generated from CubeCraft-Creations/Tracehound
b3d4226b1c
Complete rewrite of firmware into two dedicated boards per camera node: ESP8266 (Camera Bridge): - Connects ONLY to GoPro AP — polls status, sends over UART - Zero network switching, zero MQTT - HTTP GET /bacpac/SH for status, start/stop - JSON-per-line UART protocol to ESP32 ESP32 (MQTT Bridge): - Connects ONLY to travel router — MQTT to Pi hub - Reads status from ESP8266 over UART2 (RX16/TX17) - Auto-registration, heartbeat, command forwarding - Zero camera communication UART Protocol: JSON-per-line at 115200 8N1 ESP8266→ESP32: status/ack/pong/error ESP32→ESP8266: cmd (start_recording/stop_recording/ping) Hardware updates: - BOM now includes both boards (~4/node) - 3D case has stacked dual-board compartment - UART wire channel between board recesses - Shared 3.3V power rail for both boards
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 → 192.168.4.10│
│ 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 (192.168.4.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 |
"192.168.4.10" |
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. |