festifun/plan/lane-K-badges.md
type-two 56e569fd7a Plan: Phase 6 spec + directives round 6 (M18-M24 Friend Tracks, lanes H/J/K)
Markers/badges -> detection -> cross-view triangulation -> track ribbons +
follow-a-friend + LED badge hardware kit. Coordinator-merges policy this phase.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 18:28:21 +10:00

2.8 KiB

Lane K — LED badges & bench kit (M23 firmware+docs, M24 self-test)

You build the wearable side: badge firmware speaking the frozen blink protocol, the hardware guide, and the bench self-test John runs before a shoot. Spec: 30-phase6.md M23/M24 + contract #4. Branch lane/k-badges, own worktree.

M23 — firmware + docs, the parts that bite

  • Contract #4 is FROZEN: 133 ms bit, 11100 preamble + 6-bit ID + even parity, continuous repeat, ID 63 = sync beacon. Keep the constants in ONE header (hardware/badge/protocol.h) shared by badge.ino and beacon.ino; document the manual-sync rule with tracker_detect.py's decoder constants (can't import across languages — state both locations in the header comment and in docs/hardware.md).
  • badge.ino: plain Arduino APIs (millis()-paced, no delay()-drift), single bright LED on a PWM pin OR a WS2812 (compile-time #define), ID set by #define (document per-badge flashing). Hardware is never ideal on paper: expose a BIT_TRIM_US calibration knob for clock drift.
  • beacon.ino: ID 63, double LED brightness/size guidance.
  • docs/hardware.md: parts list with rough prices (ESP32 dev board / ATtiny85, LED + resistor or WS2812, LiPo/coin cell, diffuser ping-pong ball), wiring, flashing (arduino-cli commands), wearing guidance (chest/hat, diffusion, one badge per person, ≥24 fps cameras, exposure caveat: blown-out video kills OOK contrast).
  • Compile check: arduino-cli compile --fqbn esp32:esp32:esp32 (and attiny if the core is installable). If arduino-cli isn't available in your environment, document the exact commands and mark the box unverified — do NOT claim compiled without output.

M24 — bench self-test, the parts that bite

  • scripts/badge_selftest.py must run lane H's REAL decoder (tracker_detect blink path) — import it, don't re-implement; if lane H hasn't merged yet, code against the frozen contract #3/#4 shapes and mark the integration box pending (integration3 re-runs it).
  • --synthetic mode: render a small blinking clip using the fixture's marker-rendering helpers (foundation3 exposes them in synthetic.py) and assert the ID round-trips.
  • Clear, John-readable failure messages: no blob found / decoded wrong ID / clip too short (< 1 word). Exit codes: 0 ok, 1 decode-fail, 2 usage.

Acceptance (evidence in plan/status/lane-K.md)

  • protocol.h constants byte-identical to contract #4; badge + beacon sketches compile (output pasted) or compile commands documented + marked unverified
  • docs/hardware.md complete enough that John can order parts from it
  • uv run python scripts/badge_selftest.py --synthetic decodes the rendered ID (test_badge_selftest.py covers it); failure paths print actionable text
  • Backend suite green; npm untouched