Files

3.0 KiB

phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics
phase plan subsystem tags dependency_graph tech_stack key_files decisions metrics
07 03 firmware
firmware
micropython
frame-mode
drgb
drgbw
dnrgb
udp
requires provides affects
07-01
07-02
firmware/protocol.py#FrameAssembler
firmware/main.py#frame-mode
lightsync/protocol/drgb.py
added patterns
DNRGB multi-packet reassembly
frame timeout with animation fallback
created modified
tests/test_firmware_frames.py
firmware/protocol.py
firmware/main.py
Frame timeout (2s) reverts to last animation, not idle — matches WLED behavior
frame_is_rgbw flag routes DRGB/DNRGB to write_rgb, DRGBW to write_rgbw
FrameAssembler keyed by absolute pixel index (start_index + i) — tolerates out-of-order chunks
duration completed tasks_completed files_changed
2 minutes 2026-04-07 3 3

Phase 7 Plan 3: Frame Mode Renderer Summary

One-liner: DRGB/DRGBW/DNRGB raw frame handling with FrameAssembler multi-packet reassembly and 2s animation fallback timeout.

What Was Built

Added raw frame mode to the firmware. The device now receives pixel data from the server and writes it directly to the LED strip, supporting three packet types:

  • DRGB (0x02): 3 bytes/pixel RGB, up to 490 pixels per packet — routed to strip.write_rgb()
  • DRGBW (0x03): 4 bytes/pixel RGBW, up to 367 pixels per packet — routed to strip.write_rgbw()
  • DNRGB (0x04): chunked RGB with start_index for large strips — reassembled by FrameAssembler, then routed to strip.write_rgb()

Frame mode takes priority over animation mode. When no frame packet arrives for 2 seconds, the firmware reverts to the last animation command.

Tasks Completed

Task Description Commit Files
1 Add FrameAssembler to firmware/protocol.py d14fa3c firmware/protocol.py
2 Replace firmware/main.py with frame mode version 2a22eef firmware/main.py
3 Create tests/test_firmware_frames.py (19 tests) ec97600 tests/test_firmware_frames.py

Verification

  • uv run pytest tests/test_firmware_frames.py -v — 19 passed in 0.11s
  • firmware/protocol.py contains FrameAssembler with feed(), reset(), 200ms timeout
  • firmware/main.py handles DRGB (write_rgb), DRGBW (write_rgbw), DNRGB (via FrameAssembler)
  • Frame timeout (2s) reverts to last animation command mode
  • DNRGB 600-LED multi-packet frame: 2 packets (489 + 111 LEDs) round-trip passes
  • 300-LED DRGB = 902 bytes, DRGBW = 1202 bytes — both fit in single UDP packet
  • FrameAssembler clears stale partial frames after 200ms timeout

Deviations from Plan

None — plan executed exactly as written.

Known Stubs

None — all frame handling is fully wired.

Self-Check: PASSED

  • firmware/protocol.py exists with FrameAssembler: FOUND
  • firmware/main.py exists with frame mode: FOUND
  • tests/test_firmware_frames.py exists: FOUND
  • Commits d14fa3c, 2a22eef, ec97600: FOUND