/** * @file can.cpp * * Based on ESP32-TWAI-CAN example */ #include #include "can.h" #ifndef CAN_TX #error CAN Interface not declared #else 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 can_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 can_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 frames 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 } } } #endif