Hello, I spent 2 days trying to get data from a car's CAN BUS without success. I am using an ESP32 with a CAN tranceiver. the setup is:
+-------------+
| |
| |
| |
| |
[ESP32 WROOM 32 U]
| |
CAR +-------------------------+ | |
CAN_L o--------o CAN_L 3v3 o-------o 3v3 |
CAN_H o--------o CAN_H GND o-------o GND |
| | | |
| [SN65HVD230] CAN TX o-------o 16 (RX) |
| CAN RX o-------o 17 (TX) |
+-------------------------+ +-------------+
ESP32, SN65HVD230 and the car's CANBUS share a common GND.
I tried the library in GitHub - sandeepmistry/arduino-CAN: An Arduino library for sending and receiving data using CAN bus.
The code is :
#include <CAN.h>
const int rxPin = 16;
const int txPin = 17;
// Specify the desired CAN bus speed (500 kbps)
const long canSpeed = 500E3;
unsigned long lastPacketTime = 0;
const unsigned long timeout = 20000; // 20 seconds
#define CAN_ID_ENGINE_SPEED 0x410 // CAN ID for Engine Speed (Subaru Impreza)
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("CAN Receiver");
CAN.setPins(rxPin, txPin);
if (!initializeCAN(canSpeed)) {
Serial.println("Failed to initialize CAN at 500 kbps.");
while (1);
}
}
void loop() {
int packetSize = CAN.parsePacket(); // Check for incoming CAN packets
if (packetSize) { // If a packet is received
lastPacketTime = millis();
Serial.print("Received ");
if (CAN.packetExtended()) {
Serial.print("extended ");
}
if (CAN.packetRtr()) {
Serial.print("RTR ");
}
Serial.print("packet with id 0x");
Serial.print(CAN.packetId(), HEX);
if (CAN.packetRtr()) {
Serial.print(" and requested length ");
Serial.println(CAN.packetDlc());
} else {
Serial.print(" and length ");
Serial.println(packetSize);
if (CAN.available()) {
byte buf[8];
for (int i = 0; i < packetSize; i++) {
buf[i] = CAN.read();
}
// Check if the received CAN ID is the one broadcasting Engine Speed
if (CAN.packetId() == CAN_ID_ENGINE_SPEED) {
// Process Engine Speed data based on the provided format
uint16_t engineSpeed = buf[5] | (buf[6] << 8); // Little endian
Serial.print("Engine Speed: ");
Serial.print(engineSpeed);
Serial.println(" rpm");
} else {
// Print the received data if it's not Engine Speed
for (int i = 0; i < packetSize; i++) {
Serial.print(buf[i], HEX);
Serial.print(" ");
}
Serial.println();
}
}
}
Serial.println();
} else {
if (millis() - lastPacketTime > timeout) {
Serial.println("No CAN packet received for 20 seconds, attempting to reinitialize CAN...");
if (!initializeCAN(canSpeed)) {
Serial.println("Failed to reinitialize CAN at 500 kbps.");
}
}
delay(1000);
}
}
bool initializeCAN(long speed) {
Serial.print("Initializing CAN at ");
Serial.print(speed / 1E3);
Serial.println(" kbps");
if (CAN.begin(speed)) {
Serial.print("CAN initialized successfully at ");
Serial.print(speed / 1E3);
Serial.println(" kbps");
lastPacketTime = millis();
return true;
} else {
Serial.print("Starting CAN at ");
Serial.print(speed / 1E3);
Serial.println(" kbps failed!");
return false;
}
}
in the console I can see:
08:22:40.720 -> CAN Receiver
08:22:45.409 -> Initializing CAN at 500.00 kbps
08:22:45.409 -> CAN initialized successfully at 500.00 kbps
08:23:06.357 -> No CAN packet received for 20 seconds, attempting to reinitialize CAN...
08:23:06.424 -> Initializing CAN at 500.00 kbps
08:23:06.462 -> CAN initialized successfully at 500.00 kbps
08:23:27.485 -> No CAN packet received for 20 seconds, attempting to reinitialize CAN...
....
I confirm that there is no problem with the wiring with respect to the setup shown above. I have no oscilloscope to check the signal between L and H of the CAN bus.
I checked many posts in the internet but I could not find anything that helps to solve the issue.
Any help is greatly appreciated.