Files
led-controller/docs/espnow-binary-protocol.md
Jimmy 4fc3f46866 feat(espnow): Pi bridge client, binary wire, and espnow-sender firmware
Replace serial/Wi-Fi driver transport paths with WebSocket bridge client,
binary espnow_wire delivery, device announce registry, and restructured
espnow-sender (AP + broadcast passthrough). Includes docs and tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-23 22:44:44 +12:00

2.5 KiB
Raw Blame History

ESP-NOW binary protocol

See also: espnow-architecture.md (diagrams, flows, configuration).

All ESP-NOW datagrams and Pi↔bridge WebSocket frames use binary only (no JSON on the wire). Maximum ESP-NOW payload length: 250 bytes.

ESP-NOW packet

Offset Field
0 Magic 0x4C ('L')
1 Message type
2… Type-specific body

Message types

Value Name Direction
0x01 ANNOUNCE Driver → broadcast
0x02 GROUPS Controller → driver
0x03 CMD Controller → driver
0x04 GROUP_CMD Controller → broadcast
0x10 BRIDGE_CH Controller → broadcast

ANNOUNCE (0x01)

Driver settings at boot. Sender MAC is taken from the ESP-NOW peer address (not repeated in the body).

Field Type
name_len u8
name UTF-8
num_leds u16 LE
color_order u8 enum: 0=rgb, 1=rbg, 2=grb, 3=gbr, 4=brg, 5=bgr
startup_mode u8: 0=default, 1=last, 2=off
brightness u8 0255
device_type u8: 0=led

GROUPS (0x02)

Field Type
count u8
× count u8 id_len + UTF-8 group id

CMD (0x03)

Bytes 2… are a v2 binary envelope (see src/util/binary_envelope.py): 5-byte header + presets/select/default blobs. Total packet ≤ 250 bytes.

GROUP_CMD (0x04)

Field Type
group_id_len u8
group_id UTF-8
cmd_envelope v2 binary envelope

Drivers apply the nested envelope only if group_id is in their stored group list.

BRIDGE_CH (0x10)

Field Type
channel u8 (111)

Sets the bridge ESP32 STA channel (not forwarded to LED drivers as a command).

Pi ↔ bridge WebSocket frame

Binary WebSocket messages only.

Offset Field
0 flags: bit0 = broadcast destination; bit1 reserved
16 peer MAC (6 bytes); ignored if broadcast
7… ESP-NOW packet (magic + type + body)

Broadcast destination uses peer ff:ff:ff:ff:ff:ff.

The bridge maintains at most 20 ESP-NOW peers (LRU eviction).

v2 command envelope

Native binary sections (no JSON). Header:

Byte Meaning
0 Version 2
1 Brightness wire 0127 (maps to 0255); 128255 = unchanged
2 Presets section length
3 Select section length
4 Default section length

See binary_envelope.py for blob layouts.