CAN BUS · HARDWARE IN THE LOOP

CAN Bus HIL
Test System

A physical Hardware-in-the-Loop test bench built with BeagleBone Black and ESP32, communicating over CAN bus at 500 kbps — verified with Saleae Logic Analyzer.

500kbps bitrate
16/16tests passed
0CRC errors
<1msround-trip
Concept

What is HIL?

Hardware-in-the-Loop (HIL) is a test methodology where real hardware is validated against simulated signals — mirroring how Volvo Cars, Bosch, and Continental verify ECU behaviour before integration with physical actuators.

Master
BBB
Sends test commands, validates responses, logs results
Slave
ESP32
Simulates an ECU — processes commands, replies over CAN
Protocol
CAN
Physical bus, twisted-pair, 120 Ω termination both ends
Verification
Saleae
Logic Analyzer — CAN protocol decoder, 500 kbps

Hardware

Components

All components breadboarded with twisted-pair CAN cable and 120 Ω termination at each end of the bus.

Component Role Interface Voltage
BeagleBone Black HIL Master — SocketCAN / C P9_19 / P9_20 3.3 V
ESP32 HIL Slave — TWAI driver / C++ GPIO4 / GPIO5 3.3 V
SN65HVD230 ×2 CAN transceiver — no level shifter needed Differential 3.3 V
120 Ω resistors Bus termination — both ends of CAN line CAN-H ↔ CAN-L
INA219 Power monitor — current & voltage measurement I2C 3.3 V
Saleae Logic Analyzer Signal verification — CAN protocol decoder Tap point on CAN-H Passive

Wiring

Connections

Both SN65HVD230 transceivers share the same CAN-H / CAN-L twisted-pair bus. Termination resistors sit at the outermost nodes.

Wiring diagram — ASCII 500 kbps · twisted-pair · 120 Ω each end
BeagleBone Black SN65HVD230 #1 P9_20 (CAN0 TX) ──────────► D P9_19 (CAN0 RX) ◄────────── R P9_3 (3.3 V) ──────────► VCC P9_1 (GND) ──────────► GND │ CAN-H ──[120Ω]───────────────────── CAN-H CAN-L ─────────────────────[120Ω]── CAN-LESP32 SN65HVD230 #2 │ GPIO4 (TX) ──────────► D ──┘ GPIO5 (RX) ◄────────── R 3.3 V ──────────► VCC GND ──────────► GND

Protocol

Message Format

Standard 11-bit CAN frames. BBB sends commands on ID 0x100; ESP32 responds on ID 0x200.

BBB → ESP32 · Command frame · ID 0x100
Byte 0CMD code
Byte 1VALUE high byte
Byte 2VALUE low byte
Bytes 3–7Reserved 0x00
ESP32 → BBB · Response frame · ID 0x200
Byte 00xFF OK / 0xEE ERR
Byte 1CMD echo
Byte 2VALUE high byte
Bytes 3–7Reserved 0x00

Test Scenarios

Validation Cases

Four scenarios run in a continuous loop with 1-second timeout per frame and automatic pass/fail logging to hil_log.txt.

CMD 0x0F
Heartbeat
Connection check — verifies CAN link is alive between master and slave.
→ RESP 0xFF OK
CMD 0x01
Engine RPM
Sends RPM (0–8000). Out-of-range values return 0xEE error.
→ 3000 RPM · 0xFF OK
CMD 0x02
Fuel Injection
Sends injection duty-cycle value. Slave acknowledges control command.
→ 0x1F · 0xFF OK
CMD 0x03
Temperature
Sends coolant temp (0–150 °C). Over-range triggers error response.
→ 85 °C · 0xFF OK

Logic Analyzer

Signal Capture

CAN bus signal captured on CAN-H line using Saleae Logic 2 with the CAN protocol decoder active at 500 kbps, 87.5% sample point.

Saleae Logic 2 · CAN decoder · D0 channel · 2 MHz sample rate 500 000 bps
Logic analyzer capture showing CAN frames 0x100 and 0x200 with protocol decode
0x100 BBB → ESP32 command frame
0x200 ESP32 → BBB response frame
~50 ms frame interval
~1 s test cycle
CRC-15 no errors detected
87.5% sample point

Output

Test Log

Automated pass/fail log generated on BeagleBone Black. Full log saved to hil_log.txt.

root@BeagleBone:/home/debian/hil_project — ./hil_master can0
===========================================
HIL Master - BeagleBone Black
CAN Bus HIL Test Sistemi v1.0
===========================================
 
[11:10:49] HIL Master baslatildi - can0 @ 500kbps
--- Test Turu 1 ---
[11:10:49] GONDERILDI: [Heartbeat] CMD=0x0F VALUE=0
[11:10:49] BASARILI: [Heartbeat] ESP32 cevabi OK
[11:10:50] GONDERILDI: [Motor RPM 3000] CMD=0x01 VALUE=3000
[11:10:50] BASARILI: [Motor RPM 3000] ESP32 cevabi OK
[11:10:51] GONDERILDI: [Yakit Enjeksiyonu] CMD=0x02 VALUE=31
[11:10:51] BASARILI: [Yakit Enjeksiyonu] ESP32 cevabi OK
[11:10:52] GONDERILDI: [Sicaklik 85C] CMD=0x03 VALUE=85
[11:10:52] BASARILI: [Sicaklik 85C] ESP32 cevabi OK
[11:10:53] OZET: Toplam=4 Basarili=4 Basarisiz=0
 
--- Test Turu 2 ---
[11:10:55] GONDERILDI: [Heartbeat] CMD=0x0F VALUE=0
[11:10:55] BASARILI: [Heartbeat] ESP32 cevabi OK
[11:10:56] GONDERILDI: [Motor RPM 3000] CMD=0x01 VALUE=3000
[11:10:56] BASARILI: [Motor RPM 3000] ESP32 cevabi OK
... (continuing)
 
[11:11:12] OZET: Toplam=16 Basarili=16 Basarisiz=0

Results

Test Report

All four test scenarios passed across multiple continuous test cycles with zero errors.

16/16 test scenarios passed
0 CRC errors detected
500k bps stable bitrate
<1ms round-trip latency
↗ View full source on GitHub — bahadir2/hil_project