CRC-CCITT not returning valid...

I need to get the CRC of 6 bytes in hex using CRC16-CCITT preset to 0 (xmodem).

I'v tried many options, incuding the <util/crc16.h>: CRC Computations, but I can't get the result I'm looking for. (0x0F08)

And I need the resulting CRC to be formatted into 2 bytes, like (0x0F 0x08).

Any suggestions?

byte CRC1 [6] = {0x6E, 0x00, 0x00, 0x0B, 0x00, 0x02}; //('6E00000B0002') 
  
int pkt_cnt = 0;


void setup()
{
  Serial.begin(57600);
}

void loop()
{
  
          if(pkt_cnt < 1 ) //Send the packet once
          {
            
            char crc1[1];
            snprintf(crc1, sizeof(CRC1), "%x", CRC1);// byte to char conversion
            
            calc_crc(crc1); //Calculate CRC on-the-fly
            
            Serial.write(crc1); //(CRC should = 0x0F08)
           
            pkt_cnt++;
         }
    
}// end loop


uint16_t calc_crc(char *msg)
{
  uint16_t x;
  
  for(x = 0; *msg; msg++)
  {
    x = crc_xmodem_update(x, *msg);
    snprintf(msg, 8, "%x", x);  
  }
  
  return(x);
}

 uint16_t crc_xmodem_update (uint16_t crc, uint8_t data)
    {
        int i;

        crc = crc ^ ((uint16_t)data << 8);
        for (i=0; i<8; i++)
        {
            if (crc & 0x8000)
                crc = (crc << 1) ^ 0x1021; //(polynomial = 0x1021)
            else
                crc <<= 1;
        }

        return crc;
    }

char crc1[ 1 ];

...is way too small. I suggest making it a reasonable size before concluding that your code is not working. In addition...

snprintf(crc1, sizeof(CRC1) , "%x", CRC1);// byte to char conversion

The second parameter is supposed to be the size of the destination buffer...

snprintf(crc1, sizeof(crc1) , "%x", CRC1);// byte to char conversion

The second and third characters of your message are nulls so this statement isn't going to get very far.

  for(x = 0; *msg; msg++)

Why are you looking for 0x0F08? Do you know for certain that it is the correct result?

Pete

I've rearranged the code a fair bit but it works.

char CRC1 [6] = {
  0x6E, 0x00, 0x00, 0x0B, 0x00, 0x02
}; //('6E00000B0002') 

void setup()
{
  uint16_t crc_out;
  Serial.begin(57600);

  crc_out = calc_crc(CRC1,6); //Calculate CRC on-the-fly          
  Serial.println(crc_out,HEX); //(CRC should = 0x0F08)
}

void loop()
{
}// end loop


uint16_t calc_crc(char *msg,int n)
{
  uint16_t x = 0;

  while(n--)
  {
    x = crc_xmodem_update(x, (uint16_t)*msg++);
  }

  return(x);
}

uint16_t crc_xmodem_update (uint16_t crc, uint8_t data)
{
  int i;

  crc = crc ^ ((uint16_t)data << 8);
  for (i=0; i<8; i++)
  {
    if (crc & 0x8000)
      crc = (crc << 1) ^ 0x1021; //(polynomial = 0x1021)
    else
      crc <<= 1;
  }
  return crc;
}

Pete

Very nice work guys.

Thanks to pete (el_supremo), it works like a dream.