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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy