Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AccelSense - Motion Classification on STM32 with TinyML

A hands-on TinyML project. Deployed a neural network on an STM32 Nucleo-L476RG that classifies motion (idle, moving, shaking, tapping) from a live accelerometer feed at 100 Hz.

Built this to get past the theory and actually feel what deploying AI on embedded hardware is like. Wanted real experience with the full pipeline, from wiring up a sensor to running inference on the chip.

Demo

demo.mp4

Hardware

Component Role
STM32 Nucleo-L476RG ARM Cortex-M4, 80 MHz, 128 KB RAM, 1 MB flash
MPU6050 (GY-521) 3-axis accelerometer over I2C

Wiring

MPU6050 Nucleo
VCC 3.3V
GND GND
SDA PB9 (D14, I2C1_SDA)
SCL PB8 (D15, I2C1_SCL)

Setup Development setup: Nucleo-L476RG with MPU6050 secured via tape (no breadboard needed for a 4-wire I2C connection)

Software

  • STM32CubeIDE for building, flashing, debugging
  • STM32CubeMX for peripheral config (I2C1, USART2)
  • STM32 HAL, bare-metal, no RTOS
  • Peripheral setup in C (HAL), converted to C++ (required by the Edge Impulse SDK)
  • Edge Impulse for data collection, training, and model export
  • CMSIS-PACK to integrate the model into the STM32 project

Note: Claude was used as a coding assistant throughout the project.

Model

  • Input: 1000ms window of 3-axis accelerometer data at 100 Hz (300 samples)
  • DSP: spectral features (63 features)
  • Classifier: small dense NN (20 → 10 → 4), float32
  • Classes: idle, moving, shaking, tapping
  • Training accuracy: 99.5%
  • Test accuracy: 91.26%
  • Memory: 1.7 KB RAM, ~16.6 KB flash for the model
  • Inference: 5 ms (4 ms DSP, 1 ms classifier)

View the model, data, and training on Edge Impulse

Process

  1. Wired up the MPU6050, got I2C talking, read WHO_AM_I to confirm the sensor was alive, then streamed raw accel over UART
  2. Collected labeled motion samples across a few orientations using the Edge Impulse Data Forwarder
  3. Trained the model in Edge Impulse Studio
  4. Exported as a CMSIS-PACK, dropped it into the STM32 project
  5. Wrote the inference loop: fill a 500ms window, run the classifier, print the class only when it changes

What I Learned

  • AI is unstable, needs a lot of data, and never actually hits 100%. If it does, something's wrong (usually the test set is too easy or the model is overfitting).
  • The exact same setup has to be used for training and deployment. Sample rate, sensor orientation, window size, all of it. Mismatch and predictions becomes insanely wrong.
  • On a chip with 128 KB of RAM, every design choice is a trade-off. Bigger window means better accuracy but no memory. Smaller window fits, but short events like taps get diluted.
  • Even though the model can't fully replace hand-coded logic, it saved me from having to hand-tune filters and thresholds for every motion type. That's the real value of TinyML and it's easier to simply detect new motion, for example, waves, circular motions etc...

Resources

Repo Structure

  • /AccSense - main STM32 project running the model
  • /AccelSampling - separate firmware used only to stream accel data for training

About

AccelSense - Real-Time Motion Classification on STM32 with TinyML

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages