Go Down

### Topic: Getting CRC Calculation straight. (Read 5091 times)previous topic - next topic

#### muhkuharduino

##### Jun 16, 2013, 11:48 amLast Edit: Jun 16, 2013, 11:51 am by muhkuharduino Reason: 1
Code: [Select]
`int pec15Table[256];int CRC15poly = 0x4599;char data;int len;void setup() {  init_PEC15_Table(); //run once  Serial.begin(9600); // }//guess this part is totally messed upvoid loop() { if (Serial.available() > 7) {     data = Serial.read();      len = sizeof(data);int ergebnis = pec15(&data, len);Serial.println(ergebnis);  } }// Tabelle erstellenvoid init_PEC15_Table(){  int remainder;for (int i = 0; i < 256; i++){remainder = i << 7;for (int bit = 8; bit > 0; --bit){if (remainder & 0x4000){remainder = ((remainder << 1));remainder = (remainder ^ CRC15poly);}else{remainder = ((remainder << 1));}}pec15Table[i] = remainder&0xFFFF;}}// Berechnungunsigned int pec15 (char *data , int len){int remainder,address;remainder = 16;//PEC seedfor (int i = 0; i < len; i++){address = ((remainder >> 7) ^ data[i]) & 0xff;//calculate PEC table addressremainder = (remainder << 8 ) ^ pec15Table[address];}return (remainder*2);//The CRC15 has a 0 in the LSB so the final value must be multiplied by 2} `

I messed it up... maybe some1 can give me useful hints
http://cds.linear.com/docs/en/datasheet/680412f.pdf page 63

#### Riva

#1
##### Jun 16, 2013, 12:30 pm
You need to create a char array to store the results of serial.read and then read all your serial data (how do you know when the data has ended) into the array before calling pec15.
Another tip would be to calculate the table, print it out so you can then include it using PROGMEM as it's eating 512 bytes of valuable RAM when it does not need to.
Don't PM me for help as I will ignore it.

#### muhkuharduino

#2
##### Jun 16, 2013, 01:16 pm
Guess you mean something more like this:

Code: [Select]
`void loop() {if(Serial.available()>=8){      for(int i=0;i<8;i++)        {              data[i] = Serial.read();         }}      len = sizeof(data);int ergebnis = pec15(data, len);Serial.println(ergebnis);delay(2000);  }`

#### Riva

#3
##### Jun 16, 2013, 01:40 pm

Guess you mean something more like this:

Obviously you will need to create the data array large enough to hold your maximum line length.
Your using sizeof() to determine the length of data but sizeof() will only tell you the size of the data array not the data length. You will need to maintain some sort of pointer to the next free array position that gets reset to zero after calling pec15 and this will tell you how long the data is not how long the array is.
Does the data come in fixed amounts or how do you know when the data sofar need CRC calculation doing. Is the data binary or ascii?
Don't PM me for help as I will ignore it.

#### muhkuharduino

#4
##### Jun 16, 2013, 01:49 pmLast Edit: Jun 16, 2013, 01:55 pm by muhkuharduino Reason: 1
Maybe I should forget the serial.read stuff.. it was only meant for checking if the CRC formula works.

Guess there are easier options to validate this.. please have a look at the mentioned page in the link in the initial post, maybe it will clear things up a little (regarding fixed amounts of data)

e.g. on page 55 it says "SendRDCOMMcommand (0x07 0x22) and its PEC
(0x32 0xD6)"

So i could just say something like data=0x07 0x22 and then serialprintin to check if it gives me 0x32 0xD6 ?

Code: [Select]
`int pec15Table[256];int CRC15poly = 0x4599;char data='0x070x22';int len=8;void setup() {  init_PEC15_Table(); //run once  Serial.begin(9600); // }void loop() {int ergebnis = pec15(&data, len);Serial.println(ergebnis, HEX);delay(2000);  }`

#### Riva

#5
##### Jun 16, 2013, 02:26 pmLast Edit: Jun 16, 2013, 02:56 pm by Riva Reason: 1
Close but your not quite there on char array. A single char can contain a value between 0 and 255. 0x07 is a way to represent the number 7 in hexadecimal and 0x22 is hexadecimal 22 (34 decimal), when the example says 0x07 0x22 that is just 2 chars not 8 as you have. Also your not letting the compiler know 'data' is an array by putting [] after the name.
Code: [Select]
`int pec15Table[256];`
is telling the compiler to reserve 256 int size memory locations (512 bytes as int is 2 bytes each).
Code: [Select]
`char data[] = {0x7,0x22};`
Does not specify the array size between [] but the data in the array is defined between the {} brackets so the compiler will still know the size the array needs to be +1

To cut a long story short here is what your looking for.
Code: [Select]
`int pec15Table[256];const int CRC15poly = 0x4599;char data[] = {0x7,0x22};int len;void setup() {  init_PEC15_Table(); //run once  Serial.begin(9600); //  len = sizeof(data);  Serial.println(len);  int ergebnis = pec15(data, len);  Serial.println(ergebnis,HEX);}void loop() {}// Tabelle erstellenvoid init_PEC15_Table() {  int remainder;  for (int i = 0; i < 256; i++)  {    remainder = i << 7;    for (int bit = 8; bit > 0; --bit)    {      if (remainder & 0x4000)      {        remainder = ((remainder << 1));        remainder = (remainder ^ CRC15poly);      }      else      {        remainder = ((remainder << 1));      }    }    pec15Table[i] = remainder&0xFFFF;  }}// Berechnungunsigned int pec15 (char *data , int len) {  int remainder,address;  remainder = 16;//PEC seed  for (int i = 0; i < len; i++)  {    address = ((remainder >> 7) ^ data[i]) & 0xff;//calculate PEC table address    remainder = (remainder << 8 ) ^ pec15Table[address];  }  return (remainder*2);//The CRC15 has a 0 in the LSB so the final value must be multiplied by 2} `

You should really put the CRC table in flash memory to save RAM.
Don't PM me for help as I will ignore it.

#### muhkuharduino

#6
##### Jun 16, 2013, 02:40 pm
Thank you for you effort !

I just took a brief look into the PROGMEM story, because there are other things which should be working before

I just started with this point (CRC) for no reason. I just saw the C Code example and wanted to make it run.

It now outputs "32D6". In the datasheet it says
Quote
The pec15() function calculates the PEC and will return
the correct 15 bit PEC for byte arrays of any given length.

#### Riva

#7
##### Jun 16, 2013, 02:55 pm
Out of boredom I have also converted it to use PROGMEM

Code: [Select]
`#include <avr/pgmspace.h>const PROGMEM prog_int16_t pec15Table[] = {    0,-14951,-12629,2866,-10033,7510,5732,-11267,    -3065,12702,15020,-203,11464,-5807,-7581,10234,    -21097,26638,25404,-22875,30040,-20287,-17421,32362,    22928,-25591,-26821,21154,-32417,17606,20468,-30099,    23342,-24905,-27259,20508,-31775,18040,19786,-30509,    -20695,27312,24962,-23525,30694,-19841,-18099,31956,    -2375,13088,14354,-629,11894,-5137,-7971,9540,    702,-14553,-13291,2444,-9615,8168,5338,-11965,    -3131,13916,15726,-1801,11018,-4461,-6751,8248,    1986,-15781,-13975,3312,-8435,6804,4518,-11201,    24146,-25653,-28423,21856,-31075,17156,18486,-29265,    -21931,28620,25854,-24217,29338,-18685,-17359,31144,    -22293,28018,26176,-23591,28708,-19011,-16753,31510,    23788,-26251,-28089,22494,-31709,16826,19080,-28911,    1404,-16155,-13353,3662,-8781,6186,4888,-10623,    -3717,13538,16336,-1463,10676,-5075,-6369,8838,    -24045,26506,27832,-22239,31452,-16571,-19337,29166,    22036,-27763,-26433,23846,-28965,19266,16496,-31255,    3972,-13795,-16081,1206,-10421,4818,6624,-9095,    -1149,15898,13608,-3919,9036,-6443,-4633,10366,    -1731,15524,14230,-3569,8690,-7061,-4263,10944,    3386,-14173,-15471,1544,-10763,4204,7006,-8505,    21674,-28365,-26111,24472,-29595,18940,17102,-30889,    -24403,25908,28166,-21601,30818,-16901,-18743,29520,    20950,-27569,-24707,23268,-30439,19584,18354,-32213,    -23087,24648,27514,-20765,32030,-18297,-19531,30252,    -959,14808,13034,-2189,9358,-7913,-5595,12220,    2118,-12833,-14611,884,-12151,5392,7714,-9285,    2808,-12447,-15277,458,-11721,6062,7324,-9979,    -257,15206,12372,-2611,9776,-7255,-5989,11522,    -22673,25334,27076,-21411,32672,-17863,-20213,29842,    21352,-26895,-25149,22618,-29785,20030,17676,-32619};char data[] = {    0x7,0x22};int len;void setup() {  //init_PEC15_Table(); //run once  Serial.begin(115200); //   len = sizeof(data);  Serial.println(len);  int ergebnis = pec15(data, len);  Serial.println(ergebnis,HEX);}void loop() {}// Berechnungunsigned int pec15 (char *data , int len) {    int remainder,address;    remainder = 16;//PEC seed    for (int i = 0; i < len; i++)    {        address = ((remainder >> 7) ^ data[i]) & 0xff;//calculate PEC table address        remainder = (remainder << 8 ) ^ pgm_read_word_near(pec15Table + address);    }    return (remainder*2);//The CRC15 has a 0 in the LSB so the final value must be multiplied by 2} `

This will increase the compiled file size as shown in the IDE but will free 512 bytes of precious RAM.
Don't PM me for help as I will ignore it.

#### muhkuharduino

#8
##### Jun 16, 2013, 03:25 pmLast Edit: Jun 16, 2013, 03:29 pm by muhkuharduino Reason: 1

Page 53: Send RDCVA command (0x00 0x04) and its PEC (0x07 0xC2).

So.. if i do as following: char data[] = {0x00,0x04}; how do i check if the formula works correct?

the codesnippet returns: 7C2

I'm really confused by this hex stuff, i can only remember calculating CRC binary^^

#### Riva

#9
##### Jun 16, 2013, 03:57 pm

Page 53: Send RDCVA command (0x00 0x04) and its PEC (0x07 0xC2).

So.. if i do as following: char data[] = {0x00,0x04}; how do i check if the formula works correct?

the codesnippet returns: 7C2

Your getting the correct result it's just the leading 0 of the 07 has been removed (7,C2)
Don't PM me for help as I will ignore it.

Go Up