Skip to content

Repository files navigation

BlueSentinel: Multi-Protocol Battery Management System (BMS)

BlueSentinel Demo

BlueSentinel is an open-source, multi-protocol Battery Management System (BMS) firmware built on FreeRTOS for the STM32F103C8T6 (Blue Pill) microcontroller. It integrates critical battery protection algorithms with three concurrent, native communications protocols: Modbus RTU slave (RS-485), CAN 2.0B (internal bxCAN), and MQTT telemetry (WiFi).


Value Proposition

Off-the-shelf low-cost BMS boards (such as JBD or Daly) successfully protect cells but rely on proprietary serial protocols and lack native fieldbus or IoT connectivity. Bridging these batteries to vehicle controllers, PLCs, or cloud dashboards requires developers to buy external protocol converters (e.g. Modbus gateways, CAN converters) costing ₹12,000–₹25,000 per installation.

BlueSentinel eliminates this overhead by running all three communication channels natively on a single STM32 MCU alongside cell protection. This is ideal for startups, labs, and hobbyists building drones, e-bikes, autonomous robots, or solar storage.

Feature Off-the-Shelf BMS BlueSentinel
Battery Protection (OV, UV, OT, OC) Yes Yes
CAN Bus (Vehicles, Drones, Robots) No Yes (CAN 2.0B native)
Modbus RTU (PLCs, SCADA) No Yes (FC 03/06/10 slave)
WiFi MQTT (Cloud dashboard) No Yes (JSON Telemetry)
Custom Overcurrent Curves No (Hardcoded) Yes (Device 51 Inverse-Time)
Open Source No (Closed/Proprietary) Yes (MIT License)

System Architecture

All three communication tasks operate on the same snapshot memory location protected by a FreeRTOS mutex, providing a single source of truth and preventing synchronization drift between vehicle CAN networks, PLCs, and cloud dashboards.

                                 [ Hardware Sensors ]
                                          │
                                          ▼ (shim_read_sensors)
┌──────────────────────────────────────────────────────────────────────────────────┐
│ SensorRead Task (Prio 3, 10ms)                                                    │
└──────────────────────────────────────────────────────────────────────────────────┘
                                          │
                                          ▼ (xQueueOverwrite)
                                    [sensor_queue]
                                          │
                                          ▼ (xQueueReceive)
┌──────────────────────────────────────────────────────────────────────────────────┐
│ BMSLogic Task (Prio 2, 50ms)                                                     │
│                                                                                  │
│   ├── Run FSM (bms_logic_update) ─────────────────► [ Relay Command (GPIO) ]     │
│   │                                                                              │
│   ├── Update shared state/registers ◄─────────────► [ bms_snapshot_mutex ]       │
│   │                                                          ▲                   │
│   └── Format telemetry JSON                                  │                   │
└──────────────────────────────────────────────────────────────┼───────────────────┘
               │                                               │
               ▼ (shim_uart_write USART1)                      │
        [ ESP8266 Bridge ]                                     │
               │                                               │
               ▼ (WiFi/MQTT)                                   │
      [ MQTT Broker (mosquitto) ]                              │
                                                               │
                       ┌───────────────────────────────────────┴───────────┐
                       │                                                   │
                       ▼                                                   ▼
┌──────────────────────────────────────────┐   ┌──────────────────────────────────────────┐
│ ModbusSlave Task (Prio 1, Polled/Event)  │   │ CANTxRx Task (Prio 1, 50ms)              │
│                                          │   │                                          │
│   ├── Read UART (USART3/RS485)           │   │   ├── Pack & Send (0x100-0x103)          │
│   ├── Process (modbus_core_process)      │   │   └── Recv control (0x200 relay open)    │
│   └── Send UART response                 │   │                                          │
└──────────────────────────────────────────┘   └──────────────────────────────────────────┘
             ▲                                               ▲
             │ (USART3/RS485)                                │ (bxCAN/vcan0)
             ▼                                               ▼
     [ Modbus Master ]                                  [ CAN Bus ]

Quickstart (Host Simulation)

To build and run the entire system simulation locally on a Linux development machine:

  1. Set up the Python Environment:

    python3 -m venv .venv
    source .venv/bin/activate
    pip install -r requirements.txt
  2. Run all compilation and test gates:

    ./tools/gate.sh all
  3. Execute the end-to-end integration demo: Ensure virtual CAN is set up (vcan0) and the local MQTT broker is available, then run:

    ./tools/demo.sh

Simulation

In addition to host-based POSIX simulation, the firmware can be emulated on target hardware models using the Renode emulation framework.

Renode Emulation

The ARM target binary (bluesentinel.elf) is loaded into Renode using a simulated STM32F103 platform. This smoke-tests the real firmware image, verifying that the FreeRTOS scheduler boots and the telemetry loop executes.

To run the Renode smoke test:

./tools/renode_gate.sh

This is a local verification gate. It is not run inside GitHub Actions CI due to the download footprint of the portable Renode package. For details on emulator stubs, watchpoint hooks, and limitations, see docs/renode.md.


Host Simulation Metrics

The following metrics are extracted from a real 30-second host simulation run under the thermal_runaway.csv scenario (logs stored in qa/):

Demo Output Excerpt (summary.txt)

BlueSentinel Host Simulation Demo Summary
=========================================
Duration: 30 seconds
Scenario: thermal_runaway.csv

Counts:
-------
Modbus Polls: 140
CAN Frames: 2208
MQTT Telemetry Messages: 137

Protection Events:
------------------
Trip Event: EVENT: Relay OPEN at 2028 ms

Protocol Performance (Host Simulation)

Metric Measured Value (Host Simulation) Note / Protocol Details
Modbus Transaction Rate ~4.7 polls / sec Polled via pymodbus RTU master at 10 Hz over virtual PTY
CAN Frame Transmission Rate ~73.6 frames / sec 4 distinct telemetry frames (0x100–0x103) sent every 50 ms over vcan0
MQTT Telemetry Rate ~4.6 messages / sec JSON strings published to bluesentinel/telemetry over port 18830
Thermal Trip Latency 2028 ms Trip occurred when simulated NTC temperature exceeded 50.0 °C

RTOS Runtime Evidence (10s Normal Charge)

Task Stack High Watermark (Words Free) Notes
SensorRead 507 Stack size: 512 words
BMSLogic 507 Stack size: 512 words
ModbusSlave 507 Stack size: 512 words
CANTxRx 507 Stack size: 512 words
Watchdog 507 Stack size: 512 words
Idle hook 1,617,224,675 hits Demonstrates vast CPU headroom during nominal load

Limitations & Future Work

  • No SoC or fault-latch persistence: State of Charge (SoC) and fault states are lost across power cycles and resets.
  • CAN bus-off recovery absent: The system does not implement or simulate recovery from CAN bus-off conditions.
  • Hardware IWDG unexercised: The hardware Independent Watchdog (IWDG) is never fully exercised in simulation; only the software watchdog task is tested.
  • No MQTT TLS/auth: The MQTT telemetry bridge currently uses no Transport Layer Security (TLS) or authentication.
  • PTY Modbus timing: Modbus RTU timing over the virtual PTY is not strictly t3.5-accurate per the Modbus specification.
  • Cell balancing absent: The system implements cell imbalance detection but lacks the active or passive balancing logic/hardware required to correct it.
  • Physical Hardware Bench Validation: Flashing target binary onto physical STM32F103 board and validating sensor readings against real battery cells. (Incomplete / Pending)
  • Custom PCB Design: Designing a KiCad motherboard incorporating the Blue Pill, RS-485 transceiver, CAN transceiver, ACS712 secondary current sensor, and INA226 primary sensor. (Incomplete / Pending)
  • Academic Paper Submission: Formatting and submitting an IJERT/JETIR paper on the resource consumption and latency bounds of multi-protocol RTOS firmware. (Incomplete / Pending)

References

BlueSentinel builds upon and cites the following academic and technical literature:

  1. Suguna et al., "STM32-Based Adaptive BMS," JETIR, Apr 2026. Defines the baseline performance case for transitioning low-cost BMS designs from simple Arduino architectures to 32-bit ARM microcontrollers.
  2. Ungurean, "Integrating Fieldbus and Data-Centric Middleware: An STM32 Modbus Master Gateway for DDS-Based IIoT Systems," MDPI Technologies 13(11):526, Nov 2025. Acts as the closest relative benchmarking latency and packet rates for STM32 fieldbus gateways.
  3. Pham et al., "Battery Management System for Unmanned Electric Vehicles with CAN BUS and Internet of Things," MDPI Vehicles 4(3):37, Jun 2022. Precedent for a distributed CAN + IoT telemetry architecture in unmanned electric vehicles.
  4. "Hybrid SoC Estimation Using Coulomb Counting + Adaptive Unscented Kalman Filter," MDPI Energies 16(14):5558, 2023. Provides the theoretical grounding for the Coulomb-counting drift and calibration limits.

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

STM32F103 battery management system with FreeRTOS, Modbus RTU, CAN, and MQTT telemetry — host-simulated and ARM cross-compiled

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages