OBD : get car speed

Overall project: I have a differential GPS receiver including an IMU (integrated motion unit). (SparkFun Board). The IMU should allow still getting precise position while loosing sky view. Indeed, result is not very good, especially along car motion direction. One should transmit additionnel information like wheel tick, odometer or speed to the "fusion engine" of the GPS. Therefore, I want to get the speed from the OBD plug of my car (Dacia Lodgy, 6 years old, European market).

So I have:

In arduino IDE 1.8.19, I installed the following libraries: Adafruit CAN, Adafruit MCP2515 and CAN Adafruit Fork.

If I use the MCP2515_CAN_Receiver code sample provided by Adafruit, I get:

MCP2515 Receiver test!
MCP2515 chip found

This is all. As long as I don't ask for data, I will not get data. I have to send a request to the OBD through the CAN BUS.

So, I used the above mentioned code and added manually a PID request, one each 10 s. After the first request, I got plenty of sequences even if I switch off car or feather board. Most of sequences were with high PID (>0xFF). Bellow 0xFF, the most common one is 0x90 (WWH-OBD Vehicle OBD System Information ) and the second one, less often, is 0xC6 (8 bytes, unidentified). That's all. No other sequences, especially the 0x0D that I'm waiting for. Requests are well sent. If I unplug the cable on the car side, I don't have the sent confirmation. If you have any idea of what can I do to get an answer to my request, what kind of test may I do to get a clearer view of the problem or whatever.

The current code is:

/*
 * Adafruit MCP2515 FeatherWing CAN Receiver Example
 */

#include <Adafruit_MCP2515.h>

#ifdef ESP8266
   #define CS_PIN    2
#elif defined(ESP32) && !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2) && !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3)
   #define CS_PIN    14
#elif defined(TEENSYDUINO)
   #define CS_PIN    8
#elif defined(ARDUINO_STM32_FEATHER)
   #define CS_PIN    PC5
#elif defined(ARDUINO_NRF52832_FEATHER)  /* BSP 0.6.5 and higher! */
   #define CS_PIN    27
#elif defined(ARDUINO_MAX32620FTHR) || defined(ARDUINO_MAX32630FTHR)
   #define CS_PIN    P3_2
#elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040)
   #define CS_PIN    7
#elif defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W) // PiCowbell CAN Bus
   #define CS_PIN    20
#else
    // Anything else, defaults!
   #define CS_PIN    5
#endif

// Set CAN bus baud rate
#define CAN_BAUDRATE (500000)

Adafruit_MCP2515 mcp(CS_PIN);

const unsigned long speed_interval = 10000;  // interval at which speed is requested
unsigned long currentTime=0;
unsigned long previousTime=0;

void request_speed()
{
    mcp.beginPacket(0x7df, 8);
    mcp.write(0x02); // number of additional bytes
    mcp.write(0x01); // show current data
    mcp.write(0x0D);
    mcp.write(0x00);
    mcp.write(0x00);
    mcp.write(0x00);
    mcp.write(0x00);
    mcp.write(0x00); 
    if (mcp.endPacket()) {
      Serial.println("Packet sent");
    }
}

void setup() {
  Serial.begin(115200);
  while(!Serial) delay(10);

  Serial.println("MCP2515 Receiver test!");

  if (!mcp.begin(CAN_BAUDRATE)) {
    Serial.println("Error initializing MCP2515.");
    while(1) delay(10);
  }
  Serial.println("MCP2515 chip found");

//  mcp.filter(0x0D);

}

long PID;
const long max_PID = 255;

void loop() {
  // try to parse packet
  int packetSize = mcp.parsePacket();

  if (packetSize) {
    // received a packet
 //   Serial.print("Received ");

    if (mcp.packetExtended()) {
      Serial.print("extended ");
    }

    if (mcp.packetRtr()) {
      // Remote transmission request, packet contains no data
      Serial.print("RTR ");
    }

    PID = mcp.packetId();
    if (PID<=max_PID) {
      Serial.print("packet with id 0x");
      Serial.print(PID, HEX);
    }
  //  Serial.print(mcp.packetId(), HEX);

    if (mcp.packetRtr()) {
      Serial.print(" and requested length ");
      Serial.println(mcp.packetDlc());
    } else {
      if (PID<=max_PID) {
      Serial.print(" and length ");
      Serial.println(packetSize);
      }
      // only print packet data for non-RTR packets
      while (mcp.available()) {
//        Serial.print((char)mcp.read());
        if (PID<=max_PID)
        {
        Serial.print(mcp.read(), DEC);
        }
        else
        mcp.read();
      }
        if (PID<=max_PID)
      Serial.println();
    }

//    Serial.println();
  }

  currentTime=millis();
  if((currentTime-previousTime)>speed_interval){
    previousTime=currentTime;
    Serial.println("Speed requested");
    request_speed();
  }
}

your english is very difficult to understand.
if you used a translator to translate to english please copy english text and translate back to your native language.
If you can't understand the translated back text, chances are that we will not understand either!

similar to your code but hopefully you can then see what is going on with this one.
(Compiles, NOT tested)

/*
   Adafruit MCP2515 FeatherWing CAN Example
*/
#include <Adafruit_MCP2515.h>

#ifdef ESP8266
#define CS_PIN    2
#elif defined(ESP32) && !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2) && !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3)
#define CS_PIN    14
#elif defined(TEENSYDUINO)
#define CS_PIN    8
#elif defined(ARDUINO_STM32_FEATHER)
#define CS_PIN    PC5
#elif defined(ARDUINO_NRF52832_FEATHER)  /* BSP 0.6.5 and higher! */
#define CS_PIN    27
#elif defined(ARDUINO_MAX32620FTHR) || defined(ARDUINO_MAX32630FTHR)
#define CS_PIN    P3_2
#elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040)
#define CS_PIN    7
#elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_CAN)
#define CS_PIN    PIN_CAN_CS
#elif defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W) // PiCowbell CAN Bus
#define CS_PIN    20
#else
// Anything else, defaults!
#define CS_PIN    5
#endif

// Set CAN bus baud rate
#define CAN_BAUDRATE 500000UL

Adafruit_MCP2515 mcp(CS_PIN);

void setup() {
  Serial.begin(115200);
  while (!Serial) delay(10);

  Serial.println("MCP2515 Sender test!");

  if (!mcp.begin(CAN_BAUDRATE)) {
    Serial.println("Error initializing MCP2515.");
    while (1) delay(10);
  }
  Serial.println("MCP2515 chip found");
}

void loop() {
  // send packet: id is 11 bits, packet can contain up to 8 bytes of data
  Serial.print("Sending packet ... ");

  mcp.beginPacket(0x7DF);
  mcp.write(0x02);
  mcp.write(0x01);
  mcp.write(0x0D);
  mcp.write(0x00);
  mcp.write(0x00);
  mcp.write(0x00);
  mcp.write(0x00);
  mcp.write(0x00);
  mcp.endPacket();

  Serial.println("done");

  delay(1000);

  // try to parse packet
  int packetSize = mcp.parsePacket();

  if (packetSize) {
    // received a packet
    Serial.print("Receiveing: ");

    Serial.print("packet with id 0x");
    Serial.print(mcp.packetId(), HEX);
    Serial.print(" and length ");
    Serial.println(packetSize);
    while (mcp.available()) {
      Serial.print(mcp.read(), HEX);
      Serial.print(" ");
    }
    Serial.println();
  }
}

if you do get output, please share output also next time ;)

hope that helps...

I tested your code.

Output:

MCP2515 Sender test!
MCP2515 chip found
Sending packet ... done
Receiveing: packet with id 0x90 and length 5
0 0 0 0 0
Sending packet ... done
Receiveing: packet with id 0x12E and length 8
C8 7F FD 7F F0 FF FF 0
Sending packet ... done
Receiveing: packet with id 0x12E and length 8
C8 7F FE 80 0 FF FF 0
Sending packet ... done
Receiveing: packet with id 0x354 and length 8
0 0 0 0 0 0 0 0
Sending packet ... done
Receiveing: packet with id 0x354 and length 8
0 0 0 0 0 0 0 0
Sending packet ... done
Receiveing: packet with id 0x55D and length 8
0 FD 50 C0 81 0 0 0
Sending packet ... done
Receiveing: packet with id 0x55D and length 8
0 FD 50 C0 81 0 0 0
Sending packet ... done
Receiveing: packet with id 0x12E and length 8
C8 7F FD 7F F0 FF FF 0
Sending packet ... done
Receiveing: packet with id 0x12E and length 8
C8 7F FD 7F F0 FF FF 0
Sending packet ... done
Receiveing: packet with id 0x12E and length 8
C8 7F FE 7F F0 FF FF 0
Sending packet ... done
Receiveing: packet with id 0x12E and length 8
C8 7F FE 7F F0 FF FF 0
Sending packet ... done
Receiveing: packet with id 0x12E and length 8
C8 7F FD 7F F0 FF FF 0
Sending packet ... done
Receiveing: packet with id 0x29C and length 8
0 0 0 0 FF FF 0 0
Sending packet ... done
Receiveing: packet with id 0x5DE and length 8
0 8 0 80 0 0 0 41
Sending packet ... done
Receiveing: packet with id 0x5DE and length 8
0 8 0 80 0 0 0 41
Sending packet ... done
Receiveing: packet with id 0x5DE and length 8
0 8 0 80 0 0 0 41
Sending packet ... done
Receiveing: packet with id 0x5DF and length 3
0 45 0
Sending packet ... done
Receiveing: packet with id 0x673 and length 7
0 0 FF FF FF FF 0
Sending packet ... done
Receiveing: packet with id 0x673 and length 7
0 0 FF FF FF FF 0
Sending packet ... done
Receiveing: packet with id 0x673 and length 7
0 0 FF FF FF FF 0
Sending packet ... done
Receiveing: packet with id 0x4F8 and length 8
88 10 30 FF FF 3 FF 0
Sending packet ... done
Receiveing: packet with id 0x666 and length 4
30 0 0 0
Sending packet ... done
Receiveing: packet with id 0x666 and length 4
30 0 0 0
Sending packet ... done
Receiveing: packet with id 0x666 and length 4
30 0 0 0
Sending packet ... done

so the problem seem to be that you have much traffic on your OBD!

using the CAN filter feature may help with this! :wink:

something like this maybe...
(Compiles, NOT tested!)

/*
   Adafruit MCP2515 FeatherWing CAN Example
*/
#include <Adafruit_MCP2515.h>

#ifdef ESP8266
#define CS_PIN    2
#elif defined(ESP32) && !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2) && !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3)
#define CS_PIN    14
#elif defined(TEENSYDUINO)
#define CS_PIN    8
#elif defined(ARDUINO_STM32_FEATHER)
#define CS_PIN    PC5
#elif defined(ARDUINO_NRF52832_FEATHER)  /* BSP 0.6.5 and higher! */
#define CS_PIN    27
#elif defined(ARDUINO_MAX32620FTHR) || defined(ARDUINO_MAX32630FTHR)
#define CS_PIN    P3_2
#elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040)
#define CS_PIN    7
#elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_CAN)
#define CS_PIN    PIN_CAN_CS
#elif defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W) // PiCowbell CAN Bus
#define CS_PIN    20
#else
// Anything else, defaults!
#define CS_PIN    5
#endif

// Set CAN bus baud rate
#define CAN_BAUDRATE 500000UL

Adafruit_MCP2515 mcp(CS_PIN);

void setup() {
  Serial.begin(115200);
  while (!Serial) delay(10);

  Serial.println("MCP2515 Sender test!");

  if (!mcp.begin(CAN_BAUDRATE)) {
    Serial.println("Error initializing MCP2515.");
    while (1) delay(10);
  }
  Serial.println("MCP2515 chip found");

  mcp.filter(0x7E8, 0x7FF);

  Serial.println("Ox7E8 pass filter set!");
}

void loop() {
  // send packet: id is 11 bits, packet can contain up to 8 bytes of data
  Serial.print("Sending packet ... ");

  mcp.beginPacket(0x7DF);
  mcp.write(0x02);
  mcp.write(0x01);
  mcp.write(0x0D);
  mcp.write(0x00);
  mcp.write(0x00);
  mcp.write(0x00);
  mcp.write(0x00);
  mcp.write(0x00);
  mcp.endPacket();

  Serial.println("done");

  delay(1000);

  // try to parse packet
  int packetSize = mcp.parsePacket();

  if (packetSize) {
    // received a packet
    Serial.print("Receiveing: ");

    Serial.print("packet with id 0x");
    Serial.print(mcp.packetId(), HEX);
    Serial.print(" and length ");
    Serial.println(packetSize);
    while (mcp.available()) {
      Serial.print(mcp.read(), HEX);
      Serial.print(" ");
    }
    Serial.println();
  }
}

hope that helps....