STM32 Step Counter – Real-Time Embedded Wearable System

STM32C071 (Arm Cortex-M0+) · Bare-metal C · SPI / I²C / DMA / PWM

STM32 step counter

Summary

Designed and implemented a real-time step counting system on an STM32C071 (Arm Cortex-M0+) microcontroller in C. The system reads motion data from an LSM6DS accelerometer over SPI, filters the signal, detects steps using a peak–valley finite state machine, and provides real-time user feedback via an OLED display, RGB LEDs, and a PWM-driven buzzer.

The firmware runs on a bare-metal cooperative scheduler (no RTOS) and uses DMA for both ADC and I²C transfers to maintain responsiveness. Step detection operates at 50 Hz and was tuned using live serial plotting. The final system reliably counts pedestrian steps, tracks distance, and provides a hardware-level goal alert.

System Overview

The device tracks step count, estimated distance (1 m per step), and progress toward a user-defined daily goal (500–15,000 steps, set via potentiometer and snapped to 500-step increments). User feedback is provided through three OLED screens (Steps, Distance, Goal Progress), progressive RGB LEDs at 25/50/75/100% of goal, and a 5-second PWM buzzer alert on goal completion.

Core hardware: STM32C071RBT6 at 12 MHz HSI, LSM6DS IMU via SPI2 (6 Mbit/s, 16-bit transfers), SSD1306 OLED via I²C1 + DMA, ADC1 + DMA for joystick and potentiometer, TIM16 PWM for buzzer (~250 Hz), TIM2 PWM for variable LED brightness. All peripheral configuration was generated in CubeMX and refined manually.

Step Detection Algorithm

Signal conditioning: All three axes (X, Y, Z) are read at 50 Hz. A 20-sample circular-buffer moving average is applied per axis (window sizes of 1, 3, and 30 were tested; 20 gave the best noise–responsiveness balance). Magnitude-squared is computed as mag² = x² + y² + z², scaled by 1,000,000 before threshold comparison.

Detection logic: A two-state FSM (WAITING_FOR_PEAK → WAITING_FOR_VALLEY) uses an upper threshold of 300 and lower threshold of 260. Crossing above 300 arms the system; crossing below 260 increments the step count. The 40-unit hysteresis gap prevents double-counting within a single stride. The FSM itself acts as the debounce — no explicit refractory timer is needed. Thresholds were tuned empirically using live serial plotting in VS Code.

Real-Time Architecture

A cooperative scheduler runs inside a superloop using HAL_GetTick() (1 kHz SysTick timebase). Task frequencies: 50 Hz for button + IMU read + filter + step detection; 4 Hz for display, LED, and joystick updates; 2 Hz for status blink. DMA is used for ADC multi-channel scanning (pot + joystick X/Y) and I²C OLED transmission, preventing blocking during screen refresh and analog sampling.

The project follows a layered module structure: drivers/ for register-level peripheral drivers, middleware/ for filtering and step detection, tasks/ for application behaviours, and app/ for orchestration. Hardware abstraction is isolated from application logic. The system runs within a 512-byte heap and 1 KB stack on on-chip SRAM only.

Calibration & Validation

Signal tuning was performed using USART2 debug output with real-time accelerometer X/Y/Z streams, filtered magnitude output, and threshold overlays. Validation features built into firmware include a double-tap test mode (≤700 ms window), joystick-controlled artificial step increments, a manual +80 step debug button, and goal-alert verification via rapid step injection.

Artifacts

Full firmware project (.zip)

Key Skills & Tools

Embedded Systems

  • STM32C071 (Cortex-M0+) bare-metal C
  • SPI IMU integration (LSM6DS)
  • I²C OLED with DMA (SSD1306)
  • ADC multi-channel scan with DMA
  • PWM generation (TIM2, TIM16)
  • CubeMX peripheral configuration

Signal Processing

  • Moving-average filtering (circular buffer)
  • 3D magnitude-based motion detection
  • Peak–valley FSM step detection
  • Hysteresis tuning and empirical calibration
  • Live serial plotting for validation

Firmware Architecture

  • Cooperative scheduler (no RTOS)
  • Non-blocking superloop design
  • Modular C project structure
  • Hardware abstraction layers
  • Real-time UART debugging

← See All Projects