checksum is used to validate data, if checksum doesn't match the data communicated has an error.
Victron Hex Protocol is an ASCII representation of Hex.
The checksum is calculated by subtraction. Define the checksum as "byte" which has the effect of discarding any overflow.
Here it is for C used by Arduino. ASCII characters are converted to byte and subtracted from checksum.
boolean victronCheckSum(char* testString, int testStringLength) {
// first character is : so start with 85 and subtract second character
byte checkSum = 85;
checkSum = checkSum - x2i(&testString[1], 1);
// subtract pairs of characters
for (int i=2; i<testStringLength; i+=2) {
checkSum = checkSum - x2i(&testString[i], 2);
}
return !checkSum; // if checksum == 0 then false else true
}
boolean victronCheckSumCalculate(char* testString, int testStringLength) {
byte checkSum = 85;
checkSum = checkSum - x2i(&testString[1], 1);
for (int i=2; i<testStringLength - 2; i+=2) {
checkSum = checkSum - x2i(&testString[i], 2);
}
testString[testStringLength-1] = hexChars[checkSum >> 4];
testString[testStringLength] = hexChars[checkSum & 15];
return true;
}
// borrowed from http://forum.arduino.cc/index.php?topic=123486.0
// converts ascii hex to integer
// use instead of strtoul so can refer to chars in a char array
// modified to limit length of "substring" of char array
byte x2i(char *s, byte numChars)
{
byte x = 0;
for(byte i=0; i<numChars; i++) {
char c = *s;
if (c >= '0' && c <= '9') {
x *= 16;
x += c - '0';
}
else if (c >= 'A' && c <= 'F') {
x *= 16;
x += (c - 'A') + 10;
}
else if (c >= 'a' && c <= 'f') {
x *= 16;
x += (c - 'a') + 10;
}
else break;
s++;
}
return x;
}