Calculating a Checksum

For questions and comments on programming in general. And for any items that don't fit into the forums below.

Moderators: Benj, Mods

Post Reply
Ron
Posts: 225
Joined: Wed Apr 11, 2007 6:15 pm
Has thanked: 2 times
Contact:

Calculating a Checksum

Post by Ron »

Hi,

I want to calculate a check sum and found this on the web and it sound right from how it has been described.

An example of a simple checksum:

* Given 4 bytes of data (can be done with any number of bytes): 0x25, 0x62, 0x3F, 0x52
* Step 1: Adding all bytes together gives 0x118.
* Step 2: Drop the Carry Nibble to give you 0x18.
* Step 3: Get the two's complement of the 0x18 to get 0xE8. This is the checksum byte.
* To Test the Checksum byte simply add it to the original group of bytes. This should give you 0x100.
* Drop the carry nibble again giving 0x00. Since it is 0x00 this means no error was detected (although an undetectable error could have occurred).

Can someone provide me with the code to do the above please. I am not sure if anyone has done this in flowcode.

Thanks

Ron

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: Calculating a Checksum

Post by Benj »

Hello Ron

The attached program should show you how to acheive the checksum functionality.
Attachments
Checksum.fcf
(5 KiB) Downloaded 618 times

Ron
Posts: 225
Joined: Wed Apr 11, 2007 6:15 pm
Has thanked: 2 times
Contact:

Re: Calculating a Checksum

Post by Ron »

Hi Benj,

Thank you very much.

Since I will be using this with RS232 COM macro, I will be using BYTES.

This will not be hex values so I will be using decimal, can I use decimal values where you used hex?

num_bytes = 5
temp_calc = 0
idx = 0
0 =
data[0] = 23
data[1] = 255
data[2] = 0
data[3] = 162
data[4] = 73

Thank you,

Ron

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: Calculating a Checksum

Post by Benj »

Hello Ron

My program was just an example, You can change it to suit your application.

Eg if you are expecting a string over RS232 then you can monitor the port reading bytes into a buffer until you receive say a carrage return. Once you get this you can calculate the length of the string and then perform the checksum function.

Also yes decimal / hex / binary are all interchangable - The chip cannot tell the difference they all end up as binary.

Ron
Posts: 225
Joined: Wed Apr 11, 2007 6:15 pm
Has thanked: 2 times
Contact:

Re: Calculating a Checksum

Post by Ron »

Hi,

It has been a while and I never got around to trying this.

I noticed that the VAR used to sum all the bytes was a TYPE INT.

Could this SUM VAR be a TYPE BYTE and then the carry nibble would automatically be dropped as the data bytes were added together?

Thanks,

Ron

Spanish_dude
Posts: 594
Joined: Thu Sep 17, 2009 7:52 am
Location: Belgium
Has thanked: 63 times
Been thanked: 102 times
Contact:

Re: Calculating a Checksum

Post by Spanish_dude »

An integer is basically 2 bytes together.
From what I read, you only need the first byte, so you could do something like this:

Code: Select all

VAR = VAR & 0xFF
This will clear everything except the first byte, so it will clear the "carry nibble". :wink:

Ron
Posts: 225
Joined: Wed Apr 11, 2007 6:15 pm
Has thanked: 2 times
Contact:

Re: Calculating a Checksum

Post by Ron »

Hi,

This checksum routine is going to be used to communicate between multiple PICs on an RS485 network.

I believe Ben's example used an INT and did what you describe. What I am trying to do is not use an INT variable as I believe all others VARS in Ben's example are BYTEs.

If I can use a BYTE as I originally asked then I save memory.

On the receiving end I could also use only BYTE VARs, letting the carry nibble "just disappear". Calculate the checksum of the incoming bytes and compare the

TX checksum value == RX checksum value, if they are equal then packet is good.

Back to my original question.

Instead of using an INT and doing a calculation to get rid of the carry nibble, can I just use BYTE and let the carry nibble "just disappear"?

Thanks

Ron

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: Calculating a Checksum

Post by Benj »

Hello Ron,
Instead of using an INT and doing a calculation to get rid of the carry nibble, can I just use BYTE and let the carry nibble "just disappear"?
I can't see any problems with doing this.

Ron
Posts: 225
Joined: Wed Apr 11, 2007 6:15 pm
Has thanked: 2 times
Contact:

Re: Calculating a Checksum

Post by Ron »

Hello Ben,


Thank you, I appreciate it.

Ron

Ondra
Posts: 325
Joined: Wed Aug 29, 2007 7:33 pm
Been thanked: 2 times
Contact:

Re: Calculating a Checksum

Post by Ondra »

Hi Ben.
I'm using your example code in my program. The issue I'm having is that when the number get large say above 255. It seams the result rolls over and I get the wrong value. For example here is a list of numbers: - 8, 82, 78, 73, 48, 48, 48, 48, 49, 49, 69, 56.
I'm printing the calculated result as it works through the list. When the loop reaches 73, I get value of 241 which is correct. Add 48 and I get a value of 33. It seems that the value is rolling over at 256. How do you add byte values to an int var. with out it rolling over? I'm calculating a checksum for the DIGI API packets. What you have here works fine on small numbers but on large values I have this issue. Your assistance on this would be appreciated. Thanks in advance.

Ondra

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: Calculating a Checksum

Post by Benj »

Hello Ondra,

In the example I posted the checksum variable is a byte and is intended as such, the checksum byte basically represents the culmination of bits so you can be fairly certain the data is correct rather then a running sum of the bytes. If you want to be able to add up all your bytes into an int variable then this should work as expected.

Ondra
Posts: 325
Joined: Wed Aug 29, 2007 7:33 pm
Been thanked: 2 times
Contact:

Re: Calculating a Checksum

Post by Ondra »

Thanks Ben. In the example it look to me that you are adding the values held in a byte array into an int. In theory this looks like it should work.
But on the chip it doesn't. When I sum the bytes into the int it keeps overflowing.
Simulating your example If I place larger byte values, ex.0xF2 I get unexpected results. Could you please have a closer look into this. There is
something missing here. Thanks again.

Ondra

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: Calculating a Checksum

Post by JonnyW »

Hi there. Could you post your example program please and we can have a look at the problem?

Looking at Bens example, if the value is not cropped to an integer, the 'Twos compliment' part: 256 - temp_calc will cause a problem.

Cheers,

Jonny

Ondra
Posts: 325
Joined: Wed Aug 29, 2007 7:33 pm
Been thanked: 2 times
Contact:

Re: Calculating a Checksum

Post by Ondra »

Thanks Jonny.
JonnyW wrote:if the value is not cropped to an integer, the 'Twos compliment' part: 256 - temp_calc will cause a problem.
could you explain.

Ondra

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: Calculating a Checksum

Post by JonnyW »

Hi. There is an icon in Bens example that performs twos compliment:
twos_byte.png
(3.95 KiB) Downloaded 4783 times
The 256 - temp_calc works fine because the icon above this always makes sure the value is less than 256. If this icon is removed then the value can be greater than 256 so the twos-compliment will give strange results. All a twos-compliment means is 'negate the number', so writing this as just 'temp_calc = -temp_calc' gives the twos-compliment of the number as an integer.

If you post an example of what you are trying then we can have a look and see where the issue is, because adding a number of bytes into an integer variable should work fine.

Cheers,

Jonny

Ondra
Posts: 325
Joined: Wed Aug 29, 2007 7:33 pm
Been thanked: 2 times
Contact:

Re: Calculating a Checksum

Post by Ondra »

Thanks Jonny here is the macro that I have an issue with.
Have a look at the calulate check sum loop.
Thanks
Attachments
CheckSumCal.fcf
(17.72 KiB) Downloaded 234 times

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: Calculating a Checksum

Post by JonnyW »

Hello. The only thing I can see that is a problem is you are doing '0xFF - checkSum' This is ones compliment (so 0 becomes 0xFF), not twos compliment (so 1 becomes 0xFF). Other than that the checksum loop looks fine.

In general, I would not negate from a fixed upper bound (so do -var, not 0x100 - var) as if you change the scale of your values you will get odd results.

I have modded the flowchart so this issue is removed, and the checksum stuff should work OK. I also did a search and replace on 'DigiAPIPacket.' to just '.' as you don't need the full macro name in v5 for locals - too much text hurts my eyes! I hope you don't mind. You are also using the global checkSum variable instead of the unused local one, so I removed this unused variable to avoid confusion.
CheckSumCal_b.fcf
(19.62 KiB) Downloaded 244 times
Cheers,

Jonny

Ondra
Posts: 325
Joined: Wed Aug 29, 2007 7:33 pm
Been thanked: 2 times
Contact:

Re: Calculating a Checksum

Post by Ondra »

Thanks Jonny.
although I'm a V5 user, this is done in V4. I made the change ( = -checkSum & 0xFF) over in V4 and it doesn't work. Another thing. I put an RS232 componet in the loop to print the result of the calculation through each loop.
when the the loop gets to (I)73(0x49) the sum result is 241(0xF1) the the next value(0)48(0x30) the addition sum result is 33(0x21). Can you run this (0x08,R,N,I,0,B,0,0,1,1,E,7) through and see what you get?

Ondra

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: Calculating a Checksum

Post by JonnyW »

Hello. Are you using SendRS232Char() to send the temporary check-sum? This will only send a byte, which will have the effect of making the value appear to wrap round when it hasn't. To see if this is actually the case, convert your value to a string and send that via RS232.

If this code is wrapping to a byte, then there is a serious bug in the compiler and we would have probably seen this before now. However, if you are calculating a check-sum into a byte this would not matter anyway - you only need a byte so accumulating the values into a byte like that would still work exactly as you would expect.

What do you mean that the code doesn't work? I don't have your setup here so can not test this on HW, but what I would do if you think your csum is incorrect is work out what you expect it to be and work out what the difference between that and your result is. It will not matter whether your temporary variables are integers or bytes so long as the result is a byte.

Aside from the subtraction from 0xFF (try changing it to 0x100), the code looks fine:

Code: Select all

DigiAPIPacket.Byte2 = 0xFF - DigiAPIPacket.Byte1
Should be:

Code: Select all

DigiAPIPacket.Byte2 = 0x100 - DigiAPIPacket.Byte1
Jonny

Ondra
Posts: 325
Joined: Wed Aug 29, 2007 7:33 pm
Been thanked: 2 times
Contact:

Re: Calculating a Checksum

Post by Ondra »

Thanks Jonny.
You were right about the RS232 component wrapping. I converted to string first, and yes I am getting the correct value.
The issue seems to be that from somewhere a char is been added at the end of the packet over riding the check-sum. I lengthened the
last loop that puts the data to the device and it works fine. I still don't know where this char is coming from, but the module ignores what
comes after the check sum. So it is working. Many thanks Ben and Jonny for helping to get this working.

Ondra

Post Reply