question

akgentile1963 avatar image
akgentile1963 asked

Calculating checksum for Set and Get commands

Hello,

I'm trying to write and read from an MPPT 100. I believe I understand the code for writing commands, but I keep getting framing errors, and I think it's my checksum.


Example. I am trying to get the battery maximum current. The command should be:

3A 37 46 30 45 44 30 26 0A

3A = start

37 = Get command

46 30 45 44 (reg ID from EDF0, converted to little endian hex)

30 = flags, set to zero

26 = checksum

0A = end

I can't find anything wrong with this, but when I sent it I get a framing error of 4AAAA. Can someone please explain what I'm missing?


Thanks

AKG

MPPT Controllers
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

1 Answer
Thiemo van Engelen (Victron Energy staff) avatar image
Thiemo van Engelen (Victron Energy staff) answered ·

Hi,

The flags and checksum are also hex strings of 2 bytes long each, so 0x30 0x30 for a flag value of 0 or 0x31 0x32 for a checksum of 0x12.

So for a get command for vreg EDF0, the full line is:

3A = ':' start
37 = '7' get command
46 30 45 44 = 'F0ED' regid 0xEDF0) converted to little endian hex
30 30 = '00' flags set to zero
37 31 = '71' checksum 0x55 - 0x07 - 0xF0 - 0xED - 0x00 = 0x71
0A = end of line

Kind regards,

Thiemo van Engelen

7 comments
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

akgentile1963 avatar image akgentile1963 commented ·

Thank you for your reply. This code works, but I'd like to understand better how you got to this answer, because it is still vague to me.

All flags on all commands are going to be represented as 30 30, which correspond to ascii 0 0. That's easy enough to remember. I can't find this in the protocol manual, but I will just remember to use it.

The calculation of the checksum is repeatable, but still not clear to me. The calculation is 0x55 minus the command and the data bytes. That part is clear.

It seems you are doing the calculation using the ascii character representations of the hex numbers. I would have done the following calculation:

0x55-0x37-0x46-0x30-0x44-0x45 = checksum, and I get an answer of 0xFF1F. Why am I converting the hex numbers into ascii representations of those numbers?

Second question. When I do your calculation, I get a negative number of -399 decimal, and then I convert it to signed hex and I get 0xFE71. I understand why I have to convert, but why don't I use both nibbles?


Thank you in advance.







0 Likes 0 ·
Thiemo van Engelen (Victron Energy staff) avatar image Thiemo van Engelen (Victron Energy staff) ♦ akgentile1963 commented ·

Hi,

When sending things to a product, the flags should be 0. When you receive an answer, the flags can have a different value.

It seems you are doing the calculation using the ascii character representations of the hex numbers:
When I understand you correctly... yes.
The data that is transmitted are byte values printed as a hexadecimal number (printf("%02X", byte_value) in C).

The vreg id is 0xEDF0, which is 2 bytes with the values 0xF0 and 0xED in little endian format and thus is transmitted as "F0ED".

The flags are a byte, and when they have the value 0x00, they are transmitted as "00".

The command is a an exception in the sense that it is treated as a regular byte for the checksum calculation, but only the lowest nibble (which is 4 bits) is sent, so this means only 1 character of the hexadecimal string. So a command value of 0x7 is transmitted as the "7".

The checksum is always 1 byte that is calculated using the other byte values. The calculation is 0x55 - command byte - vreg byte 1 - vreg byte 2 - flags byte (- data byte 1 - data byte 2 .... when applicable), truncated to the least significant byte. Then that byte value is sent as a hexadecimal string of 2 characters.

I hope this clears things up a bit.

Kind regards,

Thiemo van Engelen

0 Likes 0 ·
akgentile1963 avatar image akgentile1963 Thiemo van Engelen (Victron Energy staff) ♦ commented ·

Thank you very much. I do have one more question, please. When using a Set command, how is the data sent?


Example. I am setting the Tx port to Pulse for every 0.01 kWh. I have the following command to reg ID 0xED9E

3A = ":"

38 = "8" = set

39 = "9"

45 = "E"

45 = "E"

44 = "D"

31 = "1" this is the data

30 ="0" flag

30 ="0" flag

39 = checksum "9"

31 = checksum "1"

0A = "." end of command

I get a framing error on this. But it appears to be correct. Can you tell me how I should be including a data value of 1?

0 Likes 0 ·
akgentile1963 avatar image akgentile1963 akgentile1963 commented ·

Maybe I should clarify what I'm trying to do. I have a stand alone LCD display that I would like to use to read from and write to the controller. I believe I have the commands under control, but the controller sends out a broadcast every second. I am trying to set the controller to be used as a slave, where the LCD controls the communications.

0 Likes 0 ·
akgentile1963 avatar image akgentile1963 Thiemo van Engelen (Victron Energy staff) ♦ commented ·

Let me try this again. The command for setting the transmit port to 1 (reg 0xED9E) is

3A 38 39 45 45 44 30 30 30 31 30 31 0A

3A = Start

38 = Set

39 = 9

45 = E

45 = E

30 = flag 1

30 = flag 2

30 = data 1

31 = data 2

30 = checksum 1

31 = checksum 2 (0x55-0x8-0x9E-0xED-0x00-0x00-0x00-0x01)=01

0A = end of command


Just an idea, for the next time you guys revise your manual, a few examples in your protocol guide would be worth a lot of money,

0 Likes 0 ·
akgentile1963 avatar image akgentile1963 akgentile1963 commented ·

I skipped the D in that last command, but I did use it in the application. Please excuse me. I've been working on the same command for 7 hours and I'm starting to become less perceptive.

0 Likes 0 ·
Thiemo van Engelen (Victron Energy staff) avatar image Thiemo van Engelen (Victron Energy staff) ♦ akgentile1963 commented ·

Hi,

The result of the checksum calculation is wrong. The result I get from 0x55-0x08-0x9E-0xED-0x00-0x00-0x00-0x01 = 0xC1.

The order of the bytes and so on is now correct.

Kind regards,

Thiemo van Engelen


0 Likes 0 ·