#include <ESP32-TWAI-CAN.hpp>
// Default for ESP32
#define CAN_TX 32
#define CAN_RX 2
CanFrame rxFrame;
void sendObdFrame(uint8_t obdId) {
CanFrame obdFrame = { 0 };
obdFrame.identifier = 0x7DF; // Default OBD2 address;
obdFrame.extd = 0;
obdFrame.data_length_code = 8;
obdFrame.data[0] = 2;
obdFrame.data[1] = 1;
obdFrame.data[2] = obdId;
obdFrame.data[3] = 0xAA; // Best to use 0xAA (0b10101010) instead of 0
obdFrame.data[4] = 0xAA; // CAN works better this way as it needs
obdFrame.data[5] = 0xAA; // to avoid bit-stuffing
obdFrame.data[6] = 0xAA;
obdFrame.data[7] = 0xAA;
// Accepts both pointers and references
ESP32Can.writeFrame(obdFrame); // timeout defaults to 1 ms
}
void setup() {
// Setup serial for debbuging.
Serial.begin(115200);
// Set pins
ESP32Can.setPins(CAN_TX, CAN_RX);
// You can set custom size for the queues - those are default
ESP32Can.setRxQueueSize(5);
ESP32Can.setTxQueueSize(5);
// .setSpeed() and .begin() functions require to use TwaiSpeed enum,
// but you can easily convert it from numerical value using .convertSpeed()
ESP32Can.setSpeed(ESP32Can.convertSpeed(500));
// You can also just use .begin()..
if(ESP32Can.begin()) {
Serial.println("CAN bus started!");
} else {
Serial.println("CAN bus failed!");
}
// or override everything in one command;
// It is also safe to use .begin() without .end() as it calls it internally
if(ESP32Can.begin(ESP32Can.convertSpeed(500), CAN_TX, CAN_RX, 10, 10)) {
Serial.println("CAN bus started!");
} else {
Serial.println("CAN bus failed!");
}
}
void loop() {
static uint32_t lastStamp = 0;
uint32_t currentStamp = millis();
if(currentStamp - lastStamp > 1000) { // sends OBD2 request every second
lastStamp = currentStamp;
sendObdFrame(5); // For coolant temperature
}
// You can set custom timeout, default is 1000
if(ESP32Can.readFrame(rxFrame, 1000)) {
// Comment out if too many requests
Serial.printf("Received frame: %03X \r\n", rxFrame.identifier);
if(rxFrame.identifier == 0x7E8) { // Standard OBD2 frame responce ID
Serial.printf("Collant temp: %3d°C \r\n", rxFrame.data[3] - 40); // Convert to °C
}
}
}