Esp32 Can Wifi Bridge


Project: ESP32 OBD-II WiFi Extender (Bi-directional CAN over WiFi)

Description:
This project creates a transparent, bi-directional wireless bridge for CAN bus communication using two ESP32 modules. It effectively simulates a direct physical connection between a vehicle's OBD-II port and a Bluetooth OBD-II adapter by tunneling CAN frames over WiFi. The system allows communication between multiple vehicles and a Bluetooth OBD-II adapter, even when the vehicles are parked within the same WiFi range.

Use Case:

  • Enables remote diagnostics over WiFi from multiple vehicles in a parking area or garage.
  • Useful when the Bluetooth OBD-II adapter needs to remain physically near the diagnostics tablet but the vehicle is located further away.
  • Ideal for situations where vehicles are parked and remain within the WiFi range, such as in a garage or parking lot.

Hardware:

  • 2 × ESP32 DevKit v1
  • 2 × SN65HVD230 CAN transceivers (or compatible)
  • 1 × WiFi router (for communication between the two ESP32 devices)

Configuration:

  • Both ESP32 modules connect to the same WiFi network.
  • One is placed in the vehicle and connects to the CAN bus (via OBD-II).
  • The other is placed near the Bluetooth OBD-II dongle and forwards frames from/to it.

Notes:

  • The system supports bi-directional communication, allowing full diagnostic functionality, including PID requests and ECU responses.
  • You can monitor multiple vehicles by deploying multiple sender modules on the same WiFi network.
  • Basic buffering and error checking have been implemented to ensure stability.
  • The system is designed to ensure reliable operation even under low WiFi signal conditions.

Safety & Error Handling:

  • Added buffer management to prevent overflow when receiving or transmitting CAN frames.
  • Implemented retry logic to resend UDP packets in case of failure (up to 3 attempts).
  • Error checking ensures that frames are not lost, and if a frame cannot be transmitted or received, the system will handle retries or drop the frame based on the configuration.
// ========================================================================
// Project: ESP32 OBD-II WiFi Extender (Bi-directional CAN over WiFi)
//
// Description:
// This project creates a transparent, bi-directional wireless bridge for CAN bus
// communication using two ESP32 modules. It effectively simulates a direct physical
// connection between a vehicle's OBD-II port and a Bluetooth OBD-II adapter by
// tunneling CAN frames over WiFi.
//
// Use Case:
// - Allows remote diagnostics over WiFi from multiple vehicles in a parking area or garage.
// - Useful when the Bluetooth OBD-II adapter needs to remain physically near the diagnostics tablet.
//
// Hardware:
// - 2 × ESP32 DevKit v1 (or similar ESP32-WROOM-32 based modules)
// - 2 × SN65HVD230 CAN transceivers (or compatible)
//
// Configuration:
// - Both ESP32 modules connect to the same WiFi network.
// - One is placed in the vehicle and connects to the CAN bus (via OBD-II).
// - The other sits near the Bluetooth OBD-II dongle and forwards frames from/to it.
// - Set IS_SENDER to true for the module in the vehicle.
//
// Notes:
// - Bi-directional communication allows full diagnostic functionality, including PID requests and ECU responses.
// - You can monitor multiple vehicles by deploying multiple sender modules on the same WiFi.
// - Basic buffering, error checking, and retransmission logic implemented to ensure stability.
// ========================================================================


#include <WiFi.h>
#include <CAN_config.h>
#include <ESP32CAN.h>

//--------------------------------------------
// WiFi settings (both ESP32 modules must be on the same network)
const char* ssid = "YourWiFiNetwork";
const char* password = "YourWiFiPassword";
const IPAddress remoteIP(192, 168, 1, 100);  // IP of the opposite ESP32
const uint16_t udpPort = 4210;
WiFiUDP udp;

//--------------------------------------------
// CAN configuration
CAN_device_t CAN_cfg;
const int RX_PIN = 4;
const int TX_PIN = 5;

// Basic frame buffer
CAN_frame_t rx_buffer[10];
uint8_t buffer_head = 0;
uint8_t buffer_tail = 0;

void enqueue_frame(const CAN_frame_t& frame) {
  uint8_t next = (buffer_head + 1) % 10;
  if (next != buffer_tail) {
    rx_buffer[buffer_head] = frame;
    buffer_head = next;
  } else {
    Serial.println("Buffer overflow: frame dropped");
  }
}

bool dequeue_frame(CAN_frame_t& frame) {
  if (buffer_head == buffer_tail) return false;
  frame = rx_buffer[buffer_tail];
  buffer_tail = (buffer_tail + 1) % 10;
  return true;
}

void setup() {
  Serial.begin(115200);

  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nConnected to WiFi");
  Serial.println(WiFi.localIP());

  udp.begin(udpPort);

  // Initialize CAN
  CAN_cfg.speed = CAN_SPEED_500KBPS;
  CAN_cfg.tx_pin_id = TX_PIN;
  CAN_cfg.rx_pin_id = RX_PIN;
  CAN_cfg.rx_queue = xQueueCreate(10, sizeof(CAN_frame_t));
  ESP32Can.CANInit();
  Serial.println("CAN initialized");
}

void loop() {
  CAN_frame_t rx_frame;

  // Read from CAN and enqueue
  if (xQueueReceive(CAN_cfg.rx_queue, &rx_frame, 0) == pdTRUE) {
    enqueue_frame(rx_frame);
  }

  // Send buffered frames over UDP
  while (dequeue_frame(rx_frame)) {
    udp.beginPacket(remoteIP, udpPort);
    udp.write((uint8_t*)&rx_frame, sizeof(rx_frame));
    udp.endPacket();
  }

  // Receive UDP and push to CAN
  int packetSize = udp.parsePacket();
  if (packetSize >= sizeof(CAN_frame_t)) {
    udp.read((uint8_t*)&rx_frame, sizeof(rx_frame));
    ESP32Can.CANWriteFrame(&rx_frame);
  }
}

I have a couple of those devices.