Whats the best way to work out this checksum?

Guys,

I am working through the control of my new inverters and batteries and have worked out the next stage of sending data to them in the correct format.

Basically it is a hex string such as

aa55c07f02390b070d04000006000005ff7f0425

The last two bytes are the checksum which are calculated by a simple addition of all the preceeding bytes.

In this instance the one value that will change is the 05 towards the end of the string and this could be any number between decimal 1 and 100

I could be calculating this every 10 seconds so should not be a big load on the PI

For this particular instance the string will remain the same length - but for some of the other functions it will vary.so i would like to write a generic checksum routine that i call at the end of each calculation

What would be the most effective way ? Read it into an array and cycle through all the elements in the array and add them from there ?

Craig

There are many ways . . . I'm far from being a Node Red or JavaScript expert but If I were doing this I'd use a function node and pass in the string as a message . . .

I presume you mean the first two bytes as you talk about the preceding bytes ?

W3 School - Javascript is your friend JavaScript Tutorial

[{"id":"fe9880b4.a24d9","type":"function","z":"b7065b03.85e128","name":"","func":"var stringarray, index, runningtotal = 0, checksum = \"\";\n\nstringarray = msg.payload.split(\"\");  // creates an array of the characters in the string\n \nfor (index = 0; index < stringarray.length; index++)\n  {\n  runningtotal += parseInt(stringarray[index], 16)\n  }\n\nchecksum = runningtotal.toString(16);\nmsg.payload = msg.payload + checksum;\n\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":470,"y":1380,"wires":[["55ed4db9.070024"]]},{"id":"dc4022bd.78d48","type":"inject","z":"b7065b03.85e128","name":"value","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"aa55c07f02390b070d04000006000005ff7f0425","payloadType":"str","x":290,"y":1380,"wires":[["fe9880b4.a24d9"]]},{"id":"55ed4db9.070024","type":"debug","z":"b7065b03.85e128","name":"inc checksum","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":654.2857055664062,"y":1381.4285888671875,"wires":[]}]

let chk = 0x0;
let buf = Buffer.from(msg.payload, "hex"); 
 
for (let index = 0; index < buf.length; index++) {
    chk += (buf[index] & 0xFFFF)
}

msg.originalPayload = msg.payload;
msg.checksum = chk;
msg.checksumHex = chk.toString(16).padStart(4, "0");
msg.payload = msg.payload + msg.checksumHex;
return msg;

This should get you close.

1 Like

Hey mate - thanks for taking the time.

Not sure it is working though

If i drop the last 4 characters (2 hec characters off the end) then the rest should add up to that - when i do this - it does not spit out the 0425 i would expect.

To work these out i have been just adding every pair into calc in hex mode and they have been working

so

aa + 55 + c0 etc etc

Craig

Yep that looks like thanks Steve - much appreciated

Craig

Didn't you start off with this as a buffer in another thread, or am I confused? If so then there is no point converting it to a string and then back to a buffer.

Colin,

You are right i did start off with this as a buffer - but i then need to manipulate it to change some values (this represents the running state of my inverter in terms of charge/discharge, percentage of battery remaining etc)

I need to change some of the value on the fly (for instance go from charge a 10% to discharge at 30%) and when i change those i need to recalculate the checksum to send back to the inverter

Craig

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.