HomeEngineering Projects For YouSmart EV Battery Companion: Touchscreen HMI for Real-Time Battery Intelligence and Charging...

Smart EV Battery Companion: Touchscreen HMI for Real-Time Battery Intelligence and Charging Navigation for Budget Electric Vehicles

Impressed by this project? Give it your People’s Choice vote.
6 votes

Project Demo Video:


Component List

IDNameDesignatorQuantity
1M5Stack CoreS3-SE (ESP32-S3, 2″ 320×240 touch, speaker, mic, Wi-Fi, RTC)MOD11
2ADS1115 16-bit 4-channel I²C ADCU11
3ACS723 low-current Hall current sensor (±5 A, isolated)U21
4Resistor 4.7 kΩ 1% (pack-divider top leg)R11
5Resistor 1 kΩ 1% (pack-divider bottom leg)R21
6Resistor 10 kΩ 1% (NTC divider fixed leg)R71
7Capacitor 100 nF 50 V (ADC anti-alias)C11
8NTC thermistor 10 kΩ B3950 (pack temperature)RT11
9NEO-6M GPS module (UART)GPS11
102 A slow-blow fuse + holder (load-path protection)F11
113S Li-ion bench pack, 12.6 V max, protectedBAT11
1212 V 21 W incandescent lamp (calibration/demo load)LOAD11
13USB power bank (independent power for the CoreS3-SE)PWR11
14Grove/JST cabling, perfboard, wire, enclosure——

The purchasable bill of materials — with manufacturer and DigiKey part numbers, quantities, live prices, purpose, and schematic references — is in the public DigiKey MyList: Digikey link (as-built).

The sensors run directly from the CoreS3-SE’s own regulated 3.3 V header rail, so no LDO regulator is needed — a deliberately simpler, honest design.

Project Explanation Step By Step:

Budget EV riders in India get almost no trustworthy information from their vehicle: a coarse fuel-gauge-style bar, no temperature insight, no honest range, and no idea whether the next charger is actually reachable. The Smart EV Battery Companion is a small, independently powered touchscreen device that reads real electrical signals from a battery on a safe low-voltage bench rig, runs a validated state-of-charge estimator on-device, and — over Wi-Fi — finds nearby charging stations, routes to them, and ranks them by whether they are reachable on the energy you have left.

- Advertisement -

Crucially, every value on screen is labelled by where it came from (live sensor, laboratory-dataset replay, or estimate), so the device never overstates what it knows. The IoT element (live charger discovery + routing + offline cache) is central to the rider’s decision, not a bolt-on.

What makes it different from “just another battery dashboard”

  • Confidence-aware SoC, not a fake number — the OCV-corrected extended Kalman filter reports a LEARNING → READY → DERATED state with confidence, and openly derates when cold.
  • Reachability, not just a charger list — stations are ranked reachable / marginal / out-of-range using a conservative range plus a reserve margin.
  • Honesty as a design rule — live, replayed, and estimated values are visibly distinguished by a source badge (LIVE BENCH vs SIMULATED); no cell-balance claims, no invented replacement date, no “works on every EV” claim.
  • Validated with published lab data — the estimator was validated against the CALCE INR18650-20R dataset with a held-out split; error is reported with its temperature limitation stated openly.

The five screens

  • Dashboard: SoC arc with estimator state + confidence, conservative and nominal range, live pack voltage / current / temperature, charge/discharge indicator, and a persistent source badge.
  • Health: data-quality gauge, live pack-voltage trend, per-cell average voltage, and an honest “SoH: needs a full cycle to measure” status (no fabricated health percentage).
  • Charging (IoT): nearby chargers from Open Charge Map ranked by reachability, turn-by-turn route distance/time with an on-device route map, GPS status, and ONLINE/CACHED/OFFLINE data-source labelling.
  • Session / Energy: live energy discharged/charged (Wh), peak power, a real-time power (W) trend, and session time— all integrated from measured pack V × I.
  • Settings: theme (dark / light / auto-by-time), brightness, power-saver, Wi-Fi, data logging, current zero-calibration, and a clearly separated demo simulation mode.

Hardware Design and Sensing

The device measures three real quantities from the bench pack:

- Advertisement -
  • Voltage: a resistor divider (4.7 kΩ / 1 kΩ) scales the pack voltage into the ADS1115’s input range on channel A0. Calibrated in firmware against a multimeter (meter 11.32 V ≈ display 11.3 V); the divider-ratio constant (5.553) absorbs resistor tolerance, so precision parts are unnecessary.
  • Current: an isolated ACS723 Hall sensor in the pack’s high side, on channel A3. Zero-offset is nulled at startup with the load off; sensitivity was calibrated against a series multimeter with a 21 W lamp (meter 1.61 A). Positive = charging, negative = discharging.
  • Temperature: a 10 kΩ B3950 NTC on a divider into the ESP32-S3 ADC, converted with the beta equation; the firmware refuses to read an unconnected sensor so a missing NTC honestly shows “–“.

Why the sensors run at 3.3 V: the ADS1115 and ACS723 are powered from the CoreS3-SE’s regulated 3.3 V header pin so their I²C levels match the ESP32-S3 natively — no level shifter and no LDO needed. Sensor I²C runs on a dedicated FreeRTOS task (core 0) so the touchscreen (core 1) never stalls.

Battery Intelligence: Algorithms and Validation

The SoC estimator was validated before any on-hardware work, in Python, against the CALCE INR18650-20R (NMC) dataset. Parameters were tuned on 25 °C DST only; all other runs (including 0 °C and 45 °C) are held out.

EstimatorHeld-outMAE(pp)Worst(pp)
Voltage-only OCV lookup12.7573.88
Coulomb counting (ideal init)0.702.15
Coulomb counting (+10 pp init error)10.6912.15
OCV-corrected EKF (1st-order RC)2.0815.49

EKF by temperature: 0.38 pp @ 25 °C, 0.96 pp @ 45 °C, 8.27 pp @ 0 °C.

The device runs the same algorithm on-device, configured for the live 3S bench pack. SoC uses coulomb counting under load (immune to voltage sag) anchored to rest-gated, IR-compensated OCV correction — the approach a production fuel gauge uses, so the reading does not bounce when a load is removed.

Stated limitation: SoC accuracy is temperature-dependent (±3% at 25 °C, worse when cold), which is why the UI exposes a confidence / DERATED state rather than a single number pretending to be exact.

IoT: Charging Discovery, Routing, and Offline Resilience

The IoT layer runs on a separate FreeRTOS task (no HTTP/TLS on the UI thread):

  • Live charger discovery from Open Charge Map over verified TLS.
  • Turn-by-turn routing from openrouteservice (distance, duration, steps, and a decoded route polyline drawn on-device); rows label Air vs Road.
  • Reachability ranking from the conservative range + reserve margin.
  • Offline cache in NVS with ONLINE/CACHED/OFFLINE labels and data age (a Wi-Fi-loss test confirmed labelled fallback to cached data).
  • GPS via NEO-6M with truthful GPS FIX / LAST FIX / CONFIGURED states, and it also sets the RTC clock from GPS UTC.

Coding Explanation and Configuration

The firmware is built with PlatformIO + Arduino + M5Unified + LVGL 9.5 for the M5Stack CoreS3-SE — not the Arduino IDE — because PlatformIO pins exact library versions for reproducibility.

Build and flash:

cd cores3_firmware

pio run # build

pio run –target upload –upload-port /dev/ttyACM0 # flash

Key libraries (pinned in platformio.ini): M5GFX 0.2.28, M5Unified 0.2.21, lvgl 9.5.0, ArduinoJson 7.4.3, TinyGPSPlus 1.1.0.

Module map:

PathPurpose
src/platform/ev_sensors.cppADS1115 + ACS723 + NTC sampling on a background task
src/model/ev_live_source.cSensor reading → battery state; SoC (coulomb + rest-gated OCV)
src/model/ev_estimator.cOn-device OCV-corrected EKF (pack-configurable)
src/ui/Five LVGL screens, nav, alert banner, runtime theme
src/service/Open Charge Map + openrouteservice clients (verified TLS)
src/platform/ev_time.*, ev_power.*RTC (GPS-synced) and AXP2101 power management
analysis/Python estimator validation (reproducible)

The whole system is built around one shared application-state pipeline with three interchangeable sources — live bench, dataset replay, and deterministic fault test — so the UI, alerts, logger, and IoT services all read one coherent model.

Blocking work (I²C, Wi-Fi/TLS) is isolated on core 0; the LVGL UI on core 1 only reads snapshots, which keeps the touchscreen responsive. Last build footprint: RAM 49.6%, flash 24.1%.

Coderepository: click here

Connection Explanation

The bench rig is wired for safety and measurement accuracy:

  • Voltage sense: pack + → R1 (4.7 kΩ) → node → R2 (1 kΩ) → pack −; the node goes to ADS1115 A0 with a 100 nF anti-alias cap. Powered from the pack’s balance/main leads at low voltage only.
  • Current sense (load path): PACK+ → ACS723 IP+ → IP− → 2 A fuse → 12 V lamp → PACK−. The ACS723 is galvanically isolated and sits in the high side; its VOUT goes to ADS1115 A3. Thick wire is soldered directly to IP+/IP− so the ~1.6 A load current never passes through the breadboard.
  • Temperature: 3.3 V → 10 kΩ → node (→ CoreS3 GPIO8) → NTC → GND.
  • Power/I²C: ADS1115 and ACS723 run from the CoreS3-SE 3.3 V header pin; I²C SDA/SCL on Grove Port A (G2/G1). PACK− is tied to the common ground — essential for a stable voltage reading.
  • The CoreS3-SE is powered independently by a USB power bank, never by the pack under test. KiCad schematic: hardware/ev_sensing/.

Testing

QuantityResult
VoltageMultimeter 11.32 V vs display 11.3 V — matches after firmware calibration; stable once PACK− grounded
Current0.0 A; 1.6 A under the 21 W lamp, matching a series multimeter (1.61 A)
Temperature~27 °C ambient; rises with a warm hand, falls on a cold object; rejects an unconnected sensor
SoC under loadDrops correctly while discharging; no bounce-back when the load is removed (rest-gated OCV)
EstimatorHeld-out CALCE validation (table above), 12 per-run plots
IoTLive Bengaluru charger fetch + routing; Wi-Fi-loss test shows labelled CACHED fallback
StabilitySplash-freeze and touch-break root-caused and fixed; runs without reset

Real-World Application and Production Path

  • A retrofit companion for budget EVs — independently powered, non-invasive.
  • Compatibility is presented as a bounded matrix, not “any EV”.
  • A production version would add automotive-grade isolation, surge/load-dump protection, rated connectors/fusing, a wide-input automotive DC/DC, and a shunt-based current front-end (INA226) for finer resolution. A gated OTA path (versioned battery profiles; optional signed dual-slot firmware) reuses the developer’s professional ECU/BMS OTA experience.

Limitations (stated plainly)

  • SoC accuracy is temperature-dependent (±3% at 25 °C; ~8 pp at 0 °C) — shown as a confidence / DERATED state.
  • The ±5 A current sensor is coarse below ~0.3 A; a demo uses a ~1.6 A load, and a shunt sensor is documented as the production upgrade.
  • No cell-balance claim — the bench pack has protection, not active balancing.
  • No verified replacement-date prediction from short observation.
  • Estimator evidence is from a published single-cell NMC dataset, not a measurement of a full EV pack.

Schematics

Code

Firmware: cores3_firmware/ (PlatformIO).

Estimator validation: analysis/.

Hardware design + schematic : hardware/.

Laboratory data courtesy of the Center for Advanced Life Cycle Engineering (CALCE), University of Maryland. Citation: Zheng, Xing, Jiang, Sun, Kim, Pecht, “Influence of different open circuit voltage tests on state of charge online estimation for lithium-ion batteries,” Applied Energy 183, pp. 513–525, 2016.


SHARE YOUR THOUGHTS & COMMENTS