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:
- an Adafruit Feather M0 Adalogger
- the Adafruit CAN Bus FeatherWing - MCP2515
- the OBD Plug (16-pin) to DE-9 (DB-9) Socket Adapter Cable
- I soldered a DB-9 connector : Ground to 3, CANL to 2 and CANH to 7
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();
}
}