RobTillaart / CRC

CRC library for Arduino
MIT License
79 stars 17 forks source link

CRC8 SAE J1850 From CAN Data #39

Closed gsmith1979 closed 7 months ago

gsmith1979 commented 7 months ago

Hi Robert,

I realize this isn't a bug or issue, but wondered if you would be interested to charge me to help me on this project? I am using a Arduino device to talk to the dash of a motorcycle over CAN. I need to transmit 8 bytes of data on message ID 543, which i have no issue doing using Arduino now, bytes 1-6 are based on ecu parameters like gear position, engine rpm, etc., byte 7 is a counter that goes from 128-191 (also no issue here), and the last byte is a CRC8 SAE J1850 with 0x1D polynomial, initial value 0xFF, final Xor value 0xFF.

Using one of the online tools I can get the correct answer, in the screenshot that I attached I get the correct 0x1D answer, but I am not sure how to use the example sketches that you have provided. I have tested using the same string "123456789" with the online tool, and I obtain the same answer as your example sketch. Where I am lost is that I typically get all of the CAN incoming data to the Arduino from another device into a variable called buf[0], buf[1]...buf[7]. All of the example sketches that I have seen so far all have all of the data contained directly in 1 place like your example

const char str[99] = "123456789";

A small snippet of the CAN code to receive CAN information into buf variable is below.

unsigned char len = 0;
if (CAN_MSGAVAIL == CAN.checkReceive()) 
 {         // check if data coming
        CAN.readMsgBuf(&len, buf);    // read data,  len: data length, buf: data buf
        unsigned long canId = CAN.getCanId();

Thanks for your consideration, I would be interested to know if you can help and how much I can donate in paypal support. Hopefully this makes sense, I can explain further if needed.

0x543 CAN Message

(updated code snippet)

RobTillaart commented 7 months ago

Thanks for your question Will take a look into it tomorrow (getting late here)

gsmith1979 commented 7 months ago

Thanks so much, an especially late in the evening for you, on Eastern time here. Have a good night!

RobTillaart commented 7 months ago

The screenshot in code


//    FILE: CRC8_test2.ino
//  AUTHOR: Rob Tillaart
// PURPOSE: demo
//    DATE: 2021-01-20
//    (c) : MIT

#include "CRC8.h"

byte arr[7] = { 0x13, 0x54, 0x13, 0x88, 0x00, 0x0e, 0x99 };

CRC8 crc(0x1D, 0xFF, 0xFF, false, false);

void setup()
{
  Serial.begin(115200);
  Serial.println(__FILE__);

  crc.add((uint8_t*)arr, 7);
  Serial.println(crc.calc(), HEX);

  crc.restart();
  for (int i = 0; i < 7; i++)
  {
    crc.add(arr[i]);
  }
  uint8_t result = crc.calc();
  Serial.println(result, HEX);
  Serial.println(crc.count());
}

void loop()
{
}

// -- END OF FILE --
RobTillaart commented 7 months ago

Output

...\Arduino\libraries\CRC\examples\CRC8_test2\CRC8_test2.ino
1D
1D
7
RobTillaart commented 7 months ago

Hope this helps. Rob

gsmith1979 commented 7 months ago

My general confusion (sorry I'm a mechanical engineer and not a good programmer at all) is in how to get my 8 bytes that I read in from can as buf[0], buf[1] etc. Into an array that the function will read like you have shown), in the case where you have entered ox13 etc, could a delared variable like buf[0] be used?

I believe when I read it in, I interact with it in decimal form.

Again apologies for my lack of general programming and data types understanding.

gsmith1979 commented 7 months ago

Thank you very much for your help, I was able to get your code pasted into my mess and it seems to be working :) Please let me know what I owe you for your time! Greg

RobTillaart commented 7 months ago

My code shows 2 ways to calculate CRC. One with array as parameter and one with one element at a time As your data is already in an array called buf, the first one looks easiest.


crc.add((uint8_t*) buf, 7);
If (crc.calc() != buf[7])
{
  // Handle error
}
.
RobTillaart commented 7 months ago

Please let me know what I owe you for your time!

Did not spent serious time on your issue, so you owe me nothing.

Most of my time goes to developing and maintaining the libraries, so you might consider sponsoring that process (onetime / monthly) or if you prefer donate to charity (e.g doctors without borders) . Or just help a stranger with a question someday in your life.

RobTillaart commented 7 months ago

Maybe better example, a bit integrated

unsigned char len = 0;
if (CAN_MSGAVAIL == CAN.checkReceive()) 
 {         // check if data coming
        CAN.readMsgBuf(&len, buf);    // read data,  len: data length, buf: data buf

        crc.add((uint8_t*) buf, 7);  //  check the CRC of the incoming message
        If (crc.calc() != buf[7])
        {
          // Handle error
        }

        unsigned long canId = CAN.getCanId();

If you need to send a message

buf[0] = xxx;
buf[1] = yyy;
// etc
buf[6] = zzz;

crc.restart();      //  restart CRC calculation
crc.add((uint8_t*) buf, 7);
buf[7] = crc.calc();   // calculate the CRC and assign it to the CRC element of the buffer

CAN.sendMsgBuf(7, buf);   //  assume something like this exists
RobTillaart commented 7 months ago

As the library has several "standard" CRC sets defined in CrcParameters.h, This is how the code could initialize the crc object, so you would always know which standard was used. (instead of just 5 parameters with no obvious meaning)

CRC8 crc(CRC8_SAEJ1850_POLYNOME,
         CRC8_SAEJ1850_INITIAL,
         CRC8_SAEJ1850_XOR_OUT,
         CRC8_SAEJ1850_REV_IN,
         CRC8_SAEJ1850_REV_OUT,
         );

And yes, maintainability comes with more typing :)

gsmith1979 commented 7 months ago

Very nice, thanks so much! My programming I would say is very limited, but that probably overestimates my abilities haha. Thank you again for your time, I will make a contribution through paypal. Pretty amazing to have someone so responsive helping with something like this, greatly appreciated!

RobTillaart commented 7 months ago

You're welcome and thanks! If there are more question, feel free to open an issue !