Need help understanding code to receive OBDII messages

Hello,

I am using CANBed M4 board to read OBDII messages from a car. I am using following library with this board and I am able to read messages on the CAN bus.

Unfortunately the messages seems to not follow OBDII format as I can not seem to decode any of them in accordance with OBDII message structure.

Here is what I am seeing in CSV format:

ID,LENGTH,DATA
368,3,C0A1B
372,8,654499BB08000
644,8,3EC13E721E4AF6
374,8,A1D6103ADE600
451,8,000000FFC3
375,8,FE00011000
645,8,3E7D3E454D0AFC1
646,5,EEE554A4
682,8,008088000B4
683,8,0008A007C1F
688,8,0FFF8C1B0CE0
2,5,B3FF0787
734,8,0009400E93
768,1,0
352,7,3983B5110EEE0
384,8,30573B539812300
386,8,FF0001400EF
505,8,6820305700560
368,3,C4A25
372,8,654499BB18000
581,8,FFE0018010FFE0
374,8,A236B3AB0610
658,8,7F186281800140
1004,2,2FA0
689,6,0040000
734,8,0009400E93
1477,8,400B0D10C00
533,7,FFF4FF30FFFF0
534,2,400
352,7,3963B41080EF60
384,8,30703B439612310
386,8,FF0001310EF
505,8,6820307000560
368,3,C8A22
372,8,654498BB28000
645,8,3E833E2E4D0B0B1
374,8,A1B6123A7A620
451,8,000002FFC5
644,8,3EC63E7D1E9B01C
683,8,0008A007B63
734,8,0009400E93
768,1,0
352,7,3963B5100EFE0
384,8,30573B539611F20
386,8,FF0001320EE
505,8,6820305700560
569,8,1EE0A0204111FB80
853,8,1E501EF93044600
368,3,CCA28

For example, if I should see some basic PID's for Engine RPM (0C) and Vehicle Speed (0D).

Any input is appreciated as I am pretty new to this.

Following is the sample code I am using to generate this CSV file:

/*
  CAN 2.0 send example for CANbed M4
  
  begin(uint8_t idmodeset, uint32_t speedset, enum mcan_can_mode canmode)
  
  @idmodeset:
  
  #define MCP_STDEXT   0        // Standard and Extended    
  #define MCP_STD      1        // Standard IDs ONLY       
  #define MCP_EXT      2        // Extended IDs ONLY        
  #define MCP_ANY      3        // Disables Masks and Filters 
  @speedset:
  
  #define CAN_4K096BPS 4096
  #define CAN_5KBPS    5000
  #define CAN_10KBPS   10000
  #define CAN_20KBPS   20000
  #define CAN_31K25BPS 31250
  #define CAN_33K3BPS  33300
  #define CAN_40KBPS   40000
  #define CAN_50KBPS   50000
  #define CAN_80KBPS   80000
  #define CAN_100KBPS  100000
  #define CAN_125KBPS  125000
  #define CAN_200KBPS  200000
  #define CAN_250KBPS  250000
  #define CAN_500KBPS  500000
  #define CAN_1000KBPS 1000000
  
  @canmode:
  
  MCAN_MODE_CAN                             ISO 11898-1 CAN 2.0 mode 
  MCAN_MODE_EXT_LEN_CONST_RATE              Long CAN FD frame.
                                            * - TX and RX payloads up to 64 bytes.
                                            * - Slow transmitter: TX frames are sent at constant bit rate.
                                            * - Fast receiver: both constant-rate (slow) and dual-rate (fast)
                                            *   RX frames are supported and received. 
  MCAN_MODE_EXT_LEN_DUAL_RATE               Long and fast CAN FD frame.
                                            * - TX and RX payloads up to 64 bytes.
                                            * - Fast transmitter: control, data and CRC fields are transmitted at a
                                            *   higher bit rate.
                                            * - Fast receiver. 
*/

#include <same51_can.h>

SAME51_CAN can;

void setup()
{
    Serial.begin(115200);
    while(!Serial);
    
    uint8_t ret;
    ret = can.begin(MCP_ANY, CAN_1000KBPS, MCAN_MODE_EXT_LEN_DUAL_RATE);
    if (ret == CAN_OK) 
    {
      // Print header
      Serial.print("ID,");
      Serial.print("LENGTH,");
      Serial.print("DATA");
      Serial.print("\n");
    } else 
    {
      Serial.println("Error Initializing CAN...");
      while(1);
    }

    // initialize digital pin LED_BUILTIN as an output.
    pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
    uint8_t ret;
    uint32_t id;
    uint8_t len;
    uint8_t buf[8];
    uint8_t i;
    
    ret = can.readMsgBuf(&id, &len, buf);
    
    if (ret == CAN_OK) {
      digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on

      // check msg for RPM
      Serial.print(id, HEX);
      Serial.print(",");
      Serial.print(len, HEX);
      Serial.print(",");
      for (i = 0; i < len; i++) {
        Serial.print(buf[i], HEX);
      }
      Serial.print("\n");
    }
    else {
      digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on
      digitalWrite(LED_BUILTIN, LOW);    // turn the LED off
      //Serial.print("No message");
    }
}

// END FILE

Thank you.

Does your car match one of these lists of message identifiers?

If the ID list for your manufacturer shows the IDs in hex, you may want to display your messages IDs in hex instead of decimal.

1 Like

It's odd that you're not seeing any of the lower IDs. Can you get at the raw data from the can bus without using the library perhaps?

You might want to change this to

for (i = 0; i < len; i++) {
  if ( buf[i] < 0x10 ) Serial.print('0');
  Serial.print(buf[i], HEX);
}

so all of your data comes out as 2 byte HEX

You are seeing the latent data communication on the network, which is not OBD protocol. OBD requires a request to be sent to receive OBD style communication.

1 Like

Thank you everyone for your help. I've figured it out. The solution had to do with a combination of replies above.

@johnwasser My car did not match that list, but I've tried another car which did not have a bunch of junk on the CAN bus and I was able to get clear OBDII messages. Additionally, formatting my messages in 2 byte HEX was also helpful. Thank you for that tip @blh64 and @johnwasser. Lastly, as @hoys have mentioned, I did have to send out request messages in order to receive expected responses.