Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CRC8 SAE J1850 From CAN Data #39

Closed
gsmith1979 opened this issue Feb 12, 2024 · 13 comments
Closed

CRC8 SAE J1850 From CAN Data #39

gsmith1979 opened this issue Feb 12, 2024 · 13 comments
Assignees
Labels
question Further information is requested

Comments

@gsmith1979
Copy link

gsmith1979 commented Feb 12, 2024

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 RobTillaart self-assigned this Feb 12, 2024
@RobTillaart RobTillaart added the question Further information is requested label Feb 12, 2024
@RobTillaart
Copy link
Owner

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

@gsmith1979
Copy link
Author

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

@RobTillaart
Copy link
Owner

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
Copy link
Owner

Output

...\Arduino\libraries\CRC\examples\CRC8_test2\CRC8_test2.ino
1D
1D
7

@RobTillaart
Copy link
Owner

Hope this helps.
Rob

@gsmith1979
Copy link
Author

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
Copy link
Author

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
Copy link
Owner

RobTillaart commented Feb 13, 2024

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
Copy link
Owner

RobTillaart commented Feb 13, 2024

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
Copy link
Owner

RobTillaart commented Feb 13, 2024

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
Copy link
Owner

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
Copy link
Author

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
Copy link
Owner

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants