This is the third entry in the running series documenting Pyintel Lux — an open binary telemetry standard for microcontrollers. In this milestone: all 5 research phases are complete! We cover Phase 3 (ESP-NOW P2P mesh), Phase 4 (Host luxd SQLite proxy), and Phase 5 (Real-time in-browser WebSocket DataView charting).


The Complete 5-Phase Milestone Reached

In Entry #02, we proved that Lux achieved microsecond hardware emission speed over UART and Wi-Fi UDP.

Today, we pushed the protocol across the remaining research roadmap—implementing zero-router peer-to-peer mesh networking, SQLite host ingestion, and real-time WebSocket browser rendering.

Phase 1 (DONE)  →  Phase 2 (DONE)  →  Phase 3 (DONE)  →  Phase 4 (DONE)  →  Phase 5 (DONE)
UART emit          UDP stream         ESP-NOW Mesh       Host luxd          Web dashboard
(1 board)         (1 board + PC)     (2 boards)         ingest (SQLite)    live Chart UI

Phase 3 — ESP-NOW Peer-to-Peer Mesh (2 ESP32 Boards, No Router)

In Phase 3, we eliminated the Wi-Fi access point entirely using ESP-NOW—Espressif’s connectionless 802.11 MAC-layer protocol.

Hardware Topology

[Board A: ESP32-S3 Emitter] ──(802.11 ESP-NOW)──> [Board B: ESP32 DevKitV1 Relay] ──(UART @ 115200)──> [Host PC]
  • Board A (Emitter @ COM9): Emitted Lux binary frames over raw 802.11 frames using zero-heap batching (lux_flush).
  • Board B (Relay @ COM21): Received wireless ESP-NOW packets and relayed raw binary bytes out its UART serial port.
  • Host PC Decoder: Read Board B’s COM port using the exact same decode.py script—proving transport independence.

Empirical Results (lux_espnow_telemetry.csv)

  • Total Frames Captured: 59 frames (1,062 bytes over 30 seconds)
  • Packet Delivery Rate (PDR): 59 / 59 delivered (100.0% PDR, 0 packets lost over the air)
  • Data Integrity: 59 / 59 CRC-16 CCITT frames passed (100.0% OK)
  • Intra-burst P2P Latency (HEARTBEAT → APP_COUNTER): Min = 2.16 ms | Mean = 4.06 ± 2.96 ms
  • ESP32 Hardware Clock Delta: Minimum 10 µs

Phase 4 — Host luxd Ingest Proxy & De-Tokenization (telemetry.db)

Phase 4 built luxd_proto.py—the Python prototype of our eventual Rust luxd daemon.

Key Mechanics

  1. Symbol Dictionary De-Tokenization (symbols.json): Microcontrollers emit small 16-bit integer tokens (0x0001, 0x0101) to save wire bandwidth. luxd maps these IDs back to human-readable names (LUX_SYM_HEARTBEAT, APP_COUNTER) on the host.
  2. SQLite Database Storage: Automatically writes structured records to telemetry.db containing seq_num, symbol_name, esp_timestamp_us, payload_type, payload_value, and crc_ok.

Phase 5 — Real-Time WebSocket Web Dashboard (index.html)

Phase 5 completed the end-to-end trace from hardware interrupt to web browser:

  • WebSocket Server (server.py): Accepts raw binary Lux streams and broadcasts binary packets over ws://localhost:8765.
  • In-Browser Binary Decoder (index.html): Uses JavaScript DataView (prototype of @pyintel/lux-web) to parse 0x4C 0x58 binary headers directly in browser memory without server-side string conversion, driving a real-time Chart.js telemetry line graph.

Final Master Benchmark Comparison Across All Transports

Metric / FeaturePhase 1 (UART)Phase 2 (Wi-Fi UDP)Phase 3 (ESP-NOW Mesh)
Physical TransportCP210x USB-Serial (115.2k)802.11 Wi-Fi UDP BroadcastDirect 802.11 P2P Mesh
Infrastructure Req.Direct CableWi-Fi Access PointNone (Offline P2P)
Intra-burst Latency3.97 ± 2.93 ms0.00 ms (Batched)4.06 ± 2.96 ms
Packet Delivery Rate100.0% PDR (0 lost)90.3% PDR (6 lost)100.0% PDR (0 lost)
CRC Reliability Rate100.0% OK100.0% OK100.0% OK
Minimum esp_dt4 µs10 µs10 µs

Conclusion of Research Phase

All 5 core research goals are proven. We have empirical proof that Lux delivers sub-microsecond emission speed, zero heap memory tax, 100% data integrity, and complete transport independence across wired UART, Wi-Fi UDP sockets, and offline ESP-NOW meshes.

Next up: freezing the formal wire format spec (spec/wire-format.md) and porting the core engine to Rust no_std (lux-emb/rust) and C (lux-emb/c).


← Back to Pyintel Lux project page