CANBUS selecting specific data from CAN frame

Hi,

I am trying to get an value from a can frame, however having trouble selecting it and moving it into its own int. This is the code I have, using the AutoWP can library. However this just outputs multiple can frames, how can I get the specific one?

80000967
0
0
0
0
RPM - 0  **<--- this is the value i want!**
 
80000E67
0
0
0
0
RPM - 0
 
80001067
0
E3
FC
D2
RPM - 14941394
 
80000F67
0
0
0
0
RPM - 0

#include <SPI.h>
#include <mcp2515.h>

struct can_frame canMsg;

MCP2515 mcp2515(10);

union ArrayToInteger {
  byte array[4];
  uint32_t integer;
};

void setup() {
  Serial.begin(115200);
  
  mcp2515.reset();
  mcp2515.setBitrate(CAN_500KBPS, MCP_8MHZ);
  mcp2515.setNormalMode();
  
  Serial.println("------- CAN Read ----------");
  Serial.println("ID  DLC   DATA");
}

void loop() {
  if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {

    if(canMsg.can_id == 0x0009, HEX) // Voltage
    {
       Serial.println(canMsg.can_id, HEX); // print ID
       Serial.println(canMsg.data[0], HEX);
       Serial.println(canMsg.data[1], HEX);
       Serial.println(canMsg.data[2], HEX);
       Serial.println(canMsg.data[3], HEX);
       ArrayToInteger converter = {canMsg.data[3],canMsg.data[2],canMsg.data[1],canMsg.data[0]}; // merge 4 bits of data into a 32 bit number for RPM
       Serial.print("RPM - ");
       Serial.println(converter.integer); //Show the 32bit integer value - RPM
    
//    for (int i = 0; i<canMsg.can_dlc; i++)  {  // print the data
//      Serial.print(canMsg.data[i], HEX);
//      Serial.print(" ");
//    }
    Serial.print(" ");
    Serial.println();      
  }
}
}

See this example project for parsing CAN/OBD data

Hi,
Have you got the correct CanBus speed selected for your application?

Tom… :grinning: :+1: :coffee: :australia:

Thanks for the response, the safestrings link seams to be quite complicated, I get I need to send the data to an array, just struggling with how to achieve that and then read the data.

Tom - yes I am getting good canbus data, just extracting the right parts is what I am trying to do now.

I really dont get this - The code here with the if statement should only be true if the ID matches, however it seams to run always and keeps printing the data of all IDs.

void loop() {
  if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {

    if(canMsg.can_id == 0x0010, HEX) // Voltage
    {

      Serial.println(canMsg.can_id, HEX); // print ID

      int volt1 = canMsg.data[2];  // voltage is split over 2 bytes, read both then add together
      int volt2 = canMsg.data[3];

      int voltage = volt1 + volt2;

      Serial.print("Voltage  - "); // test
      Serial.println(voltage); // test
}
}
}

Result of code

80000967
Voltage  - 0
 
80000E67
Voltage  - 0
 
80001067
Voltage  - 461  <<- Should only show this ID and data?
 
80000F67
Voltage  - 0

Hi,
What Arduino controller are you using?
What CanBus module are you using?

Thanks… Tom… :grinning: :+1: :coffee: :australia:

Arduino nano and MCP2515 module - but as I said I am receiving the data fine, its the processing of the data to individual variables thats the problem :grinning:

Hi,
Think this is a bit of a problem;

  if(canMsg.can_id == 0x0010, HEX) // Voltage

I think it should be,

  if(canMsg.can_id == 0x0010) // Voltage

0x prefix has already declared it as Hex.

Which library are you using?

Thanks… Tom… :grinning: :+1: :coffee: :australia:

I just tried that but then I get no data out…

The library is - https://github.com/autowp/arduino-mcp2515

Thanks a lot for your help!

It looks like you’re checking for 0x0010, but the one you actually want is 0x80001067.

So, you want the value from ‘converter.integer’? You have it. Did you want to store it in a variable? Put this before, after, or in place of the two “Serial.print” lines. You will then have a variable named “RPM” that contains the value that you are printing.

uint32_t RPM = converter.integer;