Repository navigation
Conversation
Adds an opt-in BLE central to the TX backpack so a device advertising the FrSky trainer service (0xFFF0 / 0xFFF6), most notably a HeadTracker in "Wireless Transmitter (Head)" mode, can feed the radio's trainer input without the BTWifiModule hardware. The backpack connects over BLE, parses the FrSky trainer frame (8 channels), converts it to CRSF values and emits MSP_ELRS_BACKPACK_SET_PTR to the TX module over the backpack UART. The module already understands that opcode (HT Enabled / HT Start Channel = EdgeTX), so no ExpressLRS change is needed for the core feature. Although head tracking is the main use case, the implementation is generic: any FrSky trainer source works, hence the name "FrSky BLE trainer". Highlights: - src/BleTrainer.cpp + include/BleTrainer.h: NimBLE central (scan 0xFFF0, pair strongest RSSI, store MAC, reconnect on boot, Forget), per-notification FrSky parser, PWM->CRSF conversion, SET_PTR emission. - Steady 50 Hz republication so EdgeTX's trainer input does not time out. - 8 ms default connection interval, 4 s supervision timeout. - BLE + MAVLink WiFi coexistence (WiFi preference, BLE P3 in MAVLINK_TX). - Config v6: trainerPeerMac/Type/IntervalMs/Source (Auto/Native/BLE). - WebUI tab "FrSky BLE Trainer"; POST /settrainer; JSON config.trainer. - Long button press forgets the peer. - HAS_BLE_TRAINER + NimBLE-Arduino for the C3 TX backpack target. - MAVLink WiFi mode persistent across boots (telemMode). - Dedup repeated MSP_ELRS_BACKPACK_CONFIG telemetry-mode to avoid reboot loops. Validated on the Nomad: SET_PTR ~50/s, EdgeTX trainer channels move, HT + MAVLink WiFi simultaneously (10-min soak, 0 resets), module power up to 250 mW, cold boot and updater cycle. Build: ~1.19 MB (60.4% of min_spiffs), RAM 55.980 B.
Contributor
|
Tested with https://headtracker.gitbook.io/ (Arduino Nano 33 BLE Sense Rev.2 flashed with HT v2.4.0 code of https://github.com/headtracker/HeadTracker/releases ). |
Amigache
added a commit
to Amigache/Backpack
that referenced
this pull request
Oct 5, 2026
- Config v7: add bleTrainerEnable (default Off). Bumping the version resets the backpack EEPROM (re-pair required). - Handle MSP_ELRS_BACKPACK_CONFIG_BLE_TRAINER (enable) and MSP_ELRS_BACKPACK_TRAINER_PAIR (scan and pair with the strongest). - BLE trainer is now lazily initialized only when enabled; disabling stops all activity (no scan/connect). It auto-connects to the paired peer and never drops the stored MAC on connection failure (manual pairing). - WebUI tab: Enable checkbox and Pair button; /config exposes "enabled". Built on top of the FrSky BLE trainer feature (ExpressLRS#248).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an opt-in BLE central to the TX backpack so a device advertising the
FrSky trainer service (
0xFFF0/0xFFF6) - most notably a HeadTrackerin Wireless Transmitter (Head) mode - can feed the radio's trainer input
without the BTWifiModule hardware.
The backpack connects over BLE, parses the FrSky trainer frame (8 channels),
converts it to CRSF values and emits
MSP_ELRS_BACKPACK_SET_PTRto the TXmodule over the backpack UART. The module already understands that opcode
(
HT Enabled/HT Start Channel = EdgeTXin the ELRS Lua), so no ExpressLRSchange is required for the core feature.
Although head tracking is the main use case, the implementation is generic:
any FrSky trainer source works. Hence the name FrSky BLE trainer
(
BleTrainer).Scope
VRX and Timer backpacks are unchanged.
HAS_BLE_TRAINER; currently enabled forESP32C3_TX_Backpack_via_UART.chooses Auto / Native / BLE.
Changes
src/BleTrainer.cpp+include/BleTrainer.h: NimBLE central (scan for0xFFF0, pair strongest RSSI, store MAC, reconnect on boot, Forget),per-notification FrSky parser (
0x7E/0x7Dbyte-stuff,0x80+ 8 channels,XOR CRC), PWM->CRSF conversion and
SET_PTRemission.not time out between irregular BLE notifications.
since the trainer asks for its own first) and 4 s supervision timeout.
esp_coex_preference_set(ESP_COEX_PREFER_WIFI)and reduced BLE TX power (P3) in
MAVLINK_TX.trainerPeerMac/trainerPeerType/trainerIntervalMs/trainerSource(Auto / Native / BLE).using the existing
/config+callback()patterns; newPOST /settrainer;JSON
config.trainer.HAS_BLE_TRAINER+h2zero/NimBLE-Arduinofor the C3 TX backpack target.telemMode(restored on every boot),so entering the updater no longer leaves the backpack without an AP.
MSP_ELRS_BACKPACK_CONFIGtelemetry-mode message so themodule cannot trigger a reboot loop.
Testing
Hardware: RadioMaster Nomad (ESP32-C3 TX backpack) + TX16S + Arduino Nano 33 BLE
running HeadTracker (Wireless Transmitter / Head); Mission Planner as GCS.
Validated:
linked:true,SET_PTR~ 50/s (setptr5917 -> 6119 in 4 s),EdgeTX trainer channels move.
disconnects, GCS telemetry continuous (
packets_down~ 55/s,overflows_down: 0).enter/exit returns to MAVLink WiFi.
min_spiffs), RAM 55.980 B.Notes for reviewers
FrSky BLE trainer): it implements theFrSky trainer profile, not head tracking specifically. Head tracker is
documented as the main use case.
espressif32@6.7.0(Arduino-ESP32 2.0.x / IDF 4.4); 2.x needs a newer core.re-pair.
Link Mode = MAVLINKthe trainer needs a live RF link: without a linkedreceiver the module does not drain its UART FIFO. Worth a user-facing note;
not a code issue.
Related
Lua
Backpackmenu. The Lua builds the menu from the module's parameterstructure, so only a module-side field plus a new MSP is needed. Not required
for this PR.