Reputation: 33
I am trying to control a chiller through RS232 with python. I am stuck at generating a checksum as required by the following method.
"The checksum is two ASCII hexadecimal bytes representing the least significant 8 bits of the sum of all preceding bytes of the command starting with the sor."
The "sor" in this case in bytes is "2E".
-Example
For example, the PC requires the chiller mode be set to Stand By. It will transmit the following sequence of bytes.
2E 47 30 4135 0D
Note that 2Eh is the start of header (“.”), 47h is the command (“G”), 30h is the qualifier to set the mode to Stand by. 41h and 35h are checksum bytes representing the ASCII hex for “A5” which is the least significant byte of the sum of 2Eh + 47h + 30h and 0Dh is carriage return.
Does anyone know how to generate the checksum bytes 4135?
Thankyou!!
Upvotes: 3
Views: 12230
Reputation: 1708
The function rs232_checksum
calculates the sum of the bytes.
Then it converts the sum to an uppercase hexadecimal string and returns is as bytes.
def rs232_checksum(the_bytes):
return bytes('%02X' % (sum(map(ord, the_bytes)) % 256))
checksum_bytes = rs232_checksum(b'\x2e\x47\x30')
The function definition simplifies to (with binary "and" to get the least significant eight bits):
def rs232_checksum(the_bytes):
return b'%02X' % (sum(the_bytes) & 0xFF)
Upvotes: 3
Reputation: 13356
You can find the sum in hexadecimal as
>>> hexsum = hex(0x2e + 0x47 + 0x30)[2:].upper()
>>> hexsum
'A5'
(the 0x
at the front is sliced off by [2:]
)
Then you can get the ASCII values of the characters in hexadecimal as
>>> bytes = [hex(ord(c))[2:] for c in hexsum]
>>> bytes
['41', '35']
(again, the frontal 0x
is removed from each element)
Then you can join them together:
>>> checksum = ''.join(bytes)
>>> checksum
'4135'
Or everything can be done with this one-liner:
>>> ''.join(hex(ord(c))[2:] for c in hex(0x2e + 0x47 + 0x30)[2:].upper())
'4135'
Upvotes: 3