ESP32 CAN bus client firmware that receives sensor data from a CAN network and displays it on a 128x64 SSD1306 OLED display.
- Multi-sensor CAN data reception: Receives and parses data from VEML7700 (light), BME680 (temp/humidity/pressure/IAQ), MQ-3 (alcohol), and LD2410 (presence) sensors
- Real-time OLED display: 128x64 SSD1306 I2C display with organized sensor data layout
- Modular architecture: Clean separation between CAN receiver, display driver, and UI rendering
- Thread-safe data handling: FreeRTOS tasks with mutex-protected shared data structure
- Staleness detection: Alerts when sensor data hasn't been received recently (>5 seconds)
- CAN bus health monitoring: Watchdog for CAN disconnection detection
- ESP32-C3 SuperMini (or any ESP32 board)
- SSD1306 OLED Display (128x64, I2C, address 0x3C)
- SN65HVD230 CAN Transceiver (or compatible 3.3v CAN transceiver)
- Power supply (3.3V for ESP32-C3, 5V for CAN transceiver if needed)
| Function | GPIO | Description |
|---|---|---|
| CAN TX | 4 | Connect to SN65HVD230 TX pin |
| CAN RX | 5 | Connect to SN65HVD230 RX pin |
| I2C SDA | 6 | Connect to SSD1306 SDA |
| I2C SCL | 7 | Connect to SSD1306 SCL |
See docs/WIRING.md for detailed wiring diagrams.
CAN Bus Speed: 500 kbps
The client receives the following CAN message IDs:
| ID | Sensor | Data | Update Rate |
|---|---|---|---|
| 0x100 | VEML7700 | Lux value (3-byte, 0-120K), status | 1 Hz |
| 0x101 | BME680 | Temperature, humidity, pressure | 0.33 Hz |
| 0x102 | BME680 | IAQ, CO2 equiv, VOC | 0.33 Hz |
| 0x109 | MQ-3 | Alcohol PPM, ADC, Rs/R0 ratio | 1 Hz |
| 0x107 | LD2410 | Presence, distance, energy levels | 10 Hz |
| 0x10F | System | Active sensors, heap, uptime | 0.1 Hz |
See main/can_protocol.h for complete message format definitions.
┌──────────────────────────────┐
│ 12345 lux (Large) │ ← Light level
├──────────────────────────────┤
│ 23.5C 65% 1013hPa │ ← Environmental data
├──────────────────────────────┤
│ IAQ:120 Good │ ← Air quality
│ Alc:50ppm │ ← Alcohol level
├──────────────────────────────┤
│ P:75cm STALE │ ← Presence / Status
└──────────────────────────────┘
- Top: Lux value (large font)
- Middle: Temperature, Humidity, Pressure (3 columns)
- Bottom: IAQ with quality indicator, Alcohol level
- Status: Presence detection, staleness warning
main.c
├── sensor_data.h (Shared data structure with mutex)
├── can_receiver task (Receives & parses CAN messages)
└── display_ui task (Renders UI at 10 Hz)
- main/main.c: Application entry point, task coordination, system monitoring
- main/can_receiver.c: TWAI driver initialization, CAN message reception and parsing
- main/display_driver.c: SSD1306 I2C driver wrapper, low-level display functions
- main/display_ui.c: UI layout and rendering logic
- main/can_protocol.h: CAN message ID and structure definitions
- main/sensor_data.h: Shared sensor data structure with thread-safe access
- Install ESP-IDF v5.x
- Set up ESP-IDF environment:
. $HOME/esp/esp-idf/export.sh # Or your IDF path
# Clone the repository
git clone https://github.com/yourusername/Esp32-CAN-Disp-Client.git
cd Esp32-CAN-Disp-Client
# Configure the project (optional - defaults are set in sdkconfig.defaults)
idf.py menuconfig
# Build the firmware
idf.py build
# Flash to ESP32-C3
idf.py -p /dev/ttyUSB0 flash
# Monitor serial output
idf.py -p /dev/ttyUSB0 monitorTip: Use idf.py -p /dev/ttyUSB0 flash monitor to flash and monitor in one command.
Default settings are in sdkconfig.defaults. You can customize:
- GPIO pin assignments in
can_receiver.handdisplay_driver.h - CAN bitrate (default: 500 kbps)
- Display update rate (default: 10 Hz)
- Staleness timeout (default: 5 seconds)
- Connect the hardware according to the wiring diagram
- Flash the firmware to the ESP32-C3
- Connect the CAN bus to your sensor network
- The display will show sensor data as it's received
- Monitor serial output for debugging and CAN message logs
I (123) MAIN: ESP32-C3 CAN Display Client
I (456) CAN_RX: Initializing TWAI (CAN) driver
I (789) DISPLAY: Initializing SSD1306 display
I (1012) MAIN: Initialization complete!
I (1234) CAN_RX: VEML7700: Lux=1234.0, Status=0
I (2345) CAN_RX: BME680 ENV: T=23.45°C, H=65%, P=1013.2hPa
- Check CAN TX/RX wiring to TJA1050
- Verify CAN bus termination resistors (120Ω at each end)
- Check CAN bitrate matches sender (500 kbps)
- Use logic analyzer or CAN bus analyzer to verify messages on bus
- Verify I2C connections (SDA/SCL)
- Check I2C address (default 0x3C, some displays use 0x3D)
- Test display with I2C scanner
- Check power supply to display (3.3V or 5V depending on module)
- CAN messages not being received for >5 seconds
- Check CAN bus connection and sender status
- Verify sender is transmitting at expected rates
- Ensure ESP-IDF v5.x is installed and activated
- Run
idf.py fullcleanthen rebuild - Check that all source files are present
- Auto-brightness based on lux sensor reading
- add sensor data logging in sdcard
- Button input to toggle between display screens
- Alert animations (blinking) for high alcohol detection
- WiFi configuration portal
- MQTT forwarding of sensor data
- Integrate u8g2 library for better font support
See LICENSE file.
Pull requests are welcome! Please ensure:
- Code follows existing style and structure
- Comments explain CAN protocol and message formats
- Commit messages are descriptive