- name
- hardware
- description
- Hardware reference — BOM, ESP32-C3 pinout, BNO085 wiring, power, enclosure, mounting. TRIGGER when the user asks about wiring, pins, which connector, what board to buy, enclosure, physical install, or "can I use pin X for Y". DO NOT trigger for calibration math (use /calibrate) or firmware build issues (use /flash).
# Hardware reference
The single source of truth for what's in the box and how it's wired.
Mirrors `docs/hardware.md` and `docs/wiring.md`; keep them in sync.
## Bill of materials
| Part | Notes |
|---|---|
| **Seeed XIAO ESP32-C3** | Tiny, USB-C, cheap, has LiPo charger. Alternative: ESP32-C3-DevKitM-1 |
| **Adafruit BNO085 breakout** (PID 4754) | Qwiic/STEMMA-QT + headers, 3.3 V, I²C addr 0x4A (default) or 0x4B |
| 4-wire Qwiic/STEMMA-QT cable | JST-SH, saves soldering |
| USB-C cable (short, marine-grade if routed outside) | |
| Enclosure (TBD) | IP65+, non-ferrous, no lid over the antenna |
| 3M VHB or M3 fasteners | For a rigid mount — not zip ties, not velcro |
Draft — finalize after first prototype.
## ESP32-C3 pinout (XIAO variant)
| XIAO pin | GPIO | Used for | Notes |
|---|---|---|---|
| D4 | GPIO6 | I²C SDA | default for Arduino-ESP32 on C3-XIAO |
| D5 | GPIO7 | I²C SCL | |
| D1 | GPIO3 | BNO085 INT (optional) | data-ready interrupt, reduces I²C polling |
| D0 | GPIO2 | BNO085 RST (optional) | hard reset on wedge |
| 3V3 | — | BNO085 VIN | do not wire 5 V even if the breakout has a regulator |
| GND | — | BNO085 GND | |
**On DevKitM-1** the same functions map differently — check the silkscreen.
I²C bus numbers and pins are config, not constants; `lib/config/` loads them
from NVS. Don't hardcode `Wire.begin(SDA, SCL)` anywhere but `lib/imu/`.
## I²C wiring
```
ESP32-C3 BNO085
3V3 ──────────────── VIN
GND ──────────────── GND
SDA (D4/GPIO6) ───── SDA
SCL (D5/GPIO7) ───── SCL
GPIO3 ─────────────── INT (optional, pull-up on BNO side)
GPIO2 ─────────────── RST (optional, active-low)
```
- I²C pull-ups: the Adafruit breakout has 10 kΩ on SDA/SCL. Do not add more
- Bus speed: 400 kHz (`Wire.setClock(400000)`). The BNO085 handles 1 MHz,
but 400 kHz leaves headroom for cable length in the boat environment
- Cable length: keep I²C under 30 cm. For longer runs, put the sensor and
ESP32 in the same enclosure and run USB (data) / wifi (no data) to it
## Power
- USB-C from a 5 V source (helmlog Pi USB port, a DC-DC from the boat's
12 V, or a small LiPo on the XIAO's onboard charger)
- **Power draw**: ~80 mA continuous at 100 Hz sampling + active wifi.
LiPo sizing if ever needed: 1000 mAh = ~12 h runtime
- **Brown-out**: the ESP32-C3 brown-out detector is enabled by default.
If the device resets mid-race on heavy wifi transmit, the USB source is
sagging — use a better cable / closer source, don't disable the BOD
## Mounting
The sensor should be:
1. **Rigidly bolted** to structure, as close to the boat's pitch/roll
center as practical. Near the mast step is ideal; a cabin bulkhead
is acceptable; a stanchion base is **not** (flex = noise)
2. **Not near a compass** (Raymarine/B&G fluxgate) — the ESP32 wifi
radio can disturb nearby compasses. Minimum 1 m
3. **Not inside a Faraday cage** — keep the wifi antenna end of the
XIAO exposed. No metal enclosure lid above the antenna
4. **Orientation is arbitrary** — we handle it via `mount_quat`. Mount
it however the wiring wants; just *don't move it* after calibrating
## Test / debug harness
For bench development without the boat:
- A foam-core L-bracket that holds the device and a laser pointer
mounted in a known orientation — lets you rotate through known
angles and verify quaternion output
- `scripts/fake_device.py` runs on Mac and posts synthetic batches
to the helmlog dev instance without any hardware, for server-side
development
- `scripts/replay_capture.py` takes a saved LittleFS ring buffer
dump and replays it to the endpoint at real time or 10×, for
reproducing analysis bugs from known data
## Known gotchas
- **Two BNO085s on the same bus** — avoid. The breakout can be jumpered
to 0x4B but the sh2 library is not designed for multi-instance use
- **USB to a Pi** can cause ground loops if the Pi and the device share
power via other paths (e.g., both grounded to the same 12 V rail).
Symptom: garbled I²C, random resets. Fix: USB isolator or powered hub
- **STEMMA-QT cable polarity** — Qwiic/STEMMA-QT is polarized and you can't
insert it wrong, but JST-SH to loose headers IS reversible. Check 3V3
and GND before first power-on; reversed polarity kills the BNO085
- **C3 wifi and BNO085 on the same board** — no known interference, but
keep the BNO085 > 2 cm from the ESP32-C3 antenna just in case
عرض على GitHub