Skip to content
This repository was archived by the owner on Oct 14, 2026. It is now read-only.

Add Bluetooth telemetry (S.Port + CRSF), auto-connect and a selectable NimBLE host - #21

Closed
Amigache wants to merge 6 commits into
dlktdr:mainfrom
Amigache:1.0-dev
Closed

Amigache wants to merge 6 commits into
dlktdr:mainfrom
Amigache:1.0-dev

Conversation

@Amigache

@Amigache Amigache commented Oct 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

This adds Bluetooth Telemetry, auto-connect, a configurable device
name
and an optional NimBLE BLE host. The existing trainer modes
(master / slave) are unchanged.

Features

  • Bluetooth Telemetry over BLE — new.
    • S.Port (FrSky models): EdgeTX forwards the S.Port frames over the BT
      serial link and the module forwards them over BLE.
    • CRSF (ELRS models): EdgeTX forwards raw CRSF frames and the module
      passes them through unchanged.
    • The client app auto-detects the protocol, so both work over the existing
      service (0xFFF0) / characteristic (0xFFF6); no GATT change.
  • Auto-connect to the last known device (closes Bluetooth auto connect #20). The module scans and
    reconnects as soon as the saved peer appears — the peer's BLE address type is
    only known after scanning — including after a link loss.
  • Device name via AT+NAME (builds on Set device name via the AT+NAME<name> #18). The name is persisted and used
    as the GAP name and in the advertising payload; LEN_BLUETOOTH_NAME goes
    from 10 to 20 so longer names fit in a single advertising packet.
  • EdgeTX robustness:
    • re-announce Connected: on AT+ROLE1 / AT+CON and every 2 s;
    • AT+CLEAR really forgets the peer (previously auto-connect brought it
      back);
    • AT+DISC? drops the current link first, so the OK+DISC lines are not
      interleaved with trainer frames;
    • send DisConnected on a link drop so EdgeTX leaves the CONNECTED state;
    • require the AT+ prefix when scanning for commands, to avoid false
      triggers inside binary telemetry/trainer frames.
  • Selectable BLE host: Bluedroid (default) or NimBLE
    (-DUSE_NIMBLE, env C3SuperMini_nimble). On the ESP32-C3 (1 MB app):
    Bluedroid ~84 % flash / 8.8 % RAM vs NimBLE ~52 % flash / 6.3 % RAM.

How telemetry works

In Telemetry mode EdgeTX forwards the radio's telemetry over the BT serial
link. The module passes those bytes to the connected BLE central unchanged
(in MTU-sized chunks), so a single path covers S.Port (0x7E-framed), CRSF
(raw) and, in principle, LTM/MAVLink. This also fixes the previous
S.Port-only parser overflowing (RX Buffer Overflow) on CRSF streams.

Hardware / EdgeTX

Validated on an ESP32-C3 SuperMini inside a Radiomaster TX16S MK3
(EdgeTX). Note: the TX16S MK3 needs EdgeTX PR #7855
(BT_PWR_GPIO = PC13) to power the AUX2/BT connector; it is included in
current nightlies.

Validation

  • AT handshake, device name, auto-connect, Clear, discovery.
  • S.Port telemetry → INAV / Telemetry Viewer.
  • CRSF telemetry → Telemetry Viewer (RomanLut fork) with an ELRS drone.
  • Trainer master with a real HeadTracker (channels move).
  • Both BLE hosts: Bluedroid and NimBLE.

Notes

  • The Bluedroid implementation is kept behind #if !defined(USE_NIMBLE), so
    both hosts share the same application code.
  • sdkconfig.C3SuperMini is a generated file that is currently tracked, so it
    churns on every build.

- Forward the radio's S.Port telemetry frames over BLE (service 0xFFF0,
  characteristic 0xFFF6), generalising the frame parser to delimit on 0x7E
  and classify by length (14 = trainer, 9 = S.Port).
- Store the name sent by the radio via AT+NAME and use it as the GAP name
  and in the advertising payload; raise LEN_BLUETOOTH_NAME from 10 to 20.
- Pin the espressif32 platform to 6.7.0 for reproducible builds.
- Auto-connect in central mode: continuous scan and connect as soon as the
  saved peer address appears (the peer's BLE address type is only known
  after scanning), including after a link loss.
- Re-announce "Connected:" on AT+ROLE1 / AT+CON and every 2 s so EdgeTX
  reliably leaves "Not connected".
- AT+CLEAR now forgets the saved peer (previously auto-connect brought it
  back); AT+DISC? drops the current link first so the OK+DISC lines are not
  interleaved with trainer frames; send "DisConnected" on link loss.
- Require the "AT+" prefix when scanning for commands, to avoid false
  triggers inside binary telemetry/trainer frames.
- Allow Bluetooth names up to 19 characters.
Add an alternative BLE host based on Apache NimBLE, selectable with
-DUSE_NIMBLE (build environment C3SuperMini_nimble and
sdkconfig.C3SuperMini_nimble). The Bluedroid implementation is kept behind
#if !defined(USE_NIMBLE).

- bt.c: NimBLE host init/disable and the shared host task.
- bt_server.c: peripheral (service 0xFFF0, characteristic 0xFFF6, raw
  advertising with the radio name, notify).
- bt_client.c: central (scan, connect, discovery, CCCD subscribe,
  notify -> UART).

NimBLE-specific fixes found during hardware validation:
- reverse addresses between NimBLE's little-endian wire order and the
  display order used by btaddrtostr()/strtobtaddr();
- store the connected central address so "Connected:" is meaningful;
- accept 128-bit UUIDs built on the Bluetooth base UUID as their 16-bit
  alias (some peripherals expose 0xFFF0/0xFFF6 that way);
- set the initiator scan interval/window (zero made the controller reject
  the connect with HCI 0x12).

Footprint on the ESP32-C3 (1 MB app): Bluedroid ~84% flash / 8.8% RAM,
NimBLE ~52% flash / 6.3% RAM.
- Peripheral mode now forwards the radio's UART bytes to the connected BLE
  central unchanged, in MTU-sized chunks, instead of re-framing only S.Port.
  EdgeTX already frames S.Port (0x7E delimited) and forwards CRSF raw, and
  the client app auto-detects the protocol, so this supports both and stops
  the previous S.Port-only parser from overflowing on CRSF streams.
- Do not forward the connected central's trainer frames to the radio until
  EdgeTX has confirmed the mode (AT+ROLE1 / AT+CON). Previously a module
  booted in central mode auto-connected to the tracker and its high rate
  stream drowned EdgeTX's AT handshake, leaving it stuck after AT+NAME.
@Amigache Amigache closed this Oct 14, 2026
@Amigache
Amigache deleted the 1.0-dev branch October 14, 2026 19:28
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bluetooth auto connect

1 participant