A distributed Electric Vehicle (EV) Battery Monitoring and Diagnostic System implemented in C on Linux using SocketCAN.
The project models a small automotive network made up of independent software ECUs that communicate over a virtual CAN bus (vcan0). It demonstrates periodic CAN communication, event-driven diagnostic communication, signal encoding/decoding, battery monitoring, thermal management, fault detection, ECU/node failure detection, recovery, and a console-based dashboard.
Project repository: https://github.com/Sanket5358/EV_Battery_SocketCAN
An EV battery system is not normally controlled by one software module. Different electronic control units perform different functions and exchange information over an in-vehicle communication network.
This project reproduces that architecture in a Linux environment.
Instead of connecting physical CAN transceivers and a real battery pack, the project uses:
- Linux
- C programming
- SocketCAN
- Virtual CAN interface:
vcan0 can-utils- Multiple independent ECU processes
The system is intentionally divided into separate applications so that each ECU has its own responsibility and communicates with other ECUs only through CAN messages.
| ECU | Purpose |
|---|---|
| Battery Sensor ECU | Generates battery measurements |
| BMS Controller ECU | Processes battery data and determines battery status |
| Thermal ECU | Monitors temperature and handles cooling |
| Diagnostic ECU | Detects abnormal conditions and communication failures |
| Dashboard | Displays the complete system status and accepts user commands |
The main objectives of the project are:
- Build a distributed multi-ECU application using SocketCAN.
- Use a virtual CAN interface (
vcan0) for communication. - Define a common CAN message and signal specification.
- Implement at least eight unique CAN messages.
- Demonstrate periodic CAN communication.
- Demonstrate event-triggered communication.
- Decode and encode CAN signals correctly.
- Monitor battery cell voltage, pack voltage, current and SOC.
- Monitor battery temperature and cooling status.
- Implement battery warning/fault logic.
- Implement a dedicated Diagnostic ECU.
- Detect abnormal battery conditions.
- Detect missing CAN messages / ECU communication failure.
- Demonstrate ECU/node failure.
- Demonstrate recovery after communication is restored.
- Provide a console dashboard for system monitoring.
- Verify actual CAN traffic using
candump. - Keep normal operation code separate from fault-injection code.
- Maintain the project as a reproducible source-code repository.
The system is organized as independent ECU applications connected through the virtual CAN bus.
VIRTUAL CAN BUS
vcan0
|
---------------------------------------------------------
| | | |
| | | |
v v v v
+----------------+ +----------------+ +----------------+ +----------------+
| Battery Sensor | | BMS Controller | | Thermal ECU | | Diagnostic ECU |
| ECU | | ECU | | | | |
+----------------+ +----------------+ +----------------+ +----------------+
| | | |
| | | |
| 0x100-0x103 | 0x300/0x301 | 0x200/0x201 | 0x400
| | | |
+------------------+------------------+-------------------+
|
v
+------------------+
| Dashboard |
| HMI |
+------------------+
|
|
0x401
|
v
BMS Controller ECU
Battery Sensor ECU
|
| Cell voltage / Pack voltage / Current / SOC
| 0x100 - 0x103
v
BMS Controller ECU
|
| Battery status / Cooling command
| 0x300 / 0x301
v
Thermal ECU / Dashboard
Thermal ECU
|
| Temperature / Fan status
| 0x200 / 0x201
v
Diagnostic ECU / Dashboard
Diagnostic ECU
|
| Diagnostic fault
| 0x400
v
Dashboard
Dashboard
|
| User command
| 0x401
v
BMS Controller ECU
File:
battery_sensor_ecu/battery_sensor.c
Responsibilities:
- Generate simulated cell voltages.
- Generate pack voltage.
- Generate battery current.
- Generate SOC.
- Encode values into CAN frames.
- Periodically transmit battery measurement messages.
The normal sensor ECU represents normal battery operation.
File:
bms_controller_ecu/bms_controller.c
Responsibilities:
- Receive battery measurement messages.
- Decode cell voltages.
- Decode pack voltage.
- Decode battery current.
- Decode SOC.
- Determine battery status.
- Generate cooling commands.
- Send battery status and cooling information.
Battery status is represented as:
0 = NORMAL
1 = WARNING
2 = FAULT
File:
thermal_ecu/thermal.c
Responsibilities:
- Simulate battery temperature.
- Receive cooling commands.
- Control simulated fan status.
- Change temperature according to cooling state.
- Transmit temperature information.
- Transmit thermal/fan status.
The thermal model is intentionally simple because the purpose of this project is communication and distributed ECU behavior rather than physical thermal modeling.
File:
diagnostic_ecu/diagnostic.c
The Diagnostic ECU is responsible for system-level fault monitoring.
It checks:
- Cell overvoltage
- Cell undervoltage
- Invalid pack voltage
- Excessive battery current
- Invalid SOC
- Overtemperature
- Missing communication from monitored ECUs
The Diagnostic ECU maintains timestamps for the last received messages.
If a required message is not received within the configured timeout period, a communication timeout fault is generated.
Example:
FAULT_SENSOR_TIMEOUT
The diagnostic result is transmitted using CAN ID:
0x400
Source:
dashboard/dashboard.c
The dashboard provides a simple console-based HMI.
It displays:
- Pack voltage
- Battery current
- SOC
- Temperature
- Cooling fan state
- Battery status
- Diagnostic status
- CAN interface status
The dashboard also supports the user-command path through CAN ID 0x401.
The project uses standard CAN identifiers on:
vcan0
| CAN ID | Transmitter | Receiver | Signal / Purpose | DLC | Type |
|---|---|---|---|---|---|
0x100 |
Battery Sensor | BMS, Diagnostic | Four cell voltages | 8 | Periodic |
0x101 |
Battery Sensor | BMS, Diagnostic | Pack voltage | 2 | Periodic |
0x102 |
Battery Sensor | BMS, Diagnostic | Battery current | 2 | Periodic |
0x103 |
Battery Sensor | BMS, Diagnostic | SOC | 1 | Periodic |
0x200 |
Thermal ECU | Diagnostic, Dashboard | Temperature | 2 | Periodic |
0x201 |
Thermal ECU | Dashboard | Thermal/Fan status | 1 | Periodic |
0x300 |
BMS Controller | Thermal, Dashboard | Cooling command | 1 | Control |
0x301 |
BMS Controller | Dashboard | Battery status | 1 | Status |
0x400 |
Diagnostic ECU | Dashboard | Diagnostic fault | 1 | Event-triggered |
0x401 |
Dashboard | BMS Controller | User command | 1 | Event-triggered |
The system contains 10 unique CAN IDs, which exceeds the minimum requirement of eight unique CAN messages.
All multi-byte signals use two-byte unsigned integer values and are transmitted in little-endian order.
Eight data bytes contain four cell voltages.
Byte 0-1 → Cell 1
Byte 2-3 → Cell 2
Byte 4-5 → Cell 3
Byte 6-7 → Cell 4
Resolution:
0.001 V
Encoding:
raw_value = voltage × 1000
Example:
3.720 V × 1000 = 3720
Byte 0-1 → Pack Voltage
Resolution:
0.01 V
Encoding:
raw_value = voltage × 100
Example:
14.98 V × 100 = 1498
Byte 0-1 → Battery Current
Resolution:
0.1 A
Encoding:
raw_value = current × 10
Example:
25.0 A × 10 = 250
Byte 0 → SOC
Resolution:
1 %
Example:
77 % → 0x4D
Byte 0-1 → Temperature
Resolution:
0.1 °C
Encoding:
raw_value = temperature × 10
Example:
44.7 °C × 10 = 447
0 → NORMAL
1 → WARNING
2 → FAULT
0 → COOLING OFF
1 → COOLING ON
0x00 → NO FAULT
0x01 → CELL OVERVOLTAGE
0x02 → CELL UNDERVOLTAGE
0x03 → OVER TEMPERATURE
0x04 → SENSOR ECU TIMEOUT
0x05 → ECU COMMUNICATION FAULT
1 → User requests cooling ON
2 → User requests cooling OFF
The exact command handling should follow the implementation in the BMS Controller source.
EV_Battery_SocketCAN/
│
├── battery_sensor_ecu/
│ ├── battery_sensor.c
│ └── battery_sensor_overvoltage.c
│
├── bms_controller_ecu/
│ └── bms_controller.c
│
├── thermal_ecu/
│ └── thermal.c
│
├── diagnostic_ecu/
│ └── diagnostic.c
│
├── dashboard/
│ └── dashboard.c
│
├── include/
│ └── can_ids.h
│
├── Makefile
├── README.md
└── logs/
The normal battery sensor file is intentionally kept unchanged for normal operation.
The file:
battery_sensor_ecu/battery_sensor_overvoltage.c
is used only for fault injection/testing.
This makes the testing process reproducible without permanently modifying the normal sensor behavior.
Recommended environment:
- Ubuntu Linux
- GCC
- GNU Make
- Linux SocketCAN
iproute2can-utils- Git
- GitHub account
Install the required CAN utilities if they are not already available:
sudo apt update
sudo apt install can-utilsCheck GCC:
gcc --versionCheck Make:
make --versionCheck CAN utilities:
candump --versionThe core project does not require physical CAN hardware.
The current implementation uses:
Linux PC
|
└── vcan0
A physical CAN interface can be added later for hardware validation.
Open a terminal.
ip link show vcan0If it does not exist, create it:
sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set vcan0 upVerify:
ip link show vcan0You should see an interface named:
vcan0
Simply bring it up:
sudo ip link set vcan0 upA new user can obtain the project using:
git clone https://github.com/Sanket5358/EV_Battery_SocketCAN.gitEnter the project:
cd EV_Battery_SocketCANCheck the files:
find . -maxdepth 2 -type f | sortFirst try the Makefile:
makeThen check the generated executables:
lsIf the Makefile is not being used, applications can be compiled individually.
Example:
gcc -Wall -Iinclude battery_sensor_ecu/battery_sensor.c -o battery_sensorgcc -Wall -Iinclude bms_controller_ecu/bms_controller.c -o bms_controllergcc -Wall -Iinclude thermal_ecu/thermal.c -o thermalgcc -Wall -Iinclude diagnostic_ecu/diagnostic.c -o diagnosticgcc -Wall -Iinclude dashboard/dashboard.c -o dashboard_appFor the overvoltage fault-injection application:
gcc -Wall -Iinclude battery_sensor_ecu/battery_sensor_overvoltage.c -o battery_sensor_overvoltageBecause each ECU is a separate process, it is easiest to use separate terminal windows/tabs.
cd ~/EV_Battery_SocketCAN
./battery_sensorExpected behavior:
- Generates battery values.
- Sends
0x100. - Sends
0x101. - Sends
0x102. - Sends
0x103.
cd ~/EV_Battery_SocketCAN
./bms_controllerExpected behavior:
- Receives battery data.
- Decodes values.
- Determines battery status.
- Sends BMS control/status messages.
cd ~/EV_Battery_SocketCAN
./thermalExpected behavior:
- Simulates temperature.
- Processes cooling command.
- Sends temperature and thermal status.
cd ~/EV_Battery_SocketCAN
./diagnosticExpected behavior:
- Receives monitored CAN messages.
- Checks battery/thermal conditions.
- Checks communication timeouts.
- Sends diagnostic status using
0x400.
The source directory is called dashboard, so the executable should be run using its executable name:
cd ~/EV_Battery_SocketCAN
./dashboard_appThe dashboard displays the live system state.
Open another terminal:
candump vcan0You should see CAN traffic similar to:
vcan0 100 [8] ...
vcan0 101 [2] ...
vcan0 102 [2] ...
vcan0 103 [1] ...
vcan0 200 [2] ...
vcan0 201 [1] ...
vcan0 300 [1] ...
vcan0 301 [1] ...
vcan0 400 [1] ...
Press:
Ctrl + C
to stop candump.
Example:
vcan0 100 [8] BC 0E B7 0E 58 0E B2 0E
This means:
Interface : vcan0
CAN ID : 0x100
DLC : 8
Data : BC 0E B7 0E 58 0E B2 0E
For ID 0x100:
BC 0E → Cell 1
B7 0E → Cell 2
58 0E → Cell 3
B2 0E → Cell 4
Because the project uses little-endian encoding:
0x0EBC = 3772 → 3.772 V
0x0EB7 = 3767 → 3.767 V
0x0E58 = 3672 → 3.672 V
0x0EB2 = 3762 → 3.762 V
This is useful when manually validating CAN frames.
Verify that all ECUs communicate normally.
- Start
vcan0. - Start Battery Sensor ECU.
- Start BMS Controller ECU.
- Start Thermal ECU.
- Start Diagnostic ECU.
- Start Dashboard.
- Run
candump vcan0.
The system should continuously exchange CAN messages.
Typical monitored values are around:
Cell voltages : approximately 3.7 V
Pack voltage : approximately 15 V
Current : approximately 25 A
SOC : simulated percentage
Temperature : simulated normal temperature
Diagnostic state should remain:
NO FAULT
PASS
The project includes a separate fault-injection application:
battery_sensor_ecu/battery_sensor_overvoltage.c
This allows the normal battery sensor implementation to remain unchanged.
Verify cell overvoltage detection.
The test application generates a cell voltage above the normal threshold.
Example:
Cell 1 = 4.300 V
Diagnostic threshold:
4.20 V
Therefore:
4.300 V > 4.20 V
gcc -Wall -Iinclude \
battery_sensor_ecu/battery_sensor_overvoltage.c \
-o battery_sensor_overvoltageStop the normal battery sensor first, then run:
./battery_sensor_overvoltageKeep the BMS and Diagnostic ECU running.
The Diagnostic ECU should identify:
CELL OVERVOLTAGE
The dashboard should display the corresponding diagnostic condition when it receives the diagnostic message.
PASS
Verify that the Diagnostic ECU detects a missing ECU/message.
- Start the complete system.
- Confirm normal CAN traffic.
- Run
candump vcan0. - Stop one monitored ECU.
- Continue observing the Diagnostic ECU.
- Wait longer than the configured communication timeout.
The Diagnostic ECU should identify the missing communication.
Example:
FAULT STATUS : SENSOR ECU TIMEOUT
The corresponding diagnostic CAN frame is:
CAN ID = 0x400
Data = 0x04
Example observed frame:
vcan0 400 [1] 04
This means:
0x04 = SENSOR ECU TIMEOUT
PASS
Verify that the system recovers after the failed ECU is restarted.
- Stop the selected ECU.
- Confirm timeout fault.
- Restart the ECU.
- Observe CAN traffic.
- Observe Diagnostic ECU.
- Observe Dashboard.
Fresh CAN messages should be received again.
The timeout condition should clear when communication is restored.
Expected diagnostic state:
NO FAULT
PASS
Verify temperature communication.
The Thermal ECU periodically transmits:
0x200
Temperature is encoded with:
0.1 °C resolution
Example:
44.7 °C
Encoded raw value:
447 decimal
CAN bytes:
BF 01
because:
0x01BF = 447
The Dashboard and Diagnostic ECU can use the temperature message.
PASS
The BMS Controller sends a cooling command using the defined control message.
The Thermal ECU receives the command and changes the simulated cooling/fan behavior.
Cooling states:
0 → OFF
1 → ON
The Thermal ECU reports its status through the thermal status message.
This demonstrates a control path rather than only sensor-data communication.
PASS
The Diagnostic ECU reports detected faults using:
CAN ID 0x400
Example:
vcan0 400 [1] 04
Interpretation:
CAN ID = 0x400
DLC = 1
Data = 0x04
0x04 = SENSOR ECU TIMEOUT
This provides an event-triggered diagnostic communication path from the Diagnostic ECU to the Dashboard.
PASS
The Dashboard receives system information and displays:
Pack Voltage
Battery Current
State of Charge
Battery Temperature
Cooling Fan
Battery Status
Diagnostic Status
The Dashboard also supports the user-command communication path.
PASS
| Test ID | Test | Expected Result | Result |
|---|---|---|---|
| TC-01 | Normal ECU communication | All ECUs exchange CAN messages | PASS |
| TC-02 | Cell overvoltage | Diagnostic fault generated | PASS |
| TC-03 | Node/message failure | Communication timeout detected | PASS |
| TC-04 | ECU recovery | Communication restored and timeout cleared | PASS |
| TC-05 | Temperature monitoring | Temperature message received | PASS |
| TC-06 | Cooling control | Cooling command/fan state operates | PASS |
| TC-07 | Diagnostic reporting | Fault message transmitted on 0x400 | PASS |
| TC-08 | Dashboard | Live system status displayed | PASS |
| TC-09 | CAN traffic | CAN frames visible using candump | PASS |
The project was designed to cover the major requirements of the distributed SocketCAN assignment.
| Requirement | Implementation |
|---|---|
| Distributed system | Five independent ECU applications |
| Linux SocketCAN | CAN RAW sockets using SocketCAN |
| Virtual CAN | vcan0 |
| Minimum 4 ECUs | 5 ECUs |
| Minimum 8 CAN messages | 10 CAN IDs |
| CAN message matrix | Included in this README |
| Signal definitions | Included in this README |
| Periodic communication | Battery and thermal messages |
| Event-triggered communication | Diagnostic 0x400 and user command 0x401 |
| CAN decoding | Implemented in receiver ECUs |
| CAN encoding | Implemented in transmitting ECUs |
| Fault detection | Diagnostic ECU |
| Sensor fault | Overvoltage test |
| Communication timeout | Timestamp-based monitoring |
| Node failure | ECU stopping test |
| Recovery | ECU restart test |
| HMI | Console dashboard |
| CAN verification | candump vcan0 |
| Source-code repository | GitHub |
This normally means vcan0 does not exist.
Run:
sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set vcan0 upCheck:
ip link show vcan0Then restart the ECU application.
First verify that vcan0 is up:
ip link show vcan0If necessary:
sudo ip link set vcan0 upCheck:
ip link show vcan0Then:
candump vcan0Start the Battery Sensor ECU and check whether IDs 0x100–0x103 appear.
If no frames appear, verify that the sensor application is running and was compiled successfully.
Do not use:
./dashboardif dashboard is the source directory.
Compile the source as:
gcc -Wall -Iinclude dashboard/dashboard.c -o dashboard_appThen run:
./dashboard_appThe Diagnostic ECU uses communication timestamps.
If the required ECUs are not running, it is expected to eventually report a timeout.
Start the required transmitting ECUs first:
Battery Sensor
Thermal ECU
Then start the Diagnostic ECU.
This means Make believes the executable is already built and no source dependency has changed.
If you intentionally want to rebuild:
make clean
makeIf your Makefile does not contain clean, remove the executable manually and run make again.
ip link show vcan0sudo ip link set vcan0 upcandump vcan0cansend vcan0 123#11223344candump vcan0,400:7FFcandump vcan0,100:7FFcandump vcan0For this project, observing the complete bus is generally more useful during system-level testing.
When modifying the project:
cd ~/EV_Battery_SocketCANCheck the current state:
git statusAfter making changes:
git add .Create a meaningful commit:
git commit -m "Update diagnostic timeout handling"Push to GitHub:
git pushFor example:
git commit -m "Add overvoltage fault test"
git pushFor a clean demonstration, use this order.
sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set vcan0 upmakeStart:
candump
Start:
Battery Sensor ECU
BMS Controller ECU
Thermal ECU
Diagnostic ECU
Dashboard
Show:
- Battery values
- Temperature
- BMS status
- Dashboard
- Normal CAN traffic
Run the fault-injection application.
Show:
CELL OVERVOLTAGE
Stop a monitored ECU.
Show:
SENSOR ECU TIMEOUT
and:
0x400 [1] 04
in candump.
Restart the ECU.
Show:
NO FAULT
Capture screenshots of:
vcan0configuration- Normal Battery Sensor
- BMS Controller
- Thermal ECU
- Diagnostic ECU
- Dashboard
- Fault injection
- Timeout fault
- Recovery
candump
For academic evaluation, screenshots should demonstrate actual execution rather than only source code.
Recommended evidence:
01_vcan0_setup.png
02_battery_sensor_normal.png
03_bms_normal.png
04_thermal_normal.png
05_diagnostic_normal.png
06_dashboard_normal.png
07_overvoltage_fault.png
08_timeout_fault.png
09_recovery.png
10_candump_traffic.png
A useful diagnostic screenshot is:
vcan0 400 [1] 04
which represents:
0x400 → Diagnostic status
0x04 → SENSOR ECU TIMEOUT
This project is a software-based educational implementation.
It does not currently claim to be a production-ready automotive BMS.
The current system:
- Uses simulated battery values.
- Uses a virtual CAN interface.
- Uses console applications.
- Does not connect to a physical battery pack.
- Does not implement a production-grade automotive CAN database.
- Does not provide functional-safety certification.
- Does not replace a real BMS.
The purpose is to demonstrate distributed ECU communication, CAN protocol handling, monitoring, diagnostics and fault management.
Possible extensions include:
- STM32-based physical ECUs
- CAN transceiver
- Real cell-voltage measurement
- Current sensor
- Temperature sensors
- Real cooling fan
- Physical CAN bus
- CAN error handling
- Bus-off recovery
- CAN FD
- Message counters
- Alive supervision
- CRC protection
- Persistent DTC storage
- Fault history
- Fault severity
- Fault aging
- Diagnostic session handling
- UDS-based diagnostics
- State of Health estimation
- Cell balancing
- Remaining-range estimation
- Thermal prediction
- Abnormal-cell detection
- Predictive maintenance
- Graphical dashboard
- Real-time plots
- Alarm indicators
- Fault history
- Data logging
Repository:
https://github.com/Sanket5358/EV_Battery_SocketCAN
Project name:
EV_Battery_SocketCAN
Technology:
C
Linux
SocketCAN
Virtual CAN
can-utils
Git/GitHub
Communication interface:
vcan0
Number of modeled ECUs:
5
Number of defined CAN IDs:
10
This project demonstrates a complete distributed EV battery monitoring network using Linux SocketCAN.
The Battery Sensor ECU generates battery measurements. The BMS Controller processes those measurements and determines battery status. The Thermal ECU handles temperature and cooling behavior. The Diagnostic ECU supervises the system and detects abnormal values and communication failures. The Dashboard provides a human-readable view of the complete system.
The project goes beyond simple CAN transmission by demonstrating:
- Multiple independent ECUs
- Defined CAN message architecture
- Periodic communication
- Event-triggered communication
- Signal encoding and decoding
- Battery monitoring
- Thermal management
- Fault detection
- Communication timeout detection
- Node failure
- Recovery
- Fault injection
- CAN traffic verification
- Dashboard monitoring
The complete source code is maintained in the GitHub repository for reproducibility and further development.
This project is intended for educational and academic use.
If this repository is later reused or extended, add an explicit open-source license that matches the intended usage.
Sanket Chavan
Project: EV Battery Monitoring System Using Linux SocketCAN
The following screenshots demonstrate the implementation and testing of the distributed EV Battery Monitoring System using Linux SocketCAN and vcan0.
The screenshots demonstrate:
- Virtual CAN interface setup
- Battery Sensor ECU operation
- BMS Controller operation
- Thermal ECU operation
- Diagnostic ECU operation
- Dashboard monitoring
- CAN traffic using
candump - Overvoltage fault injection
- Fault detection
- Communication timeout detection
- ECU recovery
- Multi-ECU CAN communication


















