Snapshot iniziale: bridge telemetria CRSF->LTM/MAVLink (ESP-NOW)

Stato di partenza prima dei fix. Il repo git era inizializzato a meta'
(config.lock + objects/ mancante, zero commit): riparato.
my_config.h (UID reale, tutti e 3 i sottoprogetti) escluso via .gitignore;
aggiunto my_config.h.example. .pio/ escluso.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Francesco Zanin
2026-06-23 19:32:11 +02:00
commit e22a47fce1
284 changed files with 132664 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
# Backpack Emulator — bench Tier 3 per 02_telemetry_bridge
ESP32-S3 che spedisce via **ESP-NOW** pacchetti sintetici identici (per
formato) a quelli del TX Backpack ELRS reale, verso l'UID del ricevitore
sotto test. Permette di validare `02_telemetry_bridge` (o `01_telemetry_reader`)
**senza aereo, GPS o radio ELRS**: bastano le due board collegate via USB sullo
stesso banco.
## Perché esiste
I Tier 02 della suite di test (`pio check`, unit test nativi su `lib/Ltm`,
unit test on-device su `lib/EspNowCrsf` e sul path di decodifica CRSF)
verificano la logica in isolamento. Il Tier 3 chiude il cerchio: due board
reali, ESP-NOW vero, stesso firmware di produzione sul ricevitore.
## Formato del pacchetto
Identico a quello del backpack reale (vedi `lib/EspNowCrsf/EspNowCrsf.cpp` sul
ricevitore):
```
[0..7] header 8 byte (contenuto ignorato dal parser del ricevitore)
[8..] frame CRSF grezzo: sync(0xC8) len type payload... crc
```
Il CRC è calcolato con lo stesso CRC8 (poly `0xD5`) usato da terseCRSF, quindi
i frame sono validi byte-per-byte, non solo "abbastanza buoni da passare il
parser".
## Cosa manda
Cicla ogni 250 ms tra 5 frame CRSF, con payload **identici** ai vettori già
verificati in `02_telemetry_bridge/test/test_embedded_crsf_decode/test_decode.cpp`:
| Tipo | ID | Valori attesi sul ricevitore (modo HUMAN) |
|------------|--------|--------------------------------------------|
| GPS | 0x02 | lat 45.46421, lon 9.19, alt 152 m, sat 11 |
| BATTERY | 0x08 | 16.4 V, 1.2 A, 78% |
| ATTITUDE | 0x1E | pitch 9.998°, roll -5.002°, yaw 330° |
| LINK | 0x14 | RSSI -52dBm ant1, LQ 100%, SNR -9dB |
| FLIGHTMODE | 0x21 | "ACRO" |
Ogni 8 invii (~2s) manda anche un **keep-alive** (header + 2 byte a zero), per
esercitare il filtro anti-keep-alive su hardware reale e non solo nel test
unitario (regressione del bug off-by-one corretto in `EspNowCrsf.cpp`).
Confrontando i valori stampati dal ricevitore con la tabella sopra si valida
in un colpo il path completo: ESP-NOW → ring buffer → filtro keep-alive →
decode CRSF → dashboard.
## Setup
1. `src/my_config.h``TARGET_UID` deve essere **lo stesso UID** configurato
in `02_telemetry_bridge/src/my_config.h` (o `01_telemetry_reader`) sulla
board ricevitrice sotto test. Non serve la bind phrase reale: è solo
l'indirizzo a cui spedire.
2. Collega l'ESP32-S3 (qui: COM7) e l'ESP32 ricevitore (qui: COM4) allo stesso
PC, due porte separate.
3. Flasha il ricevitore in modo **HUMAN** (così vedi i valori decodificati)
o **CRSF_DUMP** (per vedere i frame grezzi).
4. Build → Upload → Monitor su questa cartella (115200).
5. Confronta l'output del ricevitore con la tabella sopra.
## Struttura del codice
```
platformio.ini
src/
main.cpp # init ESP-NOW + invio ciclico GPS/BATTERY/ATTITUDE/LINK/FLIGHTMODE + keep-alive
my_config.h # TARGET_UID -- DA COMPILARE (stesso UID del ricevitore)
```
## Limiti
Emula solo il **formato del pacchetto**, non l'intero stack ELRS (niente link
budget, niente vera bind phrase, niente canale/RF reale oltre a ESP-NOW su
canale 1). Per la validazione con catena RF completa serve comunque la radio
ELRS configurata con `Telemetry = ESPNOW` e l'UID reale dalla bind phrase.