Skip to content

feat: replace JSON BLE protocol with compact binary encoding#3

Merged
spectrachrome merged 5 commits intomainfrom
ble_binary_protocol
Feb 23, 2026
Merged

feat: replace JSON BLE protocol with compact binary encoding#3
spectrachrome merged 5 commits intomainfrom
ble_binary_protocol

Conversation

@spectrachrome
Copy link
Owner

Summary

  • Replace the JSON-over-NUS BLE protocol with a compact binary protocol
    (spec: docs/binary_protocol.md) — state snapshots shrink from ~300 bytes
    / ~15 BLE packets down to 22 bytes (1–2 packets)
  • Setter commands are 1–4 bytes with single-byte ack responses (0x00 OK /
    0xE0 parse error / 0xE1 range error), replacing verbose JSON
    round-trips
  • Add TestPattern command (0xF0) that triggers a 5-second solid-color
    episode (red/green/blue/white) at full intensity, bypassing all
    post-processing — useful for verifying LED wiring and color order
  • Add GetVersion command (0x02) returning protocol version + firmware
    semver (5 bytes)
  • Remove serde, serde_json_core, and heapless crate dependencies
    (saves ~15 KB flash)

What changed

File Change
src/ble.rs Full rewrite: binary command parser
(handle_binary_command), state encoder (22-byte snapshot), version encoder, constants for all command/response IDs, unit tests
src/bin/main.rs Shrink TX buffer 512→32 bytes, remove RX reassembly buffer entirely, remove newline framing, binary ble_handle_message, wall-clock test pattern deadline, BLE RX logging
src/state.rs Add TEST_PATTERN signal for inter-task test pattern
trigger
Cargo.toml Remove serde, serde_json_core, heapless
docs/binary_protocol.md Full protocol specification (frame format,
command table, state snapshot layout, version response, error codes)

Protocol at a glance

App → Device (commands):
0x01 GetState → 22-byte state snapshot
0x02 GetVersion → 5-byte version response
0x10..0x1D Setters → 1-byte ack (0x00 OK)
0xF0 TestPattern → 1-byte ack, 5s solid color episode

Device → App (responses):
0x00 OK
0x01 + 21B State snapshot
0x02 + 4B Version (protocol v1, fw semver)
0xE0 Parse error
0xE1 Range error

Test plan

  • Flash firmware, connect with nRF Connect — verify GetState (0x01)
    returns 22 bytes starting with 0x01 0x01
  • Send GetVersion (0x02) — verify 5-byte response 02 01 00 01 00
  • Send SetBrightness (10 80) — verify 00 ack, then GetState
    shows updated brightness
  • Send TestPattern red (F0 00) — verify 5-second solid red, returns
    to normal pattern
  • Send out-of-range value (e.g. 12 00 for FPS=0) — verify E1 range
    error
  • Verify state auto-push on flight mode change (arm/disarm with FC
    connected)
  • Verify strobe only activates when armed/arming-allowed with TX linked

22-byte state snapshots (down from ~300 JSON), 1-4 byte commands,
1-byte acks. Eliminates serde, serde_json_core, and heapless deps.
Triggers red, green, blue, or white at full intensity, bypassing all
post-processing. Uses wall-clock deadline instead of frame counting
to avoid SPI write overhead inflating the duration.
Prevents phantom strobe on the bench when no TX is powered on.
The FC reports default RC channel values (~1500) that passed the
AUX7 > 1250 threshold. Also adds ±10 deadband to TX link detection
and drains stale UART bytes before each MSP_RC poll.
Merge main branch into ble_binary_protocol, incorporating:
- AUX strobe gated on armed/arming-allowed flight mode
- TX link detection with ±10 deadband (replaces exact 1500 comparison)
- UART drain before MSP_RC polls to prevent desync
- BLE RX command logging adapted for binary protocol
@spectrachrome spectrachrome merged commit eaa8fbd into main Feb 23, 2026
1 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant