Skip to content

Commit e7b1680

Browse files
committed
Rework the bind tool around the transmitter's identity
One string carried both transient status and the UID bytes, and it lived in the page subtitle -- so the header changed meaning as you used it, and the only value the tool read back had no home of its own. Split it into a phrase form, an identity block, and feedback attached to the control that caused it. Drop "Request UID". Every event it existed to cover -- the target selector moving, a first read falling silent -- is one the App can observe, so the probe runs on tool open, after each write and on a target change, keeping the bounded six-attempt retry that reports a pre-4.1 module. Stop reading the receiver at all. It answers only over a link, and a link only exists between devices already sharing a UID, so its answer could never differ from the transmitter's -- while the link's presence says the same thing for free and costs no over-air traffic. The row now reports Connected / Not connected, and the simulator no longer seeds the two devices with different UIDs, a state the radios cannot be in. Bind and Unbind confirm before acting, which is where the advice belongs: the firmware reaches EnterBindingModeSafely at either address, so "unbind" puts the receiver into bind mode rather than erasing its binding, and the other half of the pairing is still the user's to do. The Set button carries the write sequence's progress instead of a floating status line, which frees the row that restores [EXIT] on 128x64. Set also moves to its own row with fixed text, the phrase field stays editable regardless of what is reachable, and a Both write no longer flips the selector to Transmitter behind the user.
1 parent 1e44cae commit e7b1680

8 files changed

Lines changed: 419 additions & 280 deletions

File tree

README.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,19 @@ The main tool (`SCRIPTS/TOOLS/ExpressLRS/`) lets you configure your ExpressLRS t
8585
## ExpressLRS Bind Phrase Manager
8686

8787
The bind tool (`SCRIPTS/TOOLS/ExpressLRSBind/`) sets the bind phrase -- or a raw UID entered as
88-
comma-separated bytes -- on the transmitter, the receiver, or both in one sequence, reads the
89-
current UID back for verification, and can put the TX in bind mode or unbind a connected receiver.
90-
The last five phrases are kept as a pick-and-send history. Setting the phrase over MSP requires
91-
**ExpressLRS 4.1+** on the device.
88+
comma-separated bytes -- on the transmitter, the receiver, or both in one sequence, and can put the
89+
TX in bind mode or unbind a connected receiver. The last five phrases are kept as a pick-and-send
90+
history.
91+
92+
The transmitter's UID is read back automatically -- when the tool opens, after every write, and
93+
whenever you change the target -- so the page always shows the identity the handset is transmitting
94+
on. The receiver's own UID is not read: a receiver only answers over an active link, and a link only
95+
exists between devices that already share a UID, so its answer could never differ from the
96+
transmitter's. What is worth knowing is whether it is there at all, which the link reports for free.
97+
98+
Setting the phrase over MSP requires **ExpressLRS 4.1+** on the device; a pre-4.1 module never
99+
answers, and the tool says so in the transmitter row rather than retrying forever. Bind and unbind
100+
are plain CRSF commands and work on every ExpressLRS version.
92101

93102
<img src="screenshots/tool_bind_bw.png" width="256" alt="ExpressLRS Bind Phrase Manager"><br/>
94103

docs/development.md

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,21 @@ The configuration tool, `SCRIPTS/TOOLS/ExpressLRS/`:
4343

4444
The bind phrase manager, `SCRIPTS/TOOLS/ExpressLRSBind/` (sets the bind phrase / UID over MSP;
4545
the device side requires ExpressLRS 4.1+, and a pre-4.1 device simply never answers -- the tool's
46-
bounded UID retry reports that instead of polling forever):
46+
bounded UID retry reports that instead of polling forever).
47+
48+
Only the transmitter's UID is read, and only on the events that can change it: the tool opening, a
49+
write completing, and the target selector moving. The receiver is never asked. It answers over the
50+
link, a link only exists between devices already sharing a UID, so its answer is the transmitter's
51+
number by construction; the link's presence carries the whole of what asking would have told us, and
52+
costs no over-air traffic. That is also why there is no manual refresh -- every event a "read UID"
53+
button existed to cover is one the App observes for itself:
4754

4855
| Module | Purpose |
4956
|--------|---------|
50-
| `main.lua` | Entry point and the App layer: target selection (TX/RX/Both), phrase-vs-raw-UID parsing, the two-step Both sequence (RX first -- writing its phrase drops it off the link -- then TX), the bounded UID read retry, and the frame router over `crsf.drain` |
57+
| `main.lua` | Entry point and the App layer: target selection (TX/RX/Both), phrase-vs-raw-UID parsing, the two-step Both sequence (RX first -- writing its phrase drops it off the link -- then TX), the bounded transmitter UID probe, and the frame router over `crsf.drain` |
5158
| `history_storage.lua` | The last five phrases, newest first, persisted through `file_storage.lua` as indexed keys `h1`..`h5` |
5259
| `ui/lvgl.lua` | Color LCD interface |
53-
| `ui/lcd.lua` | BW LCD interface (line list, phrase editing through `ui/lcd/text_edit.lua`) |
60+
| `ui/lcd.lua` | BW LCD interface (line list, phrase editing through `ui/lcd/text_edit.lua`). Note `popupConfirmation`'s message argument never reaches the screen on BW: EdgeTX's Lua binding sets `warningInfoText` without `warningInfoLength` (`api_general.cpp` `luaPopupConfirmation`), so a confirmation has only its 24-char title (`WARNING_LINE_LEN`) to say what it needs |
5461

5562
Both tools pick their UI chunk at runtime -- `local useLvgl = (lvgl ~= nil)` -- and load exactly one
5663
of `ui/lvgl.lua` or `ui/lcd.lua`; there are no per-radio builds.
@@ -123,13 +130,14 @@ The simulator supports multiple test scenarios, configurable via the `config.sce
123130
### MSP bind traffic
124131

125132
The mock answers the bind tool's MSP `RXTX_CONFIG` traffic: a UID read (`MSP_REQ`) is served from a
126-
per-device `mspUid` table -- the TX and RX deliberately start with different UIDs so a fresh `normal`
127-
run shows a mismatch that setting both to one phrase visibly fixes -- and a phrase write
128-
(`MSP_WRITE`) rederives the target's UID through a deterministic pseudo-hash, so equal phrases give
129-
equal UIDs (the property the Both flow demonstrates; the bytes need not match the firmware's MD5).
130-
The RX answers only while the scenario keeps it reachable, which is what exercises the tool's
131-
bounded retry, and writes are unacknowledged just like the real firmware. `FRAMETYPE_COMMAND`
132-
bind/unbind requests are log-only.
133+
per-device `mspUid` table, and a phrase write (`MSP_WRITE`) rederives the target's UID through a
134+
deterministic pseudo-hash, so equal phrases give equal UIDs (the property the Both flow
135+
demonstrates; the bytes need not match the firmware's MD5). Both devices start on the same UID,
136+
because a reachable receiver whose UID differs from the transmitter's is a state the radios cannot
137+
be in. The RX answers only while the scenario keeps it reachable, and writes are unacknowledged just
138+
like the real firmware. `FRAMETYPE_COMMAND` bind requests are log-only -- note that the firmware
139+
handles that command identically at either address (`EnterBindingModeSafely`), so the "unbind"
140+
button puts the receiver into bind mode rather than erasing its binding.
133141

134142
`config.maxPacketBytes` (default 64, `CRSF_MAX_PACKET_LEN`) is the largest frame the mock handset
135143
link carries. Parameter entries longer than `maxPacketBytes - 8` are chunked exactly as

screenshots/tool_bind.png

7.94 KB
Loading

screenshots/tool_bind_bw.png

2.21 KB
Loading

src/SCRIPTS/CRSFSimulator/csrfsimulator.lua

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,12 +1258,13 @@ end
12581258
-- MSP bind UID state
12591259
-- ============================================================================
12601260

1261-
-- Per-device bind UID, read and written over MSP RXTX_CONFIG. TX and RX
1262-
-- deliberately start different so a fresh "normal" run shows a mismatch
1263-
-- that setting both to one phrase visibly fixes.
1261+
-- Per-device bind UID, read and written over MSP RXTX_CONFIG. Both start
1262+
-- on the same UID: a receiver only answers over a link, and a link only
1263+
-- exists between devices that already share one, so a reachable RX whose
1264+
-- UID differs from the TX's is a state the radios cannot be in.
12641265
local mspUid = {
12651266
[CRSF.ADDRESS_TX] = { 13, 213, 105, 32, 0, 1 },
1266-
[CRSF.ADDRESS_RX] = { 13, 213, 105, 32, 0, 2 },
1267+
[CRSF.ADDRESS_RX] = { 13, 213, 105, 32, 0, 1 },
12671268
}
12681269

12691270
--- Derive a deterministic 6-byte UID from bind-phrase bytes: the same

0 commit comments

Comments
 (0)