Getting CRC Calculation straight.

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 up
void loop() {
 if (Serial.available() > 7) { 
    data = Serial.read();
      len = sizeof(data);
int ergebnis = pec15(&data, len);
Serial.println(ergebnis);
  } 
}

// Tabelle erstellen
void 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;
}
}

// Berechnung
unsigned 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
}

I messed it up... maybe some1 can give me useful hints
Mixed-signal and digital signal processing ICs | Analog Devices page 63

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.

Guess you mean something more like this:

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

}

muhkuharduino:
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?

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 ?

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

}

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.

int pec15Table[256];

is telling the compiler to reserve 256 int size memory locations (512 bytes as int is 2 bytes each).

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.

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 erstellen
void 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;
  }
}

// Berechnung
unsigned 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.

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 :wink:

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

The pec15() function calculates the PEC and will return
the correct 15 bit PEC for byte arrays of any given length.

Out of boredom I have also converted it to use PROGMEM

#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() {
}

// Berechnung
unsigned 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.

:smiley:

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^^

muhkuharduino:
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)