Add software LiPo UV protection with energy-save boot.

Detect under-voltage on GPIO1/11, persist UV state in NVS, enter a minimal
power mode without ESP-NOW, and recover after charge; expose LED mode 6
battery-low for host testing via goTool.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-23 18:22:52 +02:00
co-authored by Cursor
parent be18b758ed
commit f006f8b912
26 changed files with 418 additions and 37 deletions
+29 -10
View File
@@ -91,15 +91,17 @@ idf.py -p /dev/ttyUSB0 flash monitor
### 4.1 Initialisierungsreihenfolge (`powerpod.c`)
1. `pod_settings_init()` — NVS
2. DIP → `app_config.master`
3. I2C + IO-Expander → `app_config.network` (18)
4. `init_bma456()` — optional, bei Fehler weiter ohne Sensor
5. `pod_settings_apply_accel_deadzone()` wenn Sensor da
6. OTA-Partition → `app_config.running_partition`
7. `board_input_init()`
8. `esp_now_comm_init(&app_config)`**immer** (Master + Slave)
9. `led_ring_init()`
10. **Nur Master:** `cmd_queue``init_cmdHandler``init_uart` → alle `cmd_*_register()`
2. `board_input_init_adc_only()` — LiPo-ADC
3. Bei `POWERPOD_BATTERY_UV_ENABLE`: `battery_uv_evaluate_boot()` → ggf. Energiesparmodus (nur LED + ADC, **kein** weiterer Init)
4. DIP → `app_config.master`
5. I2C + IO-Expander → `app_config.network` (18)
6. `init_bma456()` — optional, bei Fehler weiter ohne Sensor
7. `pod_settings_apply_accel_deadzone()` wenn Sensor da
8. OTA-Partition → `app_config.running_partition`
9. `board_input_start_lipo_monitor()` + `board_input_init_button()`
10. `esp_now_comm_init(&app_config)`**normaler Pfad** (Master + Slave)
11. `led_ring_init()`
12. **Nur Master:** `cmd_queue``init_cmdHandler``init_uart` → alle `cmd_*_register()`
### 4.2 Master vs. Slave
@@ -397,6 +399,7 @@ Ohne Sensor: `bma456_is_ready() == false`, Firmware läuft weiter.
- Segment-Karten für Ziffern 010 in `digit_lookup[]`.
- **Kein** lokaler Demo-Loop — Anzeige nur über UART (`cmd_led_ring.c`) oder ESP-NOW `ESPNOW_LED_RING`.
- Helligkeit: `intensity` 0 → Default ~5 % (`LED_RING_DEFAULT_INTENSITY`).
- Modi: `0` clear … `5` color, `6` **battery-low** (erste 4 LEDs rot ~10 %, 5 s).
---
@@ -405,12 +408,26 @@ Ohne Sensor: `bma456_is_ready() == false`, Firmware läuft weiter.
`board_input.c`:
- **Taster** GPIO 12 — Logging bei Druck.
- **LiPo-ADC** GPIO 1 und GPIO 11.
- **LiPo-ADC** GPIO 1 und GPIO 11 (Pin-Spannung in mV).
- Master: `master_monitor_task` aktualisiert Master-Batterie alle 30 s.
- Slave: `slave_send_battery_report_to_master` nach Join, Heartbeat und Query.
Spannungen in Millivolt in Registry und `BATTERY_STATUS`-UART.
### Software-UV-Schutz (`battery_uv.c`)
Aktivierbar mit `POWERPOD_BATTERY_UV_ENABLE` in `powerpod.h` (CMake-Override möglich).
| Zustand | ADC-Schwelle | Logik |
|---------|--------------|-------|
| UV | &lt; 2300 mV | Ein gültiger Kanal reicht |
| Geladen | ≥ 3000 mV | Alle gültigen Kanäle |
- NVS-Key `uv_latch` in `pod_settings.c`
- Boot: ADC früh, bei UV nur LED + ADC-Poll (kein ESP-NOW/WiFi/UART/I2C/Button)
- Runtime: `battery_uv_poll()` im LiPo-Monitor (2 Samples Debounce)
- LED-Anzeige: Mode `6` battery-low (`led_ring_show_battery_low`)
---
## 12. Persistenz (NVS)
@@ -420,6 +437,7 @@ Spannungen in Millivolt in Registry und `BATTERY_STATUS`-UART.
| Key | Inhalt |
|-----|--------|
| `accel_dz` | Accel-Deadzone LSB |
| `uv_latch` | Software-UV-Zustand (`1` = Energiesparmodus) |
Gespeichert bei lokalem Set (UART `client_id=0`, ESP-NOW auf Slave). Geladen nach `init_bma456()`.
@@ -493,6 +511,7 @@ Includes in generierten `.pb.c` müssen `"uart_messages.pb.h"` heißen (nicht `m
| `bosch456.c` | Accelerometer + Tap |
| `led_ring.c` | LED-Anzeige |
| `board_input.c` | Taster, ADC |
| `battery_uv.c` | Software-UV-Schutz, Energiesparmodus |
| `pod_settings.c` | NVS |
| `pod_reboot.c` | Verzögerter Restart |
| `ota_uart.c` | Flash-Puffer UART-OTA |