Skip to content

rvxfahim/CAN-Demo-ESP32

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

25 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

CAN Bus Demo with ESP32, LVGL, and DBC Code Generation

A demonstration project showcasing CAN bus communication between two ESP32 boards with LVGL GUI, DBC-based code generation, and a modular firmware architecture. This project is ideal for learning CAN protocols, embedded UI development, and code generation workflows.


CAN demo

🎯 What This Project Demonstrates

  1. CAN Bus Communication

    • Dual ESP32 setup: one TX board (transmitter) and one RX board (receiver)
    • 500 kbps CAN communication using ESP32's built-in CAN controller
    • Message filtering, unpacking, and event-driven processing
  2. DBC-Driven Code Generation

    • Define CAN messages in a standard .dbc file
    • Auto-generate C code for encoding/decoding using c-coderdbc
    • Type-safe message handling with generated structs
  3. LVGL Graphical UI (RX Board)

    • Real-time display of CAN data on TFT touchscreen
    • SquareLine Studio integration for UI design
    • Arc gauge for speed, turn signal indicators
  4. Modular Firmware Architecture

    • Event-driven state machine with message routing
    • Pub/sub pattern for decoupled components
    • Health monitoring with automatic degradation and recovery

πŸš€ Quick Start

Prerequisites

  1. Hardware

    • 2x ESP32 boards (e.g., ESP32-EVB or similar)
    • CAN transceivers (e.g., SN65HVD230 or MCP2551)
    • TFT display with touch (for RX board)
    • CAN bus wiring (120Ξ© termination resistors recommended)
  2. Software

    • PlatformIO (VS Code extension or CLI)
    • Python 3.x (for optional documentation builds)
    • Git (to clone this repository)

Installation

  1. Clone the repository

    git clone https://github.com/rvxfahim/CAN-Demo-ESP32.git
    cd CAN-Demo-ESP32
  2. Configure serial ports (if different from defaults)
    Edit platformio.ini and set your COM ports:

    [env:rx_board]
    upload_port = COM8    ; Change to your RX board port
    monitor_port = COM8
    
    [env:tx_board]
    upload_port = COM9    ; Change to your TX board port
    monitor_port = COM9
  3. Build and upload

    RX Board (receiver with display):

    pio run -e rx_board -t upload
    pio device monitor -e rx_board

    TX Board (transmitter):

    pio run -e tx_board -t upload
    pio device monitor -e tx_board
  4. Connect the hardware

    • Wire CAN_H and CAN_L between boards through transceivers
    • Connect 120Ξ© termination resistors at both ends
    • Power both boards
    • TX will start sending Cluster frames; RX display will update

πŸ“– Understanding the DBC Workflow

What is a DBC File?

A DBC (CAN Database) file is an industry-standard format for defining CAN messages, signals, and their properties. It serves as the single source of truth for all CAN communication in this project.

Location: tools/Lecture.dbc

Code Generation Process

This project uses c-coderdbc to auto-generate C encode/decode functions from the DBC file.

Step 1: Edit the DBC File

The example Lecture.dbc defines a Cluster message (ID 0x65) with signals:

  • Speed (12-bit): 0–4095 range
  • Left_Turn_Signal (1-bit): boolean
  • Right_Turn_Signal (1-bit): boolean

You can edit this file with any text editor or use tools like CANdb++ Editor or SavvyCAN.

Step 2: Run the Code Generator

Windows:

cd tools\c-coderdbc
.\build\coderdbc.exe -dbc ..\Lecture.dbc -out ..\..\lib\Generated

This regenerates:

  • lib/Generated/lib/lecture.c and lecture.h (generated code, do not edit)
  • Helper files in lib/Generated/conf/, lib/Generated/inc/, etc.

Linux/macOS:
You'll need to compile c-coderdbc from source (see tools/c-coderdbc/README.md).

Step 3: Use Generated Types in Code

The firmware uses the generated types exclusively:

#include "lecture.h"  // Generated header

// Packing (TX side)
Cluster_t cluster = {0};
cluster.Speed = 2048;
cluster.Left_Turn_Signal = 1;
cluster.Right_Turn_Signal = 0;

uint8_t data[8];
Pack_Cluster_lecture(&cluster, data, 8);
CAN0.sendFrame({ .identifier = 0x65, .data = data, ... });

// Unpacking (RX side)
Cluster_t received;
Unpack_Cluster_lecture(&received, frame.data, frame.data_length_code);

Key principle: Never manually parse CAN bytes. Always use Pack_* and Unpack_* functions.


πŸ—οΈ Project Structure

CAN-Demo-ESP32/
β”œβ”€β”€ platformio.ini           # Build config (two environments: rx_board, tx_board)
β”œβ”€β”€ tools/
β”‚   β”œβ”€β”€ Lecture.dbc          # CAN message definitions (source of truth)
β”‚   └── c-coderdbc/          # DBC-to-C code generator
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ Generated/           # Auto-generated C code (from DBC)
β”‚   β”œβ”€β”€ CanDriver/           # ESP32 CAN driver abstraction
β”‚   β”œβ”€β”€ Ui/                  # LVGL UI (SquareLine Studio exports)
β”‚   └── TouchLibrary/        # Touch controller drivers
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ common/              # Shared code (MessageRouter, etc.)
β”‚   β”œβ”€β”€ rx/                  # RX board firmware (main + modules)
β”‚   β”œβ”€β”€ tx/                  # TX board firmware (main only)
β”‚   └── generated_lecture_dbc.c  # Single include wrapper for DBC code
β”œβ”€β”€ include/                 # Global headers (IOPins, TFT config)
β”œβ”€β”€ docs/                    # Sphinx documentation source
└── README.md                # This file

πŸ“š Documentation

For detailed architecture, sequence diagrams, and API references, see the full documentation:

Topics covered:

  • Getting Started: Detailed setup and hardware connections
  • Architecture: Component diagrams, state machines, data flow
  • CAN & DBC: In-depth DBC workflow and regeneration steps
  • Testing: Unit test guidelines and test hooks
  • API Reference: Doxygen-generated class/function documentation

πŸ”§ Configuration and Customization

CAN Parameters

  • Bitrate: 500 kbps (configurable in CanInterface.cpp)
  • Pins: GPIO 35 (RX), GPIO 5 (TX) β€” change in CanInterface::Initialize()
  • Message ID: 0x65 for Cluster (defined in DBC)

Display and UI

  • Screen: Configured in include/TFTConfiguration.h and lib/Ui/
  • UI Design: Edit with SquareLine Studio, export to lib/Ui/
  • Widgets: Arc gauge (ui_Arc1), labels (ui_RightLabel, ui_LeftLabel)

IO Relays (Blinkers)

  • Pins: GPIO 25 (left), GPIO 26 (right) β€” see include/IOPins.h
  • Blink Rate: 1 Hz (500ms ON/OFF) β€” adjust in IOModule::Update()

Health Monitoring

  • Timeout: 1500ms (RX declares Degraded if no CAN frames) β€” see HealthMonitor.cpp

πŸ§ͺ Testing and Troubleshooting

Common Issues

RX display doesn't update:

  • Verify TX is sending frames (check TX serial monitor)
  • Check CAN wiring and termination resistors
  • Ensure both boards have matching bitrate (500 kbps)

Blinkers don't work:

  • Confirm relay pins in include/IOPins.h match your hardware
  • Verify Left_Turn_Signal / Right_Turn_Signal bits are set in TX

System shows "Degraded":

  • Normal behavior when CAN frames stop arriving (timeout threshold)
  • Should auto-recover when TX resumes

Build Errors

Missing LVGL or TFT_eSPI: PlatformIO will auto-install dependencies from lib_deps in platformio.ini.

Linker errors about Cluster_t: Ensure src/generated_lecture_dbc.c is included in the build (check build_src_filter).


🀝 Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit changes (git commit -m 'Add amazing feature')
  4. Push to branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the GPLV3 License. See LICENSE file for details.


πŸ”— Key Technologies

  • PlatformIO β€” Cross-platform embedded build system
  • LVGL v9.1 β€” Lightweight graphics library
  • TFT_eSPI β€” Fast TFT display driver
  • SquareLine Studio β€” Drag-and-drop LVGL UI designer
  • c-coderdbc β€” DBC-to-C code generator
  • ESP32 Arduino β€” Arduino framework for ESP32

πŸ“ž Questions or Support

Releases

No releases published

Packages

No packages published