Skip to main content
emobility.academy
B.Tech / BEEdge AI & estimationIntermediate About 5 weeksKit only

Statistical Anomaly Detection on Battery Signals (Z-Score and EWMA)

You build a battery monitor on the kit that learns the normal behaviour of the cell's voltage and temperature and flags anomalies using Z-score and EWMA control charts. Alerts appear on the LCD, buzzer and RGB LEDs and are logged to a PC over UART.

Uses: ADC · UART

The problem

Fixed voltage and temperature limits catch faults only after they are severe. Many battery problems, such as a loose connection, a sensor fault or abnormal heating, show up first as unusual changes in otherwise normal readings. Simple statistical detectors can catch these early on a low-cost microcontroller.

Objectives

  • Sample cell voltage and T-sense temperature with the ADC at a fixed rate.
  • Implement rolling Z-score and EWMA detectors in fixed-point C.
  • Inject controlled anomalies using the switchable loads, the relay and the T-sense input.
  • Raise graded alerts locally and log every sample and alert to a PC.
  • Measure detection rate, false alarms and detection delay.

What you need

From the EV Embedded Development Kit

  • STM32F103C8T6 microcontroller unit (Arm Cortex-M3)
  • 1S battery with connector and T-sense input
  • Load section: three switchable resistive loads with LEDs
  • Charge/discharge control relay
  • 16×2 LCD
  • RGB LEDs and a buzzer
  • Serial UART interface

Software

  • STM32CubeIDE
  • Embedded C with HAL drivers
  • Python (pandas, matplotlib) for log analysis
  • A serial terminal

Extra parts

None. Everything this project needs is on the kit.

This project uses the kit's lithium cell. Respect polarity, never short the terminals, and don't leave the cell charging unattended.

Key concepts

Z-score
How many standard deviations a sample is from the rolling mean. A value beyond about 3 is unusual if the data are roughly normal.
EWMA (exponentially weighted moving average)
A running average where each new sample has weight lambda and older samples decay. An EWMA control chart detects small, sustained shifts better than single-sample limits.
Fixed-point arithmetic
Storing fractions as scaled integers, for example millivolts or Q16.16. The STM32F103 has no floating-point unit, so integer maths is much faster.
Estimated current
The kit has no current sensor, so discharge current is estimated as cell voltage divided by the known load resistance. Errors come from resistor tolerance, wiring and relay resistance, typically a few per cent.

Step-by-step guide

  1. 1

    Plan signals and anomaly types

    List what you will monitor: cell voltage, T-sense temperature, and the estimated current from voltage and the active load resistance. Measure each load resistor with a multimeter with the cell disconnected and write down the values. Then list anomalies you can safely create: a sudden voltage drop when loads switch unexpectedly, a slow temperature rise by warming the sensor with a fingertip, a noisy or stuck sensor by disturbing the T-sense connector, and an unexpected relay opening.

    Checkpoint: A table of signals, units, sample rates and at least four anomaly scenarios with how each will be created.

  2. 2

    Configure the board

    Turn on the DIP switches for the battery block, loads, LCD, LEDs, buzzer and UART. In CubeMX set 72 MHz, configure ADC1 in scan mode for the cell-voltage and T-sense channels with DMA into a buffer, triggered by TIM3 at 100 Hz. Configure USART at 115200 baud and the LCD GPIOs. Check the cell polarity before connecting it and never short the battery terminals. Do not leave the cell charging unattended.

    Checkpoint: Raw ADC values for both channels stream to the PC at 100 Hz and change when you switch a load.

  3. 3

    Convert to engineering units

    Calibrate the voltage channel against a multimeter at two points and store gain and offset in integer form, giving millivolts. Convert the T-sense reading to temperature using the sensor's characteristic from the kit documentation, with a lookup table if it is non-linear. Average blocks of ten samples to get a 10 Hz signal with less noise. Compute estimated current in milliamps from voltage and the switched-in load resistances.

    Checkpoint: Displayed voltage agrees with the multimeter within 20 mV and temperature agrees with a reference thermometer within 2 °C.

  4. 4

    Collect normal baseline data

    Record at least an hour of normal operation over UART: idle, each load on, loads switched in sequence, and a supervised charging period. Load the CSV into pandas and plot each signal. Look at noise level, typical step sizes when loads change and how fast temperature moves. These numbers set the detector parameters and tell you which changes are normal and must not raise alarms.

    Checkpoint: Baseline plots and a table of mean, standard deviation and maximum rate of change per signal and operating state.

  5. 5

    Implement the rolling Z-score detector

    Keep a circular buffer of the last N samples (for example 64) and update the running sum and sum of squares incrementally so each update costs a few integer operations. Compute the mean and variance in fixed point and flag a sample whose deviation exceeds k standard deviations, with k around 3 to 4. Use an integer square root or compare squared values to avoid floating point. Reset or hold the statistics when a known event, such as a commanded load change, occurs.

    Checkpoint: The detector runs at 10 Hz with execution time measured below 50 µs and raises no alarms on the baseline log replayed through it.

  6. 6

    Implement the EWMA control chart

    Update z = z + lambda × (x − z) with lambda as a power-of-two fraction such as 1/8, so the multiply becomes a shift. Set control limits from the baseline standard deviation using the EWMA limit formula with L around 3. The EWMA catches slow drifts like gradual heating that the Z-score misses. Run it separately on temperature and on the rate of change of voltage.

    Checkpoint: A slow temperature rise of about 1 °C per minute is flagged by EWMA before the Z-score detector reacts.

  7. 7

    Build alerts and the display

    Define three alert levels: notice (green to amber LED), warning (amber LED and a short beep) and critical (red LED, continuous beep, and optionally opening the charge/discharge relay). Show voltage, temperature and alert state on the 16×2 LCD. Send every sample and every alert with its detector name and score over UART as CSV. Add a keypad or button acknowledgement so a warning can be cleared.

    Checkpoint: Each alert level can be triggered and acknowledged and appears correctly on the LCD, LEDs, buzzer and log.

  8. 8

    Inject anomalies and test

    Run each planned anomaly at least ten times, noting the exact time you start it. Include confusing normal events too, such as planned load switching, to measure false alarms. Keep all logs. Make sure the cell never goes below its safe discharge voltage during tests; stop discharge tests at the cut-off given in the kit documentation. Mark each event start with a keypad press so the label is written into the same log as the samples.

    Checkpoint: A labelled dataset with ground-truth anomaly start times for at least 40 events.

  9. 9

    Evaluate and tune

    In Python, compute for each detector the detection rate, false alarm rate per hour and average detection delay. Vary k, N and lambda and plot the trade-off between delay and false alarms. Pick final parameters and justify them. Compare with a simple fixed-threshold detector as the baseline, which shows the value of the statistical methods. Keep a separate test log that you never use for tuning, so the final figures are not optimistic.

    Checkpoint: A results table and trade-off plot showing the chosen parameters and the comparison with fixed thresholds.

  10. 10

    Document the project

    Write the report: signal chain and calibration, detector maths and fixed-point implementation, test method, results and limits. Explain that current is estimated, not measured, and what error that adds. Include the timing measurements and memory use from the build output. Add a block diagram of the firmware, a table of detector parameters with their justification, and photographs of the LCD in each alert state. Finish with a short section on what a production BMS would add.

    Checkpoint: A report and demo where an examiner can trigger an anomaly and see it detected and logged.

Testing & validation

  • Voltage calibration within 20 mV of a multimeter across the cell's range.
  • No false alarms on at least one hour of replayed normal data with final parameters.
  • Every injected anomaly class detected, with average delay reported.
  • Detector execution time and RAM use measured and reported.

Expected results

A working on-device anomaly detector that flags abnormal battery behaviour earlier than fixed limits, with logged evidence of detection rates, false alarms and delays for each method.

Take it further

  • Add CUSUM as a third detector and compare.
  • Send alerts over CAN to a dashboard node.
  • Log alerts with timestamps from the RTC to SPI flash.
  • Add an INA219 current monitor and compare detection with measured instead of estimated current.

Viva and review questions

Why use EWMA as well as Z-score?

Z-score reacts to single large deviations but misses small, slow drifts. EWMA accumulates evidence over time, so it detects gradual changes like slow heating earlier.

How do you compute standard deviation without floating point?

We keep integer running sums of x and x squared over the window, compute variance in fixed point and compare squared deviation with k squared times variance, so no square root is needed.

How do you know current without a current sensor?

We estimate it as measured cell voltage divided by the known resistance of the switched-in loads. Resistor tolerance and contact resistance make it an estimate within a few per cent.

Related EV projects

All 100 EV projects