Files
Crossfire-to-Multi-telemetr…/02_telemetry_bridge
Francesco Zanin 5d6f646a5e Pulizia: rimosso codice morto RC/SBUS/PWM e uplink ESP-NOW inutilizzato
terseCRSF vendorizzata: rimosse initialise/sbus_initialise/readCrsfFrame/
decodeRC/printPWM/prepSBUS/bytesToPWM/pwmToBytes/sendSBUS e i membri/buffer
SBUS-PWM (sb_bytes, pwm_val, crsf_port, sbus_port, RC_BUILD/SBUS machinery).
Usiamo solo decodeTelemetry: mantenuti i decoder + helper (bytes2*, wrap360,
crc8_dvb_s2[_sbuf_accum] usata dalla patch CRC, printByte/printBytes). ~283
righe in meno, nessun riferimento pendente (verificato con grep su 01/02/03).

EspNowCrsf: rimosso sendRaw() e il peer broadcast in begin() (uplink
sperimentale morto, il backpack e' downlink-only). Ora RX-only pulito.

main.cpp: commento "MAVLink v1" -> "v2" (la lib emette v2).

DA VERIFICARE A BANCO con un build (qui non compilabile).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 16:55:41 +02:00
..

Telemetry Bridge — firmware unico multi-modo

ESP32 DevKit che riceve la telemetria CRSF dal TX Backpack ELRS via ESP-NOW e la espone in 4 modalità selezionabili a runtime (comando seriale, scelta salvata in NVS). Un solo firmware da compilare; nessuna ricompilazione per cambiare uso.

Modalità

# Nome USB Cosa fa
0 HUMAN testo Dashboard leggibile (GPS, batteria, assetto, link) a 1 Hz
1 CRSF_DUMP testo Dump esadecimale grezzo di ogni frame CRSF (debug/reverse)
2 LTM binario Traduce CRSF → LTM v2 per mwptools (monitoraggio volo)
3 MAVLINK binario Traduce CRSF → MAVLink v2 per mwptools (include corrente in A)

Selezione della modalità (comando seriale)

La scelta è persistente (NVS). Dal monitor seriale @115200 digita:

  • ! seguito da 0..3 → seleziona quel modo direttamente;
  • ! seguito da m → passa al modo successivo (ciclico).

La board salva la scelta in NVS e si riavvia nel nuovo modo. Senza comando, riparte sull'ultimo modo salvato.

Perché un comando seriale e non il pulsante BOOT. BOOT è GPIO0, strapping pin del bootloader: tenerlo premuto al reset manda l'ESP32 in download mode invece di eseguire il firmware, quindi il cambio modo via BOOT non era affidabile. Il prefisso ! è obbligatorio perché mwp in modo INAV interroga via MSP (byte $M<...): senza prefisso la M verrebbe interpretata come comando e farebbe cambiare modo da sola.

Uso con mwptools

Entrambi i modi LTM e MAVLink sono downlink unidirezionale — perfetti per il path downlink-only del backpack. In mwp: Connectporta USB dell'ESP32 → protocollo INAV, baud 115200.

  • Modo LTM (#2): posizione, assetto, batteria (V, mAh). LTM in INAV è opera di Jonathan Hudson, lo stesso autore di mwp.
  • Modo MAVLINK (#3): come LTM più la corrente istantanea in Ampere (SYS_STATUS/BATTERY_STATUS), RSSI (RADIO_STATUS) e % batteria — campi che LTM non trasporta. Messaggi emessi: HEARTBEAT, SYS_STATUS, GPS_RAW_INT, ATTITUDE, VFR_HUD, BATTERY_STATUS, RADIO_STATUS.

Problema noto (aperto): mwp mostra la corrente come ~0.12 A invece di 1.2 A (fattore ÷10). La codifica del firmware è spec-corretta (current_battery in cA: 120 cA = 1.2 A, verificato a byte). Sembra un'interpretazione non standard lato mwp; da indagare.

Cosa non fa: missioni, lettura/scrittura parametri, qualunque cosa MSP request/response (bidirezionale). Vedi i limiti qui sotto.

Il backpack ELRS via ESP-NOW è downlink-only by design. I maintainer ELRS (discussion #3510, gen 2026) confermano che il backpack non inietta pacchetti arbitrari nell'uplink OTA, e che l'uplink verso l'FC è possibile solo dal flusso CRSF dell'handset (radio → TX → OTA → RX → FC), con telemetria attiva.

Conseguenza: MSP bidirezionale verso l'FC attraverso il backpack non è realizzabile con ELRS stock (per questo il vecchio modo MSP sperimentale è stato rimosso). Per vero MSP bidirezionale con mwp serve un link seriale trasparente dedicato (coppia SiK/3DR 433-915 MHz, oppure mLRS con MSPX): architettura separata, non questo ESP32 sul backpack.

Struttura del codice

platformio.ini
src/
  main.cpp           # dispatcher: comando seriale '!' + NVS, loop sui modi
  my_config.h        # UID (bind phrase)                     <-- DA COMPILARE
  modes.h            # interfaccia Mode {begin,onFrame,tick}
  mode_human.cpp     # modo 0
  mode_crsfdump.cpp  # modo 1
  mode_ltm.cpp       # modo 2  (usa lib/Ltm)
  mode_mavlink.cpp   # modo 3  (usa lib/mavlink)
lib/
  EspNowCrsf/        # init ESP-NOW + ring buffer dei frame CRSF (condiviso)
  Ltm/               # encoder LTM v2 (layout fedele a inav/ltm.c)
  terseCRSF/         # parser CRSF VENDORIZZATO e patchato (vedi sotto)
  mavlink/           # libreria MAVLink ufficiale (c_library_v2, vendorizzata)

Aggiungere un nuovo modo = nuovo mode_xxx.cpp che esporta un Mode, più una riga nell'array MODES[] in main.cpp.

Librerie vendorizzate

terseCRSF e mavlink sono copiate in lib/ (non più via lib_deps) così le patch locali sono permanenti e versionate:

  • terseCRSF — patch documentate in cima a lib/terseCRSF/src/terseCRSF.h: (1) disattivati i #define SHOW_* di debug, che stampavano testo dentro lo stream binario LTM/MAVLink corrompendolo; (2) corretto bat_fuel_drawn (leggeva 4 byte includendo il byte percent → mAh consumati errati).
  • mavlink — dialetti minimal+common+standard di c_library_v2; include base -I lib/mavlink in platformio.ini (si include come <common/mavlink.h>).

Build / upload

Apri la cartella in VSCode/PlatformIO, Build → Upload → Monitor (115200). Le librerie sono già in lib/ (la prima build scarica solo il core 2.0.17). Ricorda di mettere il tuo UID in src/my_config.h.

Upload: questa board entra in download mode solo tenendo BOOT premuto durante il Connecting... di esptool (poi rilascia). Non tenerlo premuto fino al reset finale.