CCITT-16 initialized to 0 any ideo how to compute that

hello everyone!

i'm pretty new on arduino things,( i can light a led ,read a little soft ,make ppm remote but not more).

i would like to understand a little bit more about serial communications , and particulary a CCITT 16 initialized to 0 CRC.

for those who would like to know , it is about controlling a photon 320 IR camera. i use to calculate some checksum online for few functions i needed, but now i would like to know how to calculate onboard a arduino...

for example, the sentence to change the camera video output from white = hot to rain colors : $6E,$00,$00,$10,$00,$02,$BC,$9A,$00,$0B,$B1,$6B

there is two CRC ccitt 16: the first one takes the first 6 bytes: $6E,$00,$00,$10,$00,$02 and the result is BC the second one is the whole sentence with the previous calculeted CRC included : $6E,$00,$00,$10,$00,$02,$BC,$9A,$00,$0B,$B1 and the result is 6B

now my question is : is there a way to calculate both crc to be able to send the good sentence to the camera knowing that i need to be able to change the byte 4,5 and 6 (ex:$10,$00,$02) ?

i did some search and i found that there is some library for avr but i have no idea on how to make that works for arduino.

can someone point me some links or tips so i can make some projects.

thanks

i did some search and i found that there is some library for avr but i have no idea on how to make that works for arduino.

Something like that is highly C - assuming you aren't using a hardware crc generator. So whatever you have will work.

not sure i get it ???

This should get you started…

#include <util/crc16.h>

static uint8_t Buffer[] = { 0x6E, 0x00, 0x00, 0x10, 0x00, 0x02 };

void setup() 
{
  uint16_t crc;
  
  Serial.begin( 115200 );
  
  crc = 0;
  
  for ( int8_t i = 0; i < sizeof(Buffer); ++i )
  {
    crc = _crc_ccitt_update( crc, Buffer[i] );
  }
  
  Serial.println( crc, HEX );
}

The data are not structured the way you described. The first block of data is the six bytes $6E,$00,$00,$10,$00,$02 and their CCITT CRC-16 is $BC,$9A The second block of data is just the two bytes $00,$0B and their CRC is $B1,$6B Which gives the whole data block, $6E,$00,$00,$10,$00,$02, $BC,$9A, $00,$0B, $B1,$6B

Pete

P.S. your problem is remarkably similar to this thread: http://arduino.cc/forum/index.php/topic,96539.0.html

Pete

thank you for the reply, i'll try to do something with the little peace of soft.

and thank's also to Pete for the structure , you are right :

The first block of data is the six bytes $6E,$00,$00,$10,$00,$02 and their CCITT CRC-16 is $BC,$9A yes.

but the second one is : The second block of data is just the two bytes $00,$0B but the CRC is calculted with the whole sentence and gives : $B1,$6B

from the datasheet:

Process Code ; Status ; Reserved; Function ; Byte Count (MSB) ; Byte Count (LSB) ; CRC1 (MSB) ; CRC1 (LSB) ; (Data) ; … (Data) ; N (Data) ; N+1 CRC2 (MSB) ; N+2 CRC2 (LSB)

• CRC1 is calculated using only the first 6 bytes of the packet. • CRC2 is calculated using all previous bytes in the packet (i.e. bytes 0 through N).

thank's for all, need to sleep now, i'll try that tomorrow, thank you again

the CRC is calculted with the whole sentence and gives : $B1,$6B

I can confirm for you that that is correct.

• CRC1 is calculated using only the first 6 bytes of the packet. • CRC2 is calculated using all previous bytes in the packet (i.e. bytes 0 through N).

The result is the same. If your data are the six bytes $6E,$00,$00,$10,$00,$02 and you tack the CRC on the end to give $6E,$00,$00,$10,$00,$02,$BC,$9A then the CRC of these eight bytes is zero - this is a property of any CRC. So, the CRC of either the ten bytes $6E,$00,$00,$10,$00,$02,$BC,$9A,$00,$0B or of the two bytes $00,$0B is the same - $B1,$6B.

Try it.

Pete

I would suggest that you write a crc generator, given the message, message length, and initial value.

Use that on the first block (6 bytes), produced a crc16 word, put it back into the message as byte 7/8. And then reapply the same crc generator on the whole thing.

The interesting thing is, given the nature of the crc, the first 8 bytes (6 bytes + its crc16) will produce a crc16 of 0x0000, :)

dhenry: And then reapply the same crc generator on the whole thing.

Wouldn't it be more efficient (and produce the same effect) to calculate the CRC for the remaining on the remainder, rather than re-processing the preceding eight too?

hi, first of thank you very much fo r pointing me this wonderfull peace of code that works very well,

i'll have to experiment everything you said for the next hours , before i can use this in my own code, so i really try to know what is going on...

You may want to consider your particular application. The bit shifting approach is the most flexible, yet the slowest. Using a table will speed up the calculation considerably, but takes up lots of space and isn't flexible.

ok so i did a bit of a progress:

/*
char CRC1 [6] = {
  0x6E,0x00,0x00,0x10,0x00,0x02  //should give crc BC9A
}; //('6E00000B0002') 
*/

char Header [3] = {
0x6E,0x00,0x00};
char Function [1] = {
0x10}; 
char ByteCount [2] = {
0x00,0x02};  
char CRC1[6] ={
Header[0],Header[1],Header[2], Function[0],ByteCount[0], ByteCount[1]};
char Data[2] ={
0x00,0x0B};
char CRC2[2] ={ 
Data[0],Data[1]};  




void setup()
{
  
  
  uint16_t crc_out1;
  uint16_t crc_out2;
  Serial.begin(57600);

  crc_out1 = calc_crc(CRC1,6); //Calculate CRC on-the-fly 
  crc_out2 = calc_crc(CRC2,2); //Calculate CRC on-the-fly 
 // Serial.println(crc_out1,HEX); //(CRC should = BC9A)
 // Serial.println(crc_out2,HEX);
 
  Serial.print(Header[0],HEX);
  Serial.print(Header[1],HEX);
  Serial.print(Header[2],HEX);
 // Serial.print(Header,HEX);
  Serial.print(Function[0],HEX);
  Serial.print(ByteCount[0],HEX);
  Serial.print(ByteCount[1],HEX);
  
  Serial.print(crc_out1,HEX);
 
  
  Serial.print(Data[0],HEX);
  Serial.print(Data[1],HEX);

 Serial.println(crc_out2,HEX);  

}

void loop()
{
  
  
  }

the serial.print command doesn’t seams to send the real HEX values , first of all some of the 0 are missing (in 0x0B 0 are not sent??)

what am i missing??

after that is there a way to write in “ByteCount” or “Function” easily in my software like so:

byte count = 0x00, 0x02

thank you in advance

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

fefenin: what am i missing??

calc_crc

the crc calculation works great!

now i just need to learn how to format the result to send it with uart.

this post ends here i guess, thanks to everyone!!