## Calculating checksum

9 posts / 0 new
Author
Message

hello, i have a fingerprint module and i am interfacing it with ATmega32 and i use Atmel studio 6.1.

The module requires certain hexa values to be sent in sequence and these sequence correspond to certain actions. The sequence format is this:

```  1    2     3         4        5  6  7     8      9  	   10
02 	00 length  command byte  00 00 00  data  checksum    03	```

Now apart from the constant bytes, the 8th byte which is data byte does not have a fixed length. Depending upon the operation, its length can vary from 0 to 256 bytes.
The 9th byte is the checksum byte which is equals to:

XOR of all bytes between byte2 and byte9. So in this case the checksum would be:

length ^ command ^ data

My question is that for simpler commands i can code it to take XOR or even calculate it myself and hardcode it but what if the data is of multiple bytes?

What i am currently doing is that i store the sequence in an array:

```void getinfo(void)
{
char buffer[9]={start,0x00,0x04,0x01,0x00,0x00,0x00,0x05,stop}; // start = 0x02, stop=0x03
sendcmd(buffer,sizeof(buffer));
}```

and the function sendcmd(); sends the array over UART. In the code above i have calculated checksum myself because databyte was = zero. But there are some commands that have varying length of data.

For example in a command Search

``` void search(uint16_t startadd,uint16_t endadd)
{
sendcmd(buffer,sizeof(buffer));
}```

i have to send the search range in which the module will search for fingerprints. Now this range is max of 0-1023 but as far as input is concerned it can be any number say: 10-17, 375-932, 585-741... pretty much anything.
So i need to make a generalized function for calculating XOR and then place that XOR value on (N-1)th byte of my array.

My idea is:
when the function is called,
-store the range in its array
-XOR values from buffer[2] to buffer[(Sizeof(buffer)-2)]
-store the value in buffer[(Sizeof(buffer)-1)]
-Sendcmd(buffer....)

I am sort of stuck at step 2 and i also doubt if this is the best way to do it.

Oops the format looked fine in preview :s

Moderator: try this..

`===============================================================`
```void collectNsearch(uint16_t startadd,uint16_t endadd) //Collect and seach fingerprint?Sample&Search?
{

for (int x=2;x<(sizeof(buffer)-2);x++)
{
chksum ^= buffer[x];
}

sendcmd(buffer,sizeof(buffer));

}```

Seems to be working, sorry for bothering you guys. Still if anybody wants to suggest improvements plz do

Looks fine to me. You might want to use a parameter for length so you could put messages shorter than the buffer. Does the other device accept the checksum as valid? Actually, you have a parity there, a checksum would be adding the bytes.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut.

HellsGuardian wrote:

```void collectNsearch(uint16_t startadd,uint16_t endadd) //Collect and seach fingerprint?Sample&Search?
{

for (int x=2;x<(sizeof(buffer)-2);x++)
{
chksum ^= buffer[x];
}

sendcmd(buffer,sizeof(buffer));

}```

Seems to be working, sorry for bothering you guys. Still if anybody wants to suggest improvements plz do

That's a curious routine. It puts chksum (a global?) into buffer, *then* modifies it but leaves the old value in the buffer.

It sounds like you'd use a helper like this that your command functions call through to:

```void csum_sendcmd( char buf [], int sizeof_buf )
{
char checksum = buf [2];
for ( int i = 3; i < sizeof_buf - 2; ++i )
checksum ^= buf [i];

buf [sizeof_buf - 2] = checksum;

sendcmd( buf, sizeof_buf );
}

void getinfo(void)
{
char buffer[9]={start,0x00,0x04,0x01,0x00,0x00,0x00,0,stop};
csum_sendcmd(buffer,sizeof(buffer));
}

{
char buffer[13]={start,0x00,0x08,0x31,0x00,0x00,0x00,
csum_sendcmd(buffer,sizeof(buffer));
}```

blargg wrote:
HellsGuardian wrote:

```void collectNsearch(uint16_t startadd,uint16_t endadd) //Collect and seach fingerprint?Sample&Search?
{

for (int x=2;x<(sizeof(buffer)-2);x++)
{
chksum ^= buffer[x];
}

sendcmd(buffer,sizeof(buffer));

}```

Seems to be working, sorry for bothering you guys. Still if anybody wants to suggest improvements plz do

That's a curious routine. It puts chksum (a global?) into buffer, *then* modifies it but leaves the old value in the buffer.

It sounds like you'd use a helper like this that your command functions call through to:

```void csum_sendcmd( char buf [], int sizeof_buf )
{
char checksum = buf [2];
for ( int i = 3; i < sizeof_buf - 2; ++i )
checksum ^= buf [i];

buf [sizeof_buf - 2] = checksum;

sendcmd( buf, sizeof_buf );
}

void getinfo(void)
{
char buffer[9]={start,0x00,0x04,0x01,0x00,0x00,0x00,0,stop};
csum_sendcmd(buffer,sizeof(buffer));
}

{
char buffer[13]={start,0x00,0x08,0x31,0x00,0x00,0x00,
csum_sendcmd(buffer,sizeof(buffer));
}```

Yes i had some issues so i sort of forced it to refresh the value every time. But this seems to be a better idea, thanks.

best to use CRC8 and a lookup table. halfsum and XOR can leave many errors undetected, especially a dropped byte of all 0s.