generated from CubeCraft-Creations/Tracehound
996ef87dfd
Bring up the 1.3" SH1106 128x64 I2C OLED on the XIAO ESP32-C6 (D4/SDA, D5/SCL @ 0x3C) per the Notion wiring diagram. - add U8g2 dependency to the seeed_xiao_esp32c6 env - I2C bus scan at boot (logs responders to serial) - boot splash + live status screen: camera id, IDLE/REC + session timer, battery (raw until calibrated) + video-remaining, hub link state (MQTT/wifi/offline), and camera reachability - refresh runs at the top of loop() so the panel stays live even when WiFi/MQTT are down Verified on hardware: I2C scan finds 0x3C, U8g2 begin ok, panel shows clean readable text. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
RemoteRig — Dual-Board Camera Node Firmware
Platform: PlatformIO (esp8266-camera + esp32-mqtt) MQTT Contract: docs/MQTT_CONTRACT.md Hardware: hardware/README.md
Architecture
Each camera node uses two boards connected via UART — zero network switching:
┌─────────────────────┐ UART ┌─────────────────────┐
│ ESP8266 D1 Mini │ TX──────→RX │ ESP32 Dev Board │
│ (Camera Bridge) │ RX←──────TX │ (MQTT Bridge) │
│ │ 115200 │ │
│ STA → GoPro AP │ 8N1 │ STA → Travel Router │
│ HTTP → 10.5.5.1 │ │ MQTT → 10.60.1.56│
│ Start/stop/status │ │ Hub registration │
└─────────────────────┘ └──────────────────────┘
| Board | Job | Network | Protocol |
|---|---|---|---|
| ESP8266 | Camera control | GoPro AP only (10.5.5.1) | HTTP → UART JSON |
| ESP32 | Hub relay | Travel router only (10.60.1.x) | UART JSON → MQTT |
Quick Start
pip install platformio
cd firmware
# Build both
pio run -e esp8266-camera
pio run -e esp32-mqtt
# Upload to boards (connect one at a time via USB)
pio run -e esp8266-camera --target upload
pio run -e esp32-mqtt --target upload
# Upload configs (each board needs its own)
# ESP8266: copy esp8266-config.json to data/config.json, then:
pio run -e esp8266-camera --target uploadfs
# ESP32: copy esp32-config.json to data/config.json, then:
pio run -e esp32-mqtt --target uploadfs
UART Protocol (ESP8266 ↔ ESP32)
JSON-per-line at 115200 8N1. GPIO16 on both boards.
| Direction | Type | Format | Purpose |
|---|---|---|---|
| ESP8266 → ESP32 | status |
{"type":"status","battery_raw":217,...} |
Camera poll result |
| ESP8266 → ESP32 | ack |
{"type":"ack","cmd":"start_recording"} |
Command confirmation |
| ESP8266 → ESP32 | pong |
{"type":"pong","uptime_ms":12345} |
Ping response |
| ESP8266 → ESP32 | error |
{"type":"error","msg":"camera unreachable"} |
Error report |
| ESP32 → ESP8266 | cmd |
{"type":"cmd","command":"start_recording"} |
Hub command |
| ESP32 → ESP8266 | cmd |
{"type":"cmd","command":"ping"} |
Link health check |
Configuration
ESP8266 (data/esp8266-config.json)
| Key | Default | Description |
|---|---|---|
camera_ssid |
"GOPRO-BP-" |
GoPro Wi-Fi AP name |
camera_password |
"goprohero" |
GoPro Wi-Fi password |
camera_ip |
"10.5.5.1" |
Camera IP (change for Akaso to 192.168.1.1) |
poll_interval_sec |
30 |
How often to poll camera |
ESP32 (data/esp32-config.json)
| Key | Default | Description |
|---|---|---|
wifi_ssid |
"RemoteRig" |
Travel router SSID |
wifi_password |
"" |
Travel router password |
mqtt_broker |
"10.60.1.56" |
Pi Zero 2 W IP |
mqtt_port |
1883 |
Mosquitto port |
camera_id |
"" |
Assigned by hub on first announce (leave empty) |
heartbeat_interval_sec |
60 |
MQTT heartbeat frequency |
Wiring
ESP8266 D1 Mini ESP32 Dev Board
┌────────────┐ ┌────────────┐
│ │ │ │
│ TX (GPIO1)│──────────→│ RX (GPIO16)│
│ RX (GPIO3)│←──────────│ TX (GPIO17)│
│ GND │───────────│ GND │
│ 3.3V │ │ 3.3V │
│ │ │ │
└────────────┘ └────────────┘
│ │
└────────┬─────────────┘
│
LiPo → 3.3V Buck
(shared power)
Boot Sequence
- ESP8266: Connect to GoPro AP → wait for UART commands
- ESP32: Connect to travel router → connect MQTT → announce if new
- ESP8266: Poll camera every 30s → send status over UART
- ESP32: Receive status → publish MQTT
- Hub → MQTT command → ESP32 → UART → ESP8266 → HTTP → GoPro
Camera Compatibility
| Camera | camera_ip |
Protocol | Status |
|---|---|---|---|
| GoPro Hero 3 | 10.5.5.1 |
HTTP GET /bacpac/SH |
✅ Full support |
| Akaso Brave 7 | 192.168.1.1 |
Varies | 🔬 Set camera_ip, test |
For non-GoPro cameras: only the ESP8266 firmware needs changes — the ESP32 stays the same.
LED Status (ESP8266)
| LED | Meaning |
|---|---|
| Solid on | Connected to camera AP, camera responding |
| Slow blink (500ms) | Connected to AP but camera not responding |
| Off | Wi-Fi disconnected |
Troubleshooting
| Symptom | Check |
|---|---|
| No UART communication | Verify TX→RX crossover. Both boards at 115200. Shared GND. |
| ESP8266 can't connect | GoPro must be ON with Wi-Fi enabled. Default password: goprohero |
| ESP32 can't connect MQTT | systemctl status mosquitto on Pi. Port 1883 open. |
| Camera never registers | Watch ESP32 serial for "Announced" message. Check hub logs. |