Go Down

Topic: crc16 supplied code (Read 1 time) previous topic - next topic

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:
Code: [Select]

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

Code: [Select]

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

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
Code: [Select]

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:
Code: [Select]

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

[ I won't respond to messages, use the forum please ]

robtillaart


you can also consider using - http://www.nongnu.org/avr-libc/user-manual/group__util__crc.html -
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

dhenry

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

Nick Gammon

Code: [Select]
unsigned char const * cardno = 7;


Do you mean:

Code: [Select]
unsigned char const * cardno = "7";


Your code had the address of a pointer to who-knows-what at address 7.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

#5
Jan 07, 2013, 07:08 pm Last Edit: Jan 07, 2013, 08:11 pm by willievmobile Reason: 1
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 :)



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
Code: [Select]

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:
Code: [Select]

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


Code: [Select]
unsigned char const * cardno = 7;


Do you mean:

Code: [Select]
unsigned char const * cardno = "7";


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



Thank you Rob, i have looked at that and i wasnt sure if that is the same as this(or would compute the same  :smiley-eek-blue:
Quote



you can also consider using - http://www.nongnu.org/avr-libc/user-manual/group__util__crc.html -


ok now to get working again :)

Thanks everyone ill report back how it goes :D

regards
Willie

robtillaart

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

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

#7
Jan 07, 2013, 08:52 pm Last Edit: Jan 07, 2013, 08:55 pm by willievmobile Reason: 1
EDIT: Thanks Rob you posted while i was writing this :)
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):

Code: [Select]

   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 :D
..
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:
Code: [Select]

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 :smiley-roll-sweat:

Again any insight is happily received.

Thanks
Willie

robtillaart

Quote
(dont you just hate buts!)

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

Quote
so how can i calculate the LSB-CRC16 ?

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

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

this one
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)


Quote
(dont you just hate buts!)

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

:P agreed
Quote


Quote
so how can i calculate the LSB-CRC16 ?

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

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

Thanks again for everyone's help !!!

Willie

dhenry

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.

Go Up