У меня есть контроллер Athena 16C, который я контролирую через RS232. Для протокола обмена сообщениями требуется контрольная сумма:Как я могу кодировать/декодировать эту проприетарную контрольную сумму (PID-контроллер Athena 16C)?
CHKSUM: это двухзначная система нумерации кода сообщения, представляющая сумму всех значений ASCII всех символов (исключая START, CHAR, END CHAR и CHKSM). Сумма вычисляется по следующей формуле: CHKSM = SUM (все символы сообщений)% 256, где% представляет собой оператор модуля. "
Пример сообщения (от их документации) заключается в следующем:
$Ø1Ø1RØ5C1<CR>
и может быть разбита как:
$ [START CHAR] 01 [ID] 01 [ZONE] R [TYPE] 05 [PARAM] C1 [CHKSM] <CR> [END CHAR]
Я послал это сообщение к контроллеру, и он работает, как ожидалось.
Я пишу свой код в JS и иметь следующий, который, как предполагается рассчитать CHKSM поставить в конце сообщения:
var sum = 'Ø1Ø1RØ5'
.split('')
.map(function(char) {
return char.charCodeAt(0);
})
.reduce(function(current, previous) {
return previous + current;
});
var chksm = (sum % 256);
console.log(chksm.toString(16));
Контрольная сумма должна быть «C1» в соответствии с форматом сообщения , Но рассчитанная сумма равна 377, что приводит к контрольной сумме 121, которая равна 79 в гексагоне.
// 0 = 48, 1 = 49, R = 82, 5 = 53 (ASCII values)
// 48 + 49 + 48 + 49 + 82 + 48 + 53 = 377
// 377 % 256 = 121 (decimal) = 79 (hex)
Инженер из Athena прислал мне следующий код VB, но я не могу понять логику, ни синтаксис в частности. Есть ли что-то основное, что мне не хватает в этой проблеме в целом?
' Covert the mod % 256 checksum to the 2 chars:
' Will set First and Second chars for encoded value. Pass in the value (Checksum mod 256)
' and where to return the 1st and 2nd chars to.
Public Sub EncodeIt(ByVal Value As Integer, ByRef FirstChar As Integer, ByRef SecondChar As Integer)
If Value > 359 Then 'Z9 = 359, absolute max possible
Value = 359
End If
'Note: backslash '\' means integer divide, not floating point!!
If Value > 99 Then
FirstChar = (Value \ 10) + 65 - 10 '65 = ascii "A"
Else
FirstChar = (Value \ 10) + 48 '48 = ascii "0"
End If
SecondChar = (Value Mod 10) + 48
End Sub
' Convert the two chars received in a message back to normal integer.
' Take the 2 chars and return a decoded integer value
Public Function DecodeIt(ByVal FirstChar As Integer, ByVal SecondChar As Integer) As Integer
'65 = ascii "A", 48 = ascii "0"
If FirstChar > 57 Then '57 = ascii "9"
Return ((FirstChar - 65 + 10) * 10) + (SecondChar - 48)
Else
Return ((FirstChar - 48) * 10) + (SecondChar - 48)
End If
End Function