Skip to content

First Data Stream

After flashing both MCUs and connecting the UART bridge, verify the full pipeline: sensors → MCU → packet → PC.

1. Hardware checklist

  • [ ] STM32F405 flashed and USB-C connected to PC
  • [ ] KB2040 flashed and powered (USB-C or via STM32 3.3 V)
  • [ ] UART bridge wired: PC6 → GP5, PC7 ← GP4, GND common
  • [ ] At least one BNO055 connected to each bus pair (optional — zero works, but data is zeros)
  • [ ] LED_BUILTIN on on both boards (indicates setup() completed)

2. Serial monitor check

Open a terminal on the STM32 serial port:

cd firmware/stm32f405
pio device monitor -b 115200

Expected output when KB2040 is connected and all sensors present:

STM32F405: init
[IMU] 0:ok 1:ok 2:ok 3:ok
[ADC] EMG 2ch, FSR 4ch
[UART] KB2040 data
seq=0  seq=1  seq=2  ...

  • [IMU] N:fail → that BNO055 is not detected. Check I2C wiring on the corresponding bus (see Wiring).
  • [UART] no data → KB2040 not transmitting. Check UART wiring, KB2040 power, KB2040 LED → both I2C0 ok, I2C1 ok.
  • seq=N increments by 1 each line → main loop running at ~100 Hz.

3. Host data stream

Stop the PlatformIO monitor (Ctrl+C) so the serial port is free, then:

cd wearable_har_v2
.venv/bin/python -m host.serial_reader

This opens /dev/ttyACM0 (adjust with --port if needed), syncs on the 0xAA 0x55 magic bytes, validates CRC32, and prints one line per frame:

seq=0 ts=12345 imus=6 emg=2 fsr=4 crc=ok
seq=1 ts=22346 imus=6 emg=2 fsr=4 crc=ok
seq=2 ts=32347 imus=6 emg=2 fsr=4 crc=ok

crc=ok means the CRC32 checksum matched. If you see crc=FAIL, the UART bridge has bit errors — check wiring and reduce cable length.

4. Dump raw frames

For debugging, use the --hex flag to dump the raw packet bytes:

.venv/bin/python -m host.serial_reader --hex

Output:

AA 55 00 00 00 00 39 30 00 00 ...

Compare against the binary protocol reference.

5. Verify with feature extraction

from host.serial_reader import SerialReader
from host.feature_extraction import FeatureExtractor

extractor = FeatureExtractor()
with SerialReader("/dev/ttyACM0") as reader:
    for frame in reader:
        feats = extractor.add_frame(frame)
        if feats is not None:
            print(f"window: {feats.shape[0]} dims, nonzero={(feats != 0).sum()}")
            break

Expected: window: 328 dims, nonzero=... (nonzero count depends on how many sensors are connected — all zeros means no sensors are producing data).

Troubleshooting

Symptom Check
No /dev/ttyACM0 STM32 USB-C is charge-only cable? Try another cable
Permission denied sudo chmod 666 /dev/ttyACM0 or add user to dialout group
No frames (just hangs) Magic sync not found — is the STM32 actually streaming? Check monitor
Frames but all zeros IMUs may be disconnected/failed; check [IMU] N:fail on monitor
crc=FAIL on most frames UART bridge noise — check GND connection, shorten wires