Skip to content

System Architecture

The wearable is a distributed sensor network with two MCUs and a host PC.

System overview

Data flow

Sensors ──▶ STM32F405 ──▶ USB CDC ──▶ PC Host
                ▲
                │ UART 921600
                │
Sensors ──▶ KB2040
  1. Sensors — 6 BNO055 IMUs (quaternion + linear acceleration at 100 Hz), 2 MyoWare EMG envelopes, 4 FSR force sensors, plus Intel RealSense D435i (RGB-D, on a separate USB 3.0 bus for ground truth).

  2. KB2040 (RP2040) — reads 2 IMUs (chest, thigh) over I2C0/I2C1, packs a 70-byte frame, and sends it to the STM32 over UART at 921600 baud every 10 ms (100 Hz).

  3. STM32F405 — reads 4 IMUs (wrists, upper arms) over I2C1/I2C2, reads 6 ADC channels (EMG + FSR) with 4× oversampling, receives the KB2040 UART frame, assembles the 214-byte unified packet, and streams it to the PC over USB CDC.

  4. PC Host — Python 3.12 pipeline:

  5. serial_reader — magic sync, CRC validation, frame parsing
  6. FeatureExtractor — 2 s sliding window / 0.5 s stride → 328-dim feature vector
  7. LiveClassifier — TorchScript BiLSTM-CNN with EMA smoothing → activity label
  8. dashboard — Streamlit UI with stick figure, EMG/FSR displays, timeline

Why two MCUs

The STM32F405 has 2 I²C buses × 2 addresses (0x28/0x29) = 4 slots. 6 IMUs need 4 buses. The KB2040 adds 2 more I²C buses without a multiplexer.

See MCU Layout for the full bus assignment.

Timing budget

Component Duration
BNO055 read (×6 IMUs) ~2.4 ms total
ADC read (×6 ch, 4× oversample) ~0.3 ms
UART receive (70 bytes) ~0.8 ms @ 921600
Packet assembly + CRC32 ~0.2 ms
USB CDC TX (214 bytes) ~0.5 ms
Total per frame ~4.2 ms
Frame interval 10 ms (100 Hz)

Headroom: ~5.8 ms per cycle. The USB CDC TX drops a frame and continues if the host isn't draining, preventing the 100 Hz loop from backing up.