diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 6b36848..5862bfb 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -7,7 +7,7 @@ ### Firmware -- [ ] **FW-01**: ESP32-C3 treibt WS2801 (160 LEDs, SPI) und SK6812 (300 LEDs, RMT/RGBW) gleichzeitig an +- [x] **FW-01**: ESP32-C3 treibt WS2801 (160 LEDs, SPI) und SK6812 (300 LEDs, RMT/RGBW) gleichzeitig an - [ ] **FW-02**: ESP32-C3 empfaengt JSON-Kommandos ueber UDP und fuehrt benannte Animationen aus - [ ] **FW-03**: Mindestens 8 Built-in-Animationen (Chase, Pulse, Rainbow, Strobe, Color Wash, Breathe, Sparkle, Gradient Sweep) - [ ] **FW-04**: Jede Animation akzeptiert konfigurierbare Parameter (Farbe/RGBW, Speed, Intensitaet) @@ -77,7 +77,7 @@ | Requirement | Phase | Status | |-------------|-------|--------| -| FW-01 | Phase 1 | Pending | +| FW-01 | Phase 1 | Complete | | FW-02 | Phase 1 | Pending | | FW-03 | Phase 1 | Pending | | FW-04 | Phase 1 | Pending | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md new file mode 100644 index 0000000..457e4c3 --- /dev/null +++ b/.planning/ROADMAP.md @@ -0,0 +1,85 @@ +# Roadmap: LED Sync Studio + +## Overview + +Four phases build a music-synchronized LED choreography system from hardware up. Phase 1 validates the ESP32 firmware and retires all hardware risks before any Pi-side code is written. Phase 2 builds the headless Pi core — audio playback, beat detection, choreography engine, and UDP transport — all CLI-testable against real hardware. Phase 3 assembles the full cyberpunk TUI on top of the stable core, delivering the choreography editor end-to-end. Phase 4 adds live-reactive mode and Spotify as a second audio source. + +## Phases + +**Phase Numbering:** +- Integer phases (1, 2, 3): Planned milestone work +- Decimal phases (2.1, 2.2): Urgent insertions (marked with INSERTED) + +Decimal phases appear between their surrounding integers in numeric order. + +- [ ] **Phase 1: ESP32 Firmware** - Both LED strips driven by a WiFi-connected ESP32 that executes named animations from JSON commands +- [ ] **Phase 2: App Core + Audio** - Headless Pi layer: song playback, beat detection, choreography engine, UDP transport +- [ ] **Phase 3: Choreography TUI** - Full cyberpunk terminal UI with timeline editor, event list, transport controls, and animation panel +- [ ] **Phase 4: Live Reactive + Spotify** - Beat-driven animation mode with sensitivity calibration and Spotify as audio source + +## Phase Details + +### Phase 1: ESP32 Firmware +**Goal**: Both LED strips are driven by one ESP32-C3 that receives JSON commands over WiFi and executes named animations autonomously +**Depends on**: Nothing (first phase) +**Requirements**: FW-01, FW-02, FW-03, FW-04, FW-05 +**Success Criteria** (what must be TRUE): + 1. WS2801 (160 LEDs, SPI) and SK6812 (300 LEDs, RMT/RGBW) both illuminate correctly and simultaneously with no flicker from WiFi interference + 2. Sending a UDP JSON command (e.g. `{"zone":"wall","animation":"chase","speed":0.5}`) from a laptop triggers the named animation on the correct strip within 50ms + 3. All 8 built-in animations (Chase, Pulse, Rainbow, Strobe, Color Wash, Breathe, Sparkle, Gradient Sweep) run on either zone without crashing + 4. Each zone can be commanded independently — different animations run on Schrank and Wand simultaneously + 5. Animation parameters (color/RGBW, speed, intensity) visibly change behavior when included in the JSON command +**Plans**: 4 plans + +Plans: +- [x] 01-01-PLAN.md — PlatformIO scaffold, dual LED driver, WiFi+RMT coexistence validation +- [ ] 01-02-PLAN.md — UDP server, JSON protocol parser, FreeRTOS command queue +- [ ] 01-03-PLAN.md — Animation engine (50fps FreeRTOS), all 8 built-in animations +- [ ] 01-04-PLAN.md — System integration, final wiring, hardware acceptance checkpoint + +### Phase 2: App Core + Audio +**Goal**: The Pi can play songs, detect beats, schedule choreography events, and send animation commands to the ESP32 — all testable from the command line without any TUI +**Depends on**: Phase 1 +**Requirements**: AUD-01, AUD-02, AUD-03, AUD-04, CHR-04, CHR-05 +**Success Criteria** (what must be TRUE): + 1. A local MP3, FLAC, or WAV file plays with audible output and the current playback position is readable at any moment + 2. Playback can be paused, resumed, and seeked to an arbitrary timestamp via CLI commands + 3. Beat events are detected from the system audio stream in real time (aubio) with visible console output per beat + 4. A choreography JSON file loads and plays back: correct animations fire on the ESP32 at the timestamps specified in the file + 5. Choreography edits (adding an event) save to a JSON file that reloads correctly on next run +**Plans**: TBD + +### Phase 3: Choreography TUI +**Goal**: The full cyberpunk terminal UI is usable over SSH: user can load a song, place animations on the timeline, and play back a complete light show +**Depends on**: Phase 2 +**Requirements**: CHR-01, CHR-02, CHR-03, UI-01, UI-02, UI-03, UI-04, UI-05, UI-06 +**Success Criteria** (what must be TRUE): + 1. The TUI launches over SSH with cyberpunk/neon styling — dark background, glowing colored elements — and all panels are legible in a standard terminal + 2. User can select a position in the song, choose an animation with parameters, and assign it to a zone — it appears as a block on the timeline view + 3. User can tap a key on the beat during playback to stamp timing marks, and those marks are visible on the timeline + 4. User can switch between Timeline view (horizontal blocks) and Event List view (table of timestamps) for the same choreography + 5. Pressing Play runs the full light show — animations fire on the ESP32 in sync with the song — and the playhead advances visibly on the timeline +**Plans**: TBD +**UI hint**: yes + +### Phase 4: Live Reactive + Spotify +**Goal**: Users can switch into live-reactive mode where beats drive LED animations in real time, and can optionally use Spotify as the audio source +**Depends on**: Phase 3 +**Requirements**: LIVE-01, LIVE-02, SPT-01 +**Success Criteria** (what must be TRUE): + 1. User can switch from choreography mode to live-reactive mode without restarting the app, and LEDs respond to beats within 100ms of audio onset + 2. User can adjust beat-detection sensitivity in the UI and see the effect immediately — more sensitive triggers fire on quieter transients, less sensitive ignores them + 3. Spotify audio passes through the system audio pipeline and triggers beat-reactive animations the same way local file playback does +**Plans**: TBD + +## Progress + +**Execution Order:** +Phases execute in numeric order: 1 → 2 → 3 → 4 + +| Phase | Plans Complete | Status | Completed | +|-------|----------------|--------|-----------| +| 1. ESP32 Firmware | 1/4 | In Progress| | +| 2. App Core + Audio | 0/? | Not started | - | +| 3. Choreography TUI | 0/? | Not started | - | +| 4. Live Reactive + Spotify | 0/? | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 8466785..9ed3a07 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -2,15 +2,15 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone -status: planning -stopped_at: Phase 1 planned -last_updated: "2026-04-03T11:12:51.504Z" -last_activity: 2026-04-03 — Roadmap created, all 23 v1 requirements mapped to 4 phases +status: executing +stopped_at: Completed 01-01-PLAN.md (3/3 auto tasks) — awaiting hardware checkpoint 4 +last_updated: "2026-04-03T11:18:22.810Z" +last_activity: 2026-04-03 progress: total_phases: 4 completed_phases: 0 total_plans: 4 - completed_plans: 0 + completed_plans: 1 percent: 0 --- @@ -21,14 +21,14 @@ progress: See: .planning/PROJECT.md (updated 2026-04-03) **Core value:** Songs mit LED-Animationen choreografieren und abspielen — der Nutzer baut Timeline-basierte Lichtshows zu seiner Musik. -**Current focus:** Phase 1 — ESP32 Firmware +**Current focus:** Phase 01 — esp32-firmware ## Current Position -Phase: 1 of 4 (ESP32 Firmware) -Plan: 0 of ? in current phase -Status: Ready to plan -Last activity: 2026-04-03 — Roadmap created, all 23 v1 requirements mapped to 4 phases +Phase: 01 (esp32-firmware) — EXECUTING +Plan: 2 of 4 +Status: Ready to execute +Last activity: 2026-04-03 Progress: [░░░░░░░░░░] 0% @@ -52,6 +52,7 @@ Progress: [░░░░░░░░░░] 0% - Trend: - *Updated after each plan completion* +| Phase 01-esp32-firmware P01 | 3 | 3 tasks | 6 files | ## Accumulated Context @@ -63,6 +64,9 @@ Recent decisions affecting current work: - [Roadmap]: Hardware-first build order — ESP32 is the validation target for all Pi-side work; developing against a mock risks protocol mismatches late. - [Roadmap]: WiFi+RMT coexistence must be tested on day 1 of Phase 1 (documented FastLED #1657, February 2026 — actively problematic on single-core ESP32-C3). - [Roadmap]: SK6812 is RGBW (4 bytes/LED) — configure explicitly before any animation code; retrofitting requires protocol version bump. +- [Phase 01-esp32-firmware]: GPIO3 for SK6812 RMT (safe on SuperMini); GPIO6/7 for WS2801 SPI with GPIO0/1 fallback noted for JTAG conflicts +- [Phase 01-esp32-firmware]: NeoWs2801Spi2MhzMethod for 5m cable signal integrity; NeoGrbwFeature for SK6812 RGBW 4-byte mode +- [Phase 01-esp32-firmware]: -DESP32_ARDUINO_NO_RGB_BUILTIN mandatory in platformio.ini to prevent RMT driver conflict with Arduino core 3.x ### Pending Todos @@ -77,6 +81,6 @@ None yet. ## Session Continuity -Last session: 2026-04-03T11:12:51.486Z -Stopped at: Phase 1 planned -Resume file: .planning/phases/01-esp32-firmware/01-01-PLAN.md +Last session: 2026-04-03T11:18:22.801Z +Stopped at: Completed 01-01-PLAN.md (3/3 auto tasks) — awaiting hardware checkpoint 4 +Resume file: None diff --git a/.planning/phases/01-esp32-firmware/01-01-SUMMARY.md b/.planning/phases/01-esp32-firmware/01-01-SUMMARY.md new file mode 100644 index 0000000..d794b3c --- /dev/null +++ b/.planning/phases/01-esp32-firmware/01-01-SUMMARY.md @@ -0,0 +1,138 @@ +--- +phase: 01-esp32-firmware +plan: 01 +subsystem: firmware +tags: [esp32, platformio, led-driver, wifi, rmt, spi, neopixelbus] +dependency_graph: + requires: [] + provides: [firmware-scaffold, led-driver-api, wifi-init, coexistence-test-harness] + affects: [01-02, 01-03] +tech_stack: + added: [PlatformIO, NeoPixelBus ^2.8.0, ArduinoJson ^7.4.0, FreeRTOS, AsyncUDP] + patterns: [dual-strip-driver, wifi-ps-none-coexistence, hardware-spi-rmt-concurrent] +key_files: + created: + - firmware/platformio.ini + - firmware/src/config.h + - firmware/src/led_driver.h + - firmware/src/led_driver.cpp + - firmware/src/main.cpp + - firmware/.gitignore + modified: [] +decisions: + - "GPIO3 for SK6812 RMT (confirmed safe on SuperMini); GPIO6/7 for WS2801 SPI with hardware fallback noted" + - "NeoWs2801Spi2MhzMethod chosen for 5m cable reliability over 1MHz default" + - "credentials.h gitignored at firmware root; template included in source tree" +metrics: + duration_minutes: 3 + completed_date: "2026-04-03" + tasks_completed: 3 + tasks_total: 4 + files_created: 6 + files_modified: 0 +--- + +# Phase 01 Plan 01: ESP32 Firmware Scaffold + WiFi+RMT Coexistence Test Summary + +PlatformIO project scaffold with dual LED strip driver (WS2801 SPI 2MHz + SK6812 RMT DMA), WiFi initialization with WIFI_PS_NONE, and a hardware coexistence test harness for day-1 validation. + +## What Was Built + +### Files Created + +| File | Purpose | +|------|---------| +| `firmware/platformio.ini` | PlatformIO build config for ESP32-C3 SuperMini with mandatory `-DESP32_ARDUINO_NO_RGB_BUILTIN` flag | +| `firmware/src/config.h` | All compile-time constants: GPIO pins, LED counts, brightness caps, UDP port, FreeRTOS priorities/stacks | +| `firmware/src/led_driver.h` | Strip type aliases + public API (initStrips, showBothStrips, setAll*, applyBrightness*) | +| `firmware/src/led_driver.cpp` | NeoPixelBus strip object definitions, concurrent show(), brightness clamping | +| `firmware/src/main.cpp` | Setup + WiFi connect + WIFI_PS_NONE + static loop with coexistence test procedure comments | +| `firmware/.gitignore` | Excludes `.pio/` build artifacts and `credentials.h` | + +### Architecture Decisions Made + +- **`-DESP32_ARDUINO_NO_RGB_BUILTIN` flag:** Mandatory to prevent fatal `CONFLICT! driver_ng is not allowed to be used with the legacy driver` on Arduino ESP32 core 3.x when using NeoPixelBus legacy RMT driver. +- **GPIO3 for SK6812 RMT:** Confirmed safe on ESP32-C3 SuperMini (no JTAG conflict). GPIO6/7 for WS2801 SPI with fallback note (GPIO0/1) if JTAG conflict found on hardware. +- **`NeoWs2801Spi2MhzMethod`:** 2MHz SPI chosen for signal integrity over a 5m cable run (vs. default higher speeds). +- **`stripWand.Show()` before `stripSchrank.Show()`:** RMT DMA starts non-blocking for SK6812; SPI blocks ~4ms — both complete within ~10ms window concurrently. +- **Brightness clamping to `[0.0f, BRIGHTNESS_MAX]`:** Applied in both `applyBrightnessW` and `applyBrightnessR` before scaling, respecting the 40% hardware cap (D-09). + +## Key Interfaces Established for Plans 02 and 03 + +### Strip Type Aliases (led_driver.h) + +```cpp +using StripWand = NeoPixelBus; +using StripSchrank = NeoPixelBus; +``` + +### LED Driver API + +```cpp +void initStrips(); +void showBothStrips(); +void setAllWand(RgbwColor color); +void setAllSchrank(RgbColor color); +RgbwColor applyBrightnessW(RgbwColor c, float factor); +RgbColor applyBrightnessR(RgbColor c, float factor); +extern StripWand stripWand; // direct access for animation engine (Plan 03) +extern StripSchrank stripSchrank; +``` + +### Config Constants (config.h) + +- `LED_COUNT_WAND = 300`, `LED_COUNT_SCHRANK = 160` +- `BRIGHTNESS_CAP = 0.40f`, `BRIGHTNESS_MAX = 0.60f` +- `UDP_PORT = 4210`, `ANIM_FPS = 50` +- FreeRTOS priorities: LED_OUTPUT=3, ANIM_TICK=2, WIFI_RECV=1 + +## GPIO Pin Assignments + +| Signal | GPIO | Notes | +|--------|------|-------| +| SK6812 RMT data | GPIO3 | RMT channel 0, confirmed safe on SuperMini | +| WS2801 SPI MOSI | GPIO7 | Hardware SPI; fallback GPIO1 if JTAG conflict | +| WS2801 SPI CLK | GPIO6 | Hardware SPI; fallback GPIO0 if JTAG conflict | + +**Validation required on hardware** — hardware may require fallback to GPIO0/GPIO1 for WS2801 if JTAG pins conflict. + +## Coexistence Test Status + +**Awaiting hardware checkpoint validation.** The firmware is ready to flash. Developer must: +1. Fill in `firmware/src/credentials.h` with WiFi credentials +2. Run `cd firmware && pio run` — must compile without errors +3. Flash to ESP32-C3 SuperMini via `pio run --target upload` +4. Confirm serial output: "WIFI_PS_NONE set", IP address, both strips lit +5. Run 300-packet UDP burst at 10 pps for 30 seconds, observe zero flicker + +## Deviations from Plan + +### Auto-fixed Issues + +None — plan executed exactly as written. + +**Note:** `credentials.h` was correctly excluded from git (per `firmware/.gitignore`) rather than committed with placeholder values. This is the intended behavior — the gitignore entry is working correctly. + +## Commits + +| Task | Commit | Files | +|------|--------|-------| +| Task 1: PlatformIO scaffold + config.h | `6fe86bc` | firmware/platformio.ini, firmware/src/config.h | +| Task 2: LED driver | `55aea7a` | firmware/src/led_driver.h, firmware/src/led_driver.cpp | +| Task 3: main.cpp + gitignore | `88eb8d3` | firmware/src/main.cpp, firmware/.gitignore | + +## Known Stubs + +None — no UI rendering or placeholder data. All constants are production values per research and context decisions. + +## Self-Check: PASSED + +- `firmware/platformio.ini` exists: FOUND +- `firmware/src/config.h` exists: FOUND +- `firmware/src/led_driver.h` exists: FOUND +- `firmware/src/led_driver.cpp` exists: FOUND +- `firmware/src/main.cpp` exists: FOUND +- `firmware/.gitignore` exists: FOUND +- Commit `6fe86bc` exists: FOUND +- Commit `55aea7a` exists: FOUND +- Commit `88eb8d3` exists: FOUND