Protocol
LapDog frames (USB and Bluetooth)
Every event is one small binary frame, identical on both transports, so a receiver needs a single parser:
- USB:
F:+ hex + newline, mixed in with plain text replies and logs. - Bluetooth: the raw frame as manufacturer data in a legacy advert (company ID
0xFFFFfor now).
A legacy advert carries 31 bytes. After the flags and manufacturer-data header, 24 are left, so a frame is at most 24 bytes and always fits in one advert.
Header
| Byte | Field |
|---|---|
| 0 | version (high nibble, currently 2) and type (low nibble) |
| 1 | seq: increments every frame, used to drop repeated adverts and USB/Bluetooth duplicates |
| 2 | pilot |
Types
Multi-byte values are little-endian.
| Type | Body |
|---|---|
1 LAP |
lap number (0 = start/holeshot), flags (best, final), lap time ms u32 |
2 ARMED |
mode, heat u16, lap limit, time limit s u16 |
3 DISARMED |
heat u16, laps completed, passes ignored |
4 HEARTBEAT |
race stage, mode, heat u16, uptime ms u32 |
5 RACE |
race stage, race time ms u32 since GO |
6 TEXT |
slot, part/parts, up to 19 bytes of text |
7 IGNORED |
reason (1 too soon, 2 too long), ms u32, count this heat |
TEXT carries the race messages: slots 0–17 are goggle OSD rows (the same text the goggles show), plus the event name and the heat prefix. Text longer than one frame is split into up to 15 parts with consecutive sequence numbers.
ESP-NOW (goggles and RacePanel)
On ESP-NOW, LapDog acts as an ELRS Backpack timer, the way RotorHazard's VRxC_ELRS plugin does on race days:
- The sender MAC is your ELRS bind-phrase UID: the first six bytes of
MD5("-DMY_BINDING_PHRASE=\"<phrase>\""), with the multicast bit cleared. - Messages are MSPv2 frames with function
0x00B6(MSP_ELRS_SET_OSD):0x02clear,0x03 row col 0 text…to place text, and0x04to display. - Rows: event 0, heat 2, race status 5, lap result 15 (e.g.
L1:0:14.630 | BEST). - Always on a 2.4 GHz channel. Never 5 GHz ESP-NOW: Wi-Fi channels 149–165 overlap the FPV band and would hit your video right at the gate.
The encoder and decoder live in vrxc-msp, a small header-only library shared by LapDog and RacePanel so they can't drift apart.