Here is the updated, rigorous implementation plan. It is divided into two main parts: Phase A (Hardware Validation) and Phase B (System Implementation).
This plan is designed to be fed directly to an AI coding agent or followed by a firmware engineer.
Objective: Verify that every physical component is soldered correctly and functioning before writing complex system logic. Hardware Target: Seeed Studio XIAO ESP32-S3 (Custom Pinout).
- Goal: Verify the board boots and the Status LED (D6) works.
- Complexity: Extremely Low.
- Procedure:
- Write a simple
blinksketch using pinD6(GPIO 43). - Flash to the XIAO.
- Write a simple
- Success Criteria: The Red LED blinks at 1Hz.
- Goal: Verify the LED wiring, power stability, and level shifting (if applicable).
- Complexity: Low.
- Procedure:
- Install
FastLEDorAdafruit_NeoPixel. - Configure for Pin
D3(GPIO 4). - Set brightness to 50% (to test battery load safely).
- Run a "Cyclon" or "Rainbow" animation.
- Install
- Success Criteria: All pixels light up with correct colors. No flickering or "glitching" at the end of the strip.
- Goal: Verify the voltage divider on Pin
D4(GPIO 5) is reading correctly. - Complexity: Low.
- Procedure:
- Read
analogRead(5). - Apply formula:
voltage = (raw_value / 4095.0) * 3.3 * 2.0. - Print voltage to Serial Monitor every second.
- Read
- Success Criteria: Serial monitor shows ~3.7V - 4.2V (match with a multimeter to calibrate the
2.0multiplier if needed).
- Goal: Verify SPI wiring and SD card mount.
- Complexity: Medium.
- Procedure:
- Use the
SDlibrary. - Configure SPI pins explicitly:
SCK=7, MISO=8, MOSI=9, CS=44. - Attempt
SD.begin(44). - List all files on the card to Serial.
- Create a text file, write "test", read it back.
- Use the
- Success Criteria: Serial prints "SD Card Mount: Success" and lists files.
- Goal: Verify MAX98357A wiring and I2S bus.
- Complexity: High (requires I2S generator).
- Procedure:
- Use
ESP8266Audiolibrary (works on ESP32) or a simple I2S sine wave generator. - Configure I2S Pins:
BCLK=1, LRC=2, DIN=3. - Generate a 440Hz Sine Wave tone via I2S.
- Use
- Success Criteria: A clean, loud tone plays from the speaker. (If it sounds like static, check BCLK/LRC wiring order).
- Goal: Verify the button on D5 (GPIO 6) works.
- Complexity: Low.
- Procedure:
- Set Pin 6 to
INPUT_PULLUP. - Loop: Print "Pressed" when digitalRead is LOW.
- Set Pin 6 to
- Success Criteria: Serial prints "Pressed" only when you hold the button.
Objective: Build the firmware that combines these components into a synchronized swarm.
- Task: Connect to Wi-Fi and report status.
- Logic:
- Boot up.
- Connect to Hardcoded Wi-Fi credentials.
- Start UDP Listener on Port
4444(Command). - Start Heartbeat Loop: Send JSON to Server Port
5555every 1s (jittered). - Payload:
{"id": "mac_address", "bat": 4.10, "state": "IDLE"}.
- Verification: Server console shows incoming JSON from the device.
- Task: Get all nodes on the same clock.
- Logic:
- Implement
NTPClient(pool.ntp.org or local server). - Sync every 60 seconds.
- Add
timestampto the Heartbeat JSON.
- Implement
- Verification: Two devices output their time to Serial; they must match within ~10-50ms.
- Task: Play files from SD card via I2S.
- Logic:
- Integrate
ESP8266Audiolibrary (specificallyAudioFileSourceSDandAudioOutputI2S). - Create a function
playTrack(filename). - Ensure this runs on Core 1 (pinned task) to avoid Wi-Fi stutter.
- Integrate
- Verification: Hardcode a track to play on boot. Ensure music plays clearly.
- Task: Make LEDs react to audio.
- Logic:
- Implement the "Envelope Follower" (Attack/Release/Gain) struct.
- In the Audio Loop (Core 1), intercept the audio buffer.
- Calculate RMS (Root Mean Square).
- Update LED brightness based on the Envelope settings.
- Verification: Play music; LEDs pulse in time with the beat.
- Task: Execute the "Play at Time X" command.
- Logic:
- Receive UDP:
{"cmd": "PLAY", "file": "/track.mp3", "time": 1715005000}. - Check
current_ntp_time. - Calculate
delay_ms = target_time - current_ntp_time. - Wait
delay_ms. - Start Audio Task.
- Receive UDP:
- Verification: Send command. Device waits, then starts exactly at the target second.
- Task: Update content remotely.
- Logic:
- Receive UDP:
{"cmd": "DOWNLOAD", "url": "http://server/file.mp3"}. - Stop Audio/LEDs (Pause Task).
- Initialize
HTTPClient. - Stream data from URL to SD Card file path.
- Send Heartbeat
{"state": "DOWNLOADING", "progress": 50}. - On finish,
SD.close()and return to IDLE.
- Receive UDP:
- Verification: Upload a file to the server, trigger download, verify file exists on SD card and plays correctly.