Skip to content

MCU Layout

STM32F405 Feather Express

Primary MCU. 168 MHz ARM Cortex-M4, STM32duino framework.

Resource Pins Function
I2C1 PB7 (SDA), PB6 (SCL) BNO055 #0, #1 (wrists)
I2C2 PB11 (SDA), PB10 (SCL) BNO055 #2, #3 (arms)
USART6 PC7 (RX), PC6 (TX) KB2040 bridge (921600 baud)
USB CDC USB-C Data stream to PC (214-byte frames)
ADC A0–A5 2× MyoWare + 4× FSR (12-bit, 4× oversampled)
LED LED_BUILTIN On after setup() completes

The I2C1 and I2C2 buses each carry two BNO055s at 0x28/0x29 (ADR pin selects address).


KB2040 (RP2040)

I²C co-processor. 133 MHz ARM Cortex-M0+, Arduino-Pico framework.

Resource Pins Function
I2C0 GP12 (SDA), GP13 (SCL) BNO055 #4 (chest)
I2C1 GP2 (SDA), GP3 (SCL) BNO055 #5 (thigh)
Serial1 (UART1) GP4 (TX), GP5 (RX) STM32 bridge (921600 baud)
LED LED_BUILTIN On after setup() completes

Both IMUs at address 0x28 (ADR=GND) on separate buses.


Cross-MCU UART bridge

STM32F405                     KB2040
┌──────────────┐  921600 baud  ┌──────────┐
│ USART6  PC6 ─────────────────▶ GP5  RX  │
│          PC7 ◀───────────────── GP4  TX  │
│          GND ────────────────── GND      │
└──────────────┘               └──────────┘

Critical timing note

The put_f32 helper in the KB2040 firmware writes floats byte-by-byte to avoid unaligned-word faults on the Cortex-M0+. The v1 code used memcpy — fine on Cortex-M4 but a hard fault on M0+.


I2C bus map (all IMUs)

                    STM32F405 (4 IMUs)
  I2C1 (PB7/PB6) ──┤ 0x28 = L wrist  │
                    │ 0x29 = R wrist  │
  I2C2 (PB11/PB10) ┤ 0x28 = L arm    │
                    │ 0x29 = R arm    │
                    └─────────────────┘

                    KB2040 (2 IMUs)
  I2C0 (GP12/GP13) ┤ 0x28 = chest
  I2C1 (GP2/GP3) ──┤ 0x28 = thigh
                    └─────────────────┘