Calculating checksum

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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)
{
	char buffer[13]={start,0x00,0x08,0x31,0x00,0x00,0x00,(startadd>>8),startadd,(endadd>>8),endadd,checksum,stop};
	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.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oops the format looked fine in preview :s

Moderator: try this..

===============================================================
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
void collectNsearch(uint16_t startadd,uint16_t endadd) //Collect and seach fingerprint?Sample&Search?
{
char buffer[13]={start, 0x00, 0x08, 0x32, 0x00, 0x00, 0x00, (startadd>>8), startadd ,(endadd>>8), endadd, chksum,stop}; //XOR data bytes as well

	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

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

HellsGuardian wrote:

void collectNsearch(uint16_t startadd,uint16_t endadd) //Collect and seach fingerprint?Sample&Search?
{
char buffer[13]={start, 0x00, 0x08, 0x32, 0x00, 0x00, 0x00, (startadd>>8), startadd ,(endadd>>8), endadd, chksum,stop}; //XOR data bytes as well

	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));
}

void search(uint16_t startadd,uint16_t endadd)
{
    char buffer[13]={start,0x00,0x08,0x31,0x00,0x00,0x00,
            (startadd>>8),startadd,
            (endadd>>8),endadd,0,stop};
    csum_sendcmd(buffer,sizeof(buffer));
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

blargg wrote:
HellsGuardian wrote:

void collectNsearch(uint16_t startadd,uint16_t endadd) //Collect and seach fingerprint?Sample&Search?
{
char buffer[13]={start, 0x00, 0x08, 0x32, 0x00, 0x00, 0x00, (startadd>>8), startadd ,(endadd>>8), endadd, chksum,stop}; //XOR data bytes as well

	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));
}

void search(uint16_t startadd,uint16_t endadd)
{
    char buffer[13]={start,0x00,0x08,0x31,0x00,0x00,0x00,
            (startadd>>8),startadd,
            (endadd>>8),endadd,0,stop};
    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.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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

Can you elaborate please? Kindly note the module takes only XORs as checksum so i am sort of forced to use XOR

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well it's true that a CRC8 is more likely to "spot" errors. A simple XOR can be defeated if there are a couple of bit errors in the data - one makes it wrong, the other then corrects it.

But, if the device doesn't give the choice then, as you say, you have to go with the XOR they've chosen to use - it's better than nothing.