Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Расчитать контрольную сумму байтового массива запроса СПТ-941 / 14 сообщений из 14, страница 1 из 1
23.02.2014, 05:18
    #38569713
AlexDmit
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчитать контрольную сумму байтового массива запроса СПТ-941
Уважаемые специалисты! Столкнулся с проблемой расчета кс массива байт, а именно...Есть условие: "Контрольная сумма вычисляется арифметическим суммированием байтов NT, КЗ заголовка, и байтов блока данных с последующим побитовым инвертированием. В качестве значения КС используется младший байт указанной суммы" ... байтовый массив(оригинал запроса): {16,0,144,49,0,5,0,63,0,0,0,0,127,51}, где "16"-управляющий код начала кадра и "51"-фактическая контрольная сумма исключаются из расчета... в итоге к расчету {0,144,49,0,5,0,63,0,0,0,0,127} ... результат суммирования и последующего преобразования должен равняться "51" ... Поверьте дилетанту, перепробовал разные CRC и алгоритмы ... результат отрицательный. Желательно на vb.net. Заранее блдагодарен. Для проверки ... еще пара массивов: {16,0,144,126,0,5,0,69,0,0,1,0,208,167},
{16,0,144,47,0,5,0,63,0,0,0,0,95,186},
{16,0,144,47,0,4,0,63,146,41,2,58,37}.
...
Рейтинг: 0 / 0
23.02.2014, 13:04
    #38569778
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчитать контрольную сумму байтового массива запроса СПТ-941
AlexDmitЖелательно на vb.net.

Модератор: Тема перенесена из форума "Visual Basic".
...
Рейтинг: 0 / 0
23.02.2014, 13:59
    #38569794
VSVLAD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчитать контрольную сумму байтового массива запроса СПТ-941
Можно было оформить документацию соответствующе. Я не знаю почему у вас в запросе 14 байтов. В найденной документации, я вижу что всего их 9, и должен запрос заканчиваться байтом конца кадра: 16 16 или 22 10

БайтСодержание1Код начала кадра (10Н)2Групповой номер прибора (NT)3Код запроса4Поле 15Поле 26Поле 37Поле 48Контрольная сумма (КС)9Код конца кадра (16Н)
Контрольная сумма представляет собой побитно инвертированный младший байт суммы всех
предшествующих байтов за исключением кода начала кадра (байты 2...7)У вас верные исходные данные?
...
Рейтинг: 0 / 0
24.02.2014, 04:07
    #38570018
AlexDmit
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчитать контрольную сумму байтового массива запроса СПТ-941
Извиняюсь!!! Не включил конец кадра, но тем не менее, согласно сопутствующей документации, первый и конечные два байта массива из расчета кс (либо определения полинома) исключаются. В своем случае набросал промежуточную прогу-прослушку com-портов и прослушал процесс обмена между тепловычислителем СПТ-941 и программой "ПРОЛОГ". Получил образцы массивов запрос-ответ(каковы прилагаю). Чаще всего описанное в документации и фактом обмена - частичное не соответствие, поэтому следую "МЕТОДОМ ПРОБ И ОШИБОК", т.е. есть образцы ... определить способ формирования кс. С протоколом обмена для ВКТ-7 подобной проблемы не было ... все ровно, но не для "Логики". Поэтому прилагаю последовательность массивов:
Запрос
16,0,144,126,0,5,0,69,0,0,1,0,208,167,22
Ответ
16,0,144,126,0,65,0,69,123,53,47,135,123,53,47,135,22

255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,16,0,188,0,67,0,0,0,255,48,255,255,255,134,130,153,164,71,198,230,72,191,233,194,135,158,63,22


Запрос
16,0,144,47,0,5,0,63,0,0,0,0,95,186,22
Ответ
16,0,144,47,0,4,0,63,146,41,2,58,37,22

Запрос
16,0,144,48,0,5,0,63,0,0,0,0,148,16,22
Ответ
16,0,144,48,0,4,0,63,146,41,2,222,83,22


Запрос
16,0,144,49,0,5,0,63,0,0,0,0,127,51,22
16,0,144,50,0,5,0,63,0,0,0,0,82,119,22
16,0,144,51,0,5,0,63,0,0,0,0,185,84,22
16,0,144,52,0,5,0,63,0,0,0,0,8,22
16,0,63,0,0,0,0,192,22




Запрос
16,0,144,42,0,5,0,63,0,0,0,0,40,118,22
Ответ
16,0,144,42,0,4,0,63,146,41,2,114,155,22

Запрос
16,0,144,43,0,5,0,69,0,0,1,0,171,76,22
Ответ
16,0,144,43,0,65,0,69,123,53,47,135,123,53,47,135,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,188,0,67,0,0,0,255,48,255,255,255,134,130,153,164,71,198,230,72,191,233,194,135,154,76,22

Вроде как-то так....
...
Рейтинг: 0 / 0
24.02.2014, 21:14
    #38570937
VSVLAD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчитать контрольную сумму байтового массива запроса СПТ-941
AlexDmit,

Что-то описанный алгоритм вычисления до конца не могу понять. Может пригодится наработка. Вычисляет или по крайней мере похожую цифру выдает на одном запросе. Скорее всего, потому что сумма не превышает 255. Чувствую что нормальное решение где-то рядом
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
Private Const Bit1 As Long = &H1   '1       00000001
Private Const Bit2 As Long = &H2   '2       00000010
Private Const Bit3 As Long = &H4   '4       00000100
Private Const Bit4 As Long = &H8   '8       00001000
Private Const Bit5 As Long = &H10  '16      00010000
Private Const Bit6 As Long = &H20  '32      00100000
Private Const Bit7 As Long = &H40  '64      01000000
Private Const Bit8 As Long = &H80  '128     10000000

Private Sub Form_Load()
    Dim I As Long, KSum As Long
    Dim arrBytes() As Variant
    
    arrBytes = Array(16, 0, 63, 0, 0, 0, 0, 192, 22)
    
    For I = 1 To UBound(arrBytes) - 2
        KSum = KSum + arrBytes(I)
    Next
    
    KSum = KSum And &HFF

    KSum = KSum Xor Bit8
    KSum = KSum Xor Bit7
    KSum = KSum Xor Bit6
    KSum = KSum Xor Bit5
    KSum = KSum Xor Bit4
    KSum = KSum Xor Bit3
    KSum = KSum Xor Bit2
    KSum = KSum Xor Bit1

    
    MsgBox "Расчет суммы: " & KSum & vbCrLf & _
           "Контрольная сумма: " & arrBytes(UBound(arrBytes) - 1), vbInformation
End Sub
...
Рейтинг: 0 / 0
25.02.2014, 04:11
    #38571080
AlexDmit
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчитать контрольную сумму байтового массива запроса СПТ-941
Согласен, случай попадания в яблочко единичен.Вероятно присутствует какая-то фишка, либо при суммировании(тип Int, или Byte), либо полином при инвертировании, либо .... все в месте.Это пережиток 90-х ... заморочить алгоритм, мне так кажется, может быть, я, не прав. Но тем не менее ребята пишут свои проги для СПТ-941 и считывают архивы, а значит не все так сложно, как кажется. Благодарю всех за поддержку...все равно доведу до конца.
...
Рейтинг: 0 / 0
25.02.2014, 11:22
    #38571339
Где-то в степи
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчитать контрольную сумму байтового массива запроса СПТ-941
AlexDmit,
тут надо просто позвонить содателям и переспросить или уточнить алгоритм создания кс,
он настолько прост, настролько и не понятен..
вот словоа -арифметическим суммированием байтов NT, КЗ заголовка, и байтов блока данных с последующим побитовым инвертированием
что тут имелось в виду, сумма байтов потом инверсия, или сумма nt b кз + сумма инвертированная блока данных,
или общая сумма но при прибавлении инвертировать аккумулятор.
сама то процедура процедура имхо не представляет труда.
суммирование в беззнаковое, инверсия (~) , взятие младшего &0хFF
...
Рейтинг: 0 / 0
26.02.2014, 11:00
    #38572573
AlexDmit
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчитать контрольную сумму байтового массива запроса СПТ-941
Звонить родителям это трата времени, средств и т.п.
Ответ,явно, будет не однозначным ... либо приобретите сетевую версию программы ... либо гуся на рынке..., а иначе "..пилите Шура...".
Попробую подобрать полином методом "дедовского тыка" ... благо весь акцент на младшем байте, а следовательно всего 256 вариантов.Принцип довольно прост: прибор на RS232(com-port) прямое соединение, установка связи готовым шаблоном, а затем ... посылка сформированного запроса в цикле (n=0 to 255) последовательно увеличивая sum Xor (h00+n) до получения положительного, не нулевого, ответа ... запоминаем полином в массив и т.д. В результате получаем на каждый байт массива sum от 0 до 255 свой Xor. Как то так. В любом случае результат выложу.
...
Рейтинг: 0 / 0
26.02.2014, 11:25
    #38572621
Pallaris
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчитать контрольную сумму байтового массива запроса СПТ-941
Нда. Я бы позвонил
...
Рейтинг: 0 / 0
26.02.2014, 18:38
    #38573389
AlexDmit
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчитать контрольную сумму байтового массива запроса СПТ-941
Еще раз, огромная благодарность за поддержку!!! Все получилось ... без алгоритмов и полиномов ... по принципу "не усложняй" ... последовательность построения как в VB6.Подскажите как выложить листинг таким каков есть, может быть кому-то пригодится, дабы не тратить время на эксперименты и средства на приобретение не доработанного программного обеспечения для приборов энергоучета.
...
Рейтинг: 0 / 0
26.02.2014, 18:52
    #38573408
Нахлобуч
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчитать контрольную сумму байтового массива запроса СПТ-941
Сделай Gist
...
Рейтинг: 0 / 0
26.02.2014, 19:32
    #38573460
VSVLAD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчитать контрольную сумму байтового массива запроса СПТ-941
AlexDmit,

Если листинг небольшой, выложи его здесь. Обрами код тегом [SRC VB][/SRC] и тегом [ SPOILER][/SPOILER]. Интересно посмотреть алгоритм
...
Рейтинг: 0 / 0
27.02.2014, 11:27
    #38573891
AlexDmit
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчитать контрольную сумму байтового массива запроса СПТ-941
Как и обещал, прилагаю листинг таковым в черновом варианте без утряски. Как видно ... ничего сложного нет. Если у кого-либо присутствует необходимость в заготовках опроса приборов "Теплоком", то ... всегда пожалуйста.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
Private Sub Button_Click(sender As Object, e As EventArgs) Handles Button.Click
        If comport.IsOpen = True Then
            ''внешнее устройство должно передать тепловычислителю стартовую последовательность не менее чем из шестнадцати байтов 0хFF

            Dim msg1 As [Byte]() = {&HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HFF}
           ''запись массива в выходной буфер com-порта
            comport.Write(msg1, 1, msg1.Count - 1)
           ''Временные соотношения при обмене с тепловычислителем
            Sleep(4)

            ''Заголовок кадра содержит:
            ''&H10 - 0х10 – управляющий код начала кадра;
            ''&HFF - NT – сетевой номер тепловычислителя, которому адресован запрос / от которого исходит ответ, Значение 255 (0xFF)соответствует безадресному
            ''обращению к тепловычислителю
            ''&H3F - КЗ – код запроса.
            ''&H0, &H0, &H0, &H0, .... - Длина блока данных переменна и оределяется типом обрабатываемого запроса. Максимальная
            ''длина блока данных составляет 64 байта
            ''Завершающая секция кадра содержит:
            ''&H...- КС – контрольная сумма;
            ''&H16 - 0х16 – управляющий код конца кадра.

            ''Запрос сеанса обмена и модели прибора
            Dim msg_in As [Byte]() = {&HFF, &H3F, &H0, &H0, &H0, &H0}
            Dim msg_out As [Byte]()
            Sleep(1500)
            MyZapros(msg_in, msg_out)
            comport.Write(msg_out, 0, msg_out.Count - 1)
            Sleep(2200)
		Dim in_buff() As Byte
            Read_Buff(in_buff)

            'Запрос выбора скорости обмена
            msg_in = {&HFF, &H42, &H2, 0, 0, 0}
            MyZapros(msg_in, msg_out)
            Sleep(2200)
		Read_Buff(in_buff)

            ''Запрос суточного архива за 26-12-2013
            msg_in = {&HFF, &H59, 113, 12, 26, 0}
            MyZapros(msg_in, msg_out)
            comport.Write(msg_out, 0, msg_out.Count - 1)
            Sleep(2200)
		Read_Buff(in_buff)

            ''Запрос тотальные параметры Q ОЗУ (0x0538)
            msg_in = {&HFF, &H52, &H38, &H5, 4, 0}
            MyZapros(msg_in, msg_out)
            comport.Write(msg_out, 0, msg_out.Count - 1)
            Sleep(2200)
		Read_Buff(in_buff)

            ''Запрос тотальные параметры Q Flash (0x427A)
            msg_in = {&HFF, &H45, &H7A, &H42, 1, 0}
            MyZapros(msg_in, msg_out)
            comport.Write(msg_out, 0, msg_out.Count - 1)
		Sleep(2200)
		Read_Buff(in_buff)

		''........ и т.д.
        End If
    End Sub

''Процедура формирования запроса
Private Sub MyZapros(ByVal in_mass() As Byte, ByRef out_mass() As Byte)
        Dim zap() As Byte
       
        Dim pr As String = ","
        Dim ks As Integer = Nothing
        Dim m As Integer = 0

       ''арифметическое суммирование байт массива
        For Each st As Byte In in_mass
            ks += st
        Next
        '' инвертируем побитно 
        Dim dv_norma As String = Convert.ToString(ks, 2) ''   DecToBin(ks)
        Dim dv_invert As String
        For n = 1 To dv_norma.Length
            pr = Mid(dv_norma, n, 1)
            If pr = "1" Then
                pr = "0"
            ElseIf pr = "0" Then
                pr = "1"
            End If
            dv_invert += pr
        Next
        
       '' выделим младший байт 
        pr = dv_invert.Trim
        If pr.Length > 8 Then
            pr = Mid(pr, pr.Length - 7, 8)
        End If
        
        '' получаем десятичное представление контрольной суммы
        zap = Nothing
        ReDim zap(pr.Length - 1)
        For n = 0 To zap.Count - 1
            zap(n) = Int(Mid(pr, n + 1, 1)) * (2 ^ (zap.Count - (n + 1)))
            m += zap(n)
        Next
        ks = m

        '' формируем выходной массив
        ReDim out_mass(in_mass.Length + 3)
        out_mass(0) = &H10
        For n = 0 To in_mass.Count - 1
            m = n + 1
            out_mass(m) = in_mass(n)
        Next
        out_mass(m + 1) = ks
        out_mass(m + 2) = &H16
    End Sub

'' процедура чтения буфера
Dim fl_read As Boolean ''флаг остановки цикла Do...Loop

    Private Sub Read_Buff(ByRef in_buff() As Byte)
        in_buff = Nothing
        Dim ind As Integer = 0
        Do
            My.Application.DoEvents()
            If fl_read = False Then Exit Sub
            If comport.IsOpen = True Then
                If comport.BytesToRead <> 0 Then
                    buf = comport.ReadByte
                   If InStr(buf, ("+++")) Then MsgBox("Потеря несущей"):Exit Sub
                    ReDim Preserve in_buff(ind)
                    in_buff(ind) = buf
                    If comport.BytesToRead = 0 Then
                        Exit Do
                    Else
                        ind += 1
                    End If
                End If
            End If
        Loop
    End Sub

'' процедура разбора полученного массива суточного архива
Private Sub Razbor_Arch_Syt(ByVal out_mas_in() As Byte, ByRef grid_mass() As Decimal)
        Dim out_mas_byt() As Byte
        Dim m As Integer
        For n = 3 To out_mas_in.Count - 3
            m = n - 3
            ReDim Preserve out_mas_byt(m)
            out_mas_byt(m) = CByte(out_mas_in(n))
        Next
        ReDim Preserve out_mas_byt(44)
        Dim NS_f() As Byte = {out_mas_byt(0), out_mas_byt(1), out_mas_byt(2)}
        Dim SP As Byte = out_mas_byt(3)
        Dim t1_f() As Byte = {out_mas_byt(4), out_mas_byt(5), out_mas_byt(6), out_mas_byt(7)}
        Dim t2_f() As Byte = {out_mas_byt(8), out_mas_byt(9), out_mas_byt(10), out_mas_byt(11)}
        Dim V1_f() As Byte = {out_mas_byt(12), out_mas_byt(13), out_mas_byt(14), out_mas_byt(15)}
        Dim V2_f() As Byte = {out_mas_byt(16), out_mas_byt(17), out_mas_byt(18), out_mas_byt(19)}
        Dim V3_f() As Byte = {out_mas_byt(20), out_mas_byt(21), out_mas_byt(22), out_mas_byt(23)}
        Dim M1_f() As Byte = {out_mas_byt(24), out_mas_byt(25), out_mas_byt(26), out_mas_byt(27)}
        Dim M2_f() As Byte = {out_mas_byt(28), out_mas_byt(29), out_mas_byt(30), out_mas_byt(31)}
        Dim M3_f() As Byte = {out_mas_byt(32), out_mas_byt(33), out_mas_byt(34), out_mas_byt(35)}
        Dim Q_f() As Byte = {out_mas_byt(36), out_mas_byt(37), out_mas_byt(38), out_mas_byt(39)}
        Dim TN_f() As Byte = {out_mas_byt(40), out_mas_byt(41), out_mas_byt(42), out_mas_byt(43)}

        Dim t1 As Decimal
        Float(t1_f, t1)
        Dim t2 As Decimal
        Float(t2_f, t2)
        Dim V1 As Decimal
        Float(V1_f, V1)
        Dim V2 As Decimal
        Float(V2_f, V2)
        Dim V3 As Decimal
        Float(V3_f, V3)
        Dim M1 As Decimal
        Float(M1_f, M1)
        Dim M2 As Decimal
        Float(M2_f, M2)
        Dim M3 As Decimal
        Float(M3_f, M3)
        Dim Q As Decimal
        Float(Q_f, Q)
        Dim TN As Decimal
        Float(TN_f, TN)
        grid_mass = {SP, t1, t2, V1, V2, V3, M1, M2, M3, Q, TN}
    End Sub

''Процедура вычисления float
Private Sub Float(ByVal f_mass() As Byte, ByRef out_param As Decimal)

        Dim e As Integer = f_mass(3)
        Dim f0 As String = Convert.ToString(f_mass(2), 2) ''DecToBin(f_mass(2))
        Dim f1 As String = Convert.ToString(f_mass(1), 2) ''DecToBin(f_mass(1))
        Dim f2 As String = Convert.ToString(f_mass(0), 2) ''DecToBin(f_mass(0))
        Dim bit() As Integer
        Dim ii As Decimal
        Dim i As Integer
        Dim n As Integer
        For n = 1 To f0.Length
            i = n - 1
            ReDim Preserve bit(i)
            bit(i) = Int(Mid(f0, n, 1))
        Next
        ii = Nothing
        n = 0
        For Each b As Integer In bit
            If b <> 0 Then ii += 2 ^ (-n)
            n += 1
        Next
        out_param = ((-1) ^ 0) * (2 ^ 0 + ii) * 2 ^ (e - 127)
    End Sub

''Функция преобразования... аналог Convert.ToString(mass(n), 2) 
Public Function DecToBin(ByVal DeciValue As Long, Optional ByVal NoOfBits As Integer = 8) As String
        Dim i As Integer
        Do While DeciValue > (2 ^ NoOfBits) - 1
            NoOfBits = NoOfBits + 8
        Loop
        DecToBin = vbNullString
        For i = 0 To (NoOfBits - 1)
            DecToBin = CStr((DeciValue And 2 ^ i) / 2 ^ i) & DecToBin
        Next i
    End Function


...
Рейтинг: 0 / 0
27.02.2014, 11:38
    #38573910
Pallaris
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчитать контрольную сумму байтового массива запроса СПТ-941
Мне вот это понравилось
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
'' инвертируем побитно 
        Dim dv_norma As String = Convert.ToString(ks, 2) ''   DecToBin(ks)
        Dim dv_invert As String
        For n = 1 To dv_norma.Length
            pr = Mid(dv_norma, n, 1)
            If pr = "1" Then
                pr = "0"
            ElseIf pr = "0" Then
                pr = "1"
            End If
            dv_invert += pr
        Next
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Расчитать контрольную сумму байтового массива запроса СПТ-941 / 14 сообщений из 14, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]