I'm having a trouble with calculating checksum for a command that sends temperature to external divice. I'm using serial protocol and I have to do this for checksum:
Checksum: two ASCII hexadecimal bytes representing the least significant 8 bits of the sum of all preceding bytes of the command.
For some command I already have calculated checksums.
Example:
HEX: 2E 47 30 4135 0D
ASCII: .G0A5
But when I want to send command for setting temperature I have to calculate checksum for myself.
This command consists of (for temperature 20.5°C):
. M +205 3D (in ASCII)
In this example 3D are Ascii characters for checksum, but I do not know how to get them with Arduino code.
I do not know how to sum bytes of chars ('.', 'M', '+', '2', etc.) and take the least significant 8 bits of the sum.
Welcome to the Forum. Please read the two posts at the top of this Forum by Nick Gammon on guidelines for posting here, especially the use of code tags ("</>") when posting source code files. Also, before posting the code, use Ctrl-T in the IDE to reformat the code in a standard format, which makes it easier for us to read.
data: 0x2E + 0x47 + 0x30 = checksum: 0xA5
Then you have to convert the byte 0xA5 to the ascii charaters 'A' and '5', that is 0x41('A') and 0x35('5').
So the total result is : 0x2E, 0x47, 0x30, 0x41, 0x35.
Okay, I think I understand it.
Build your string or code in a byte buffer.
Create a checksum by adding every value to a byte, ignore overflow of the byte.
Convert the checksum into two nibbles.
byte data[20] = ".M+205".
int length = 6; // or strlen(data)
byte checksum = 0;
for ( int i=0; i<length; i++)
checksum += data[i];
byte lowNibble = checksum & 0x0F; // take the 4 lowest bits
byte highNibble = (checksum >> 4) & 0x0F; // take the 4 highest bits
// Convert the lowNibble and highNibble to a readable ascii character
if ( lowNibble >= 0x0A)
lowNibble += 'A';
else
lowNibble += '0';
if ( highNibble >= 0x0A)
highNibble += 'A';
else
highNibble += '0';
// Add them to the end of the data, high nibble first
data[length++] = highNibble;
data[length++] = lowNibble;
// transmit data with 'length' number of bytes