crc16 supplied code

hey guys,

i started a project a little while ago with some UHFreaders which im using to get into Arduino...
Ive run into a few problems but slowly im working my way thru them.

at the moment im having trouble grasping the crc16 check sum that i have to send and receive every time i communicate with the reader.
Here is the code from the protocol manual:

#define PRESET_VALUE 0xFFFF
#define POLYNOMIAL 0x8408
unsigned int uiCrc16Cal(unsigned char const * pucY, unsigned char ucX)
{
  unsigned char ucI,ucJ;
  unsigned short int uiCrcValue = PRESET_VALUE;
  for(ucI = 0; ucI < ucX; ucI++)
  {
    uiCrcValue = uiCrcValue ^ *(pucY + ucI);
    for(ucJ = 0; ucJ < 8; ucJ++)
    {
      if(uiCrcValue & 0x0001)
      {
        uiCrcValue = (uiCrcValue >> 1) ^ POLYNOMIAL;
      }
      else
      {
        uiCrcValue = (uiCrcValue >> 1);
      }
    }
  }
  return uiCrcValue;
}

Which i can paste into arduino and it compiles. But when i try and call the function i cant compile:

unsigned char const * cardno = 7;
   unsigned short int reply = uiCrc16Cal(cardno,6); //here im guessing its the dataarray and length that i need to send???

the card number i have is 07 00 EE 00 A2 B4 89 61
(just a breakdown 07 is the length , 00 reader address , EE is tht command , 00 is status , A2 and B4 is the data , 89 and 61 are the CRC16 check sums LSB-CRC16 and MSB-CRC16. so i can use this to double check my crc calculations...

ive read for more than a week while doing my lcd,rtc and sd card code all which ive managed :smiley: but the reader communication is killing my last braincells/...

oh on the LCD i have a tm1638 and its working great, but what would be the best way of making a menu structure? ive looked into menwiz but doesnt look like it will support the tm1638. at the moment i just have a bunch of strings in an array but that is very heavy on ram(from what ive read) any ideas?

any help is appreciated .

thanks
W

You are trying to set a variable of char * type to 7. 7 is an integer, not a pointer-to-char.

Why not something like

void whatever ()
{
  unsigned char buffer [BUFLEN] ;
  .. put stuff in buffer
  unsigned int reply = uiCrc16Cal (buffer, BUFLEN) ;
  .. use the crc...

In Arduino you don't need to say "short" as ints are already 16 bit.

Personally I'm not a fan of verbose coding style with types encoded in the variable names, and that
function is probably a lot easier to understand rewritten more concisely with better var names:

unsigned int uiCrc16Cal (byte * buf, byte len)
{
  unsigned int crc = PRESET_VALUE ;
  for (byte i = 0; i < len; i++)
  {
    crc ^= buf [i] ;
    for (byte j = 0; j < 8; j++)
    {
      unsigned int feedback = (crc & 0x0001) == 0 ? 0 : POLYNOMIAL ;
      crc = (crc >> 1) ^ feedback ;
    }
  }
  return crc ;
}

you can also consider using - avr-libc: <util/crc16.h>: CRC Computations -

Your code is correct. You just aren't passing the correct parameters to it.

unsigned char const * cardno = 7;

Do you mean:

unsigned char const * cardno = "7";

Your code had the address of a pointer to who-knows-what at address 7.

Thanks Guys for the fast responses,

im happy the code is right i actually tried sending a array must have done something stupid (as usual).....

Thanks mark i agree your code looks better and easier to read :slight_smile:

MarkT:
You are trying to set a variable of char * type to 7. 7 is an integer, not a pointer-to-char.

Why not something like

void whatever ()

{
  unsigned char buffer [BUFLEN] ;
  .. put stuff in buffer
  unsigned int reply = uiCrc16Cal (buffer, BUFLEN) ;
  .. use the crc...




In Arduino you don't need to say "short" as ints are already 16 bit.


Personally I'm not a fan of verbose coding style with types encoded in the variable names, and that
function is probably a lot easier to understand rewritten more concisely with better var names:


unsigned int uiCrc16Cal (byte * buf, byte len)
{
  unsigned int crc = PRESET_VALUE ;
  for (byte i = 0; i < len; i++)
  {
    crc ^= buf [i] ;
    for (byte j = 0; j < 8; j++)
    {
      unsigned int feedback = (crc & 0x0001) == 0 ? 0 : POLYNOMIAL ;
      crc = (crc >> 1) ^ feedback ;
    }
  }
  return crc ;
}

ok sorry i know i read in some books i must put it in "" totally slipped my mind thank you!!

[quote author=Nick Gammon link=topic=141151.msg1060824#msg1060824 date=1357545875]

unsigned char const * cardno = 7;

Do you mean:

unsigned char const * cardno = "7";

Your code had the address of a pointer to who-knows-what at address 7.

[/quote]
Thank you Rob, i have looked at that and i wasnt sure if that is the same as this(or would compute the same :fearful:

robtillaart:
you can also consider using - avr-libc: <util/crc16.h>: CRC Computations -

ok now to get working again :slight_smile:

Thanks everyone ill report back how it goes :smiley:

regards
Willie

CRC-16 == CRC-16 but implementations can have bugs ...

EDIT: Thanks Rob you posted while i was writing this :slight_smile:
EDIT2: oh just remembered i cant test if the crc works right with the reader as im still waiting for my serial -TTL converters...
oh but its fun when your a blond!!!

Hey Guys ,

Just an update.. its working!!!!!!!!

tried it with this card number : 07 00 EE 00 29 15 6E BD

used a buffer (just hard coded to see if it works):

   buffer[0]=0x07;
   buffer[1]=0x00;
   buffer[2]=0xEE;
   buffer[3]=0x00;
   buffer[4]=0x29;
   buffer[5]=0x15;
   buffer[6]=0x6E; // is this the LSB crc16 ?????

and got a crc of BD6E which is the last two bytes of the card number backwards (as i believe it should be) swaped is 6E and BD.
Which is GREAT :smiley:
..
but
..(dont you just hate buts!)

maybe im understanding the documentation incorrectly (English is not my native tongue)
the documentation says when sending ill need something like:

command:
Len , Adr ,  Cmd , Data[] , LSB-CRC16 , MSB-CRC16.

response is :
Len , Adr , reCmd , Status , Data[] , LSB-CRC16 , MSB-CRC16

so how can i calculate the LSB-CRC16 ? as i used that in to do the crc calculation?

or am i wrong and i just do the crc calc on Len, Adr , Cmd and Data[] ?
i think that should give me 2 bytes and use them as the last 2 bytes to be sent?

Im guessing im wrong so will start sending data to the reader to see if it works :cold_sweat:

Again any insight is happily received.

Thanks
Willie

(dont you just hate buts!)

depends, if the first sentence before the but is negative ....

so how can i calculate the LSB-CRC16 ?

int x = do_crc-16();
byte lsb = x & 0xFF;
byte msb = x >> 8;

or am i wrong and i just do the crc calc on Len, Adr , Cmd and Data[] ?

this one

robtillaart:

(dont you just hate buts!)

depends, if the first sentence before the but is negative ....

:stuck_out_tongue: agreed

so how can i calculate the LSB-CRC16 ?

int x = do_crc-16();
byte lsb = x & 0xFF;
byte msb = x >> 8;

or am i wrong and i just do the crc calc on Len, Adr , Cmd and Data[] ?

this one

Thank you Rob, ill be doing most of the code i can for the menus ect to try and be as finished as i can when my converters come

if anyone has i idea which menu lib works with the TM1638 module feel free to save me a lot of work trying to make my own :wink:

Thanks again for everyone's help !!!

Willie

There are plenty of tests for crc routines.

A simpler way, however, is the append the crc checksum to the end of the original message and recalculate the crc on the expand message (=original message + 2 bytes).

The checksum for the expanded message should be zero.