Battery calibration:
- two-point linear cal (bat_raw_min->0%, bat_raw_max->100%) of the
GoPro offset-57 raw byte, persisted in SPIFFS config
- publish battery_pct in MQTT status only when calibrated (omit
otherwise, per MQTT_CONTRACT); OLED shows % when calibrated, raw
until then
- set_battery_cal MQTT command: explicit {raw_min,raw_max} or
capture-current {point:"full"|"empty"} for field calibration
RGB STAT LED:
- drive D0/D1/D2 (R/G/B) with health colors instead of the single
green channel: red=offline, magenta=wifi-but-no-hub,
yellow=hub-but-no-camera, green=healthy; blue during boot
- RGB_COMMON_ANODE polarity flag; this module is common-anode
Verified on hardware: boots, OLED ok, RGB shows correct colors
(blue->red on the bench).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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
- Unified firmware for ESP32 (dual-STA) and ESP8266 (time-shared STA)
- ESP8266: alternates between GoPro AP and travel router per poll cycle
- PlatformIO dual-target: esp32dev + esp8266dev (d1_mini)
- camera_ip config field for Akaso/non-GoPro cameras
- LittleFS support for ESP8266 (replaces SPIFFS)
- Camera compatibility table (GoPro H3/H4, Akaso)
- LED polarity handled per-platform (ESP8266 active-low)
ESP8266 time-sharing adds ~4s latency per 30s cycle — invisible at poll rate.