Cameron Keller
Cameron Keller

Reputation: 33

Checksum Generation from sum of bits in python

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

Answers (2)

Heiko Oberdiek
Heiko Oberdiek

Reputation: 1708

Python 2

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')

Python 3

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

Sufian Latif
Sufian Latif

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

Related Questions