2

I have some C code running on my Arduino that does a CRC calculation. I can't get it to work on Python with my RPi. I suspect it's because the Arduino is using a 16 bit unsigned integer and RPi is not. BTW - I'm brand new to Python.

Here's my Arduino code

void setup() {
  Serial.begin(9600);
  byte testData[]= {0x82, 0x00, 0x3A, 0x0A, 0x89, 0x00, 0x7D, 0xE3};
  // crc for test data is 32227
  // first 6 bytes in testData is the data, last 2 are CRC

  uint16_t crc = crc16_test(testData, 6);
  Serial.println(crc);  
}

uint16_t crc16_test(uint8_t buf[], uint8_t len )
{
  uint16_t crc = 0;
  for (int j=0; j < len; j++)
  {
    crc ^= buf[j] << 8;
    for(int i = 0; i < 8; ++i ) 
    {
      if( crc & 0x8000 )
        crc = (crc << 1) ^ 0x1021;
      else
        crc = crc << 1;
    }
  }
  return crc;
}

Here's my RPi code

rlist = [0x82, 0x00, 0x3A, 0x0A, 0x89, 0x00, 0x7D, 0xE3]
crc = crc16_ccitt(rlist, 6)
print(crc)

#----------------------
def crc16_ccitt(rawData, length):

    crc = 0
    l = 0
    for byteData in rawData:
        if l == length:
            break

        crc ^= (byteData << 8)
        l += 1

        k = 0 
        while k < 8:
            k += 1
            if(crc & 0x8000):
                crc = (crc << 1) ^ 0x1021 
            else:
                crc = crc << 1 

    return (crc)

The python code returns a big 19 digit number.

  • 1
    Why don't you simply use crcmod? http://crcmod.sourceforge.net/crcmod.predefined.html – Janka Nov 14 '18 at 20:15
  • I looked at crcmod and found it pretty confusing. I thought it would be easier to just write the function in python, but that's not so easy either I'm sure crcmod is easy if you know what you're doing. Can you show me how I would use crcmod in my example? – Scott Goldthwaite Nov 14 '18 at 22:08
  • http://crcmod.sourceforge.net/crcmod.html#examples – Janka Nov 14 '18 at 22:48
  • http://crcmod.sourceforge.net/crcmod.predefined.html#examples – Janka Nov 14 '18 at 22:49
  • I looked at those examples. I wasn't able to use those to figure out how to do the CRC for me. – Scott Goldthwaite Nov 15 '18 at 01:09
  • I tried the this example: – Scott Goldthwaite Nov 15 '18 at 01:37
  • I tried the this example but I got an error:
    hex(crc32_func(bytearray((49, 50, 51, 52, 53, 54, 55, 56, 57))))
    
    – Scott Goldthwaite Nov 15 '18 at 01:47
  • I'm trying to format my code in these comments, but I can't get it to work. Here is the error:

    File "/usr/local/lib/python2.7/dist-packages/crcmod/crcmod.py", line 450, in crcfun return xorOut ^ fun(data, xorOut ^ crc, table) File "/usr/local/lib/python2.7/dist-packages/crcmod/_crcfunpy.py", line 73, in _crc32r crc = table[ord(x) ^ int(crc & 0xFFL)] ^ (crc >> 8) TypeError: ord() expected string of length 1, but int found

    – Scott Goldthwaite Nov 15 '18 at 01:55
  • Since the C version uses uint16_t, the operations are performed modulo 2^16. You need to do the same in python. That can be done using bitwise and with 0xFFFF. – SleuthEye Nov 15 '18 at 04:02

1 Answers1

0

The following seems to satisfy your test vector in the comment

import crcmod
crcfun = crcmod.mkCrcFun(0x11021, rev=False, initCrc=0, xorOut=0)
result = crcfun(b'\x82\x00\x3a\x0a\x89\x00')

results in 32227 (ignoring the last 2 bytes as suggested by the comment). 0x11021 is the polynomial for the CCITT CRC-16 variant so I think you may have a typo in that value in your code examples. Looking at the table of predefined algorithms the xmodem one matches the above settings so we can use:

from crcmod.predefined import *
crc = crcmod.predefined.mkCrcFun('xmodem')
result crc(b'\x82\x00\x3a\x0a\x89\x00')

and get the same result of 32227 (0x7de3)

patthoyts
  • 501
  • 4
  • 10