Skip to content

Latest commit

 

History

History
114 lines (92 loc) · 5.77 KB

File metadata and controls

114 lines (92 loc) · 5.77 KB

Here is the architectural definition and implementation roadmap designed specifically for an Agentic AI system to execute.


Project Architecture: Synchronized Audio Swarm (UDP/NTP)

1. System Overview

Goal: Create a distributed audio system consisting of up to 32 battery-powered ESP32-S3 nodes. Core Function: Nodes must synchronize their internal clocks via NTP and execute audio playback triggers received via UDP broadcast with perceptual synchronization (<50ms variance). Telemetry: Nodes provide real-time status updates (Heartbeats) to a central Node.js server for visualization.

2. Hardware Specification

  • MCU: ESP32-S3-WROOM (Dual Core, 240MHz).
  • Audio Output: MAX98357A I2S Amplifier (connected via I2S).
  • Visual Output: WS2812B Addressable LEDs (Data Pin).
  • Power: 3.7V LiPo Battery (Monitored via Voltage Divider on Analog Pin).
  • Network: 2.4GHz Wi-Fi (Private AP recommended).

3. Network Topology & Protocol

The system uses a Split-Port UDP Architecture to prevent congestion.

Channel Protocol Port Direction Frequency Payload Format
Command UDP Multicast 4444 Server $\rightarrow$ Swarm On Event JSON
Telemetry UDP Unicast 5555 Swarm $\rightarrow$ Server 1Hz (Jittered) JSON
Dashboard WebSocket N/A Server $\leftrightarrow$ Browser Real-time JSON

3.1 Data Structures

A. Command Payload (Server $\rightarrow$ Node)

{
  "cmd": "PLAY",             // Enum: "PLAY", "STOP", "LIGHTS", "REBOOT"
  "file": "/track01.mp3",    // File path in SPIFFS/LittleFS
  "timestamp": 1715005000,   // UNIX Epoch: Target Start Time (Future)
  "vol": 0.8                 // 0.0 to 1.0
}

B. Telemetry Payload (Node $\rightarrow$ Server)

{
  "id": "node_01",           // Unique MAC-based or Hardcoded ID
  "state": "IDLE",           // Enum: "BOOT", "SYNCING", "IDLE", "ARMED", "PLAYING"
  "bat": 3.85,               // Battery Voltage (Float)
  "rssi": -62,               // WiFi Signal Strength (Int)
  "drift": 4                 // NTP Offset in ms (for debugging quality of sync)
}

4. Firmware Architecture (ESP32-S3)

To prevent audio glitches (starvation), the firmware utilizes FreeRTOS Task Pinning.

Core 0: Network & Logic Task

  • Responsibility: Wi-Fi stack, UDP listening, NTP synchronization, JSON parsing, Battery monitoring.
  • Heartbeat Logic: Sends Telemetry Payload every 1000ms. Crucial: Must add random(0, 200) ms delay to every heartbeat to mitigate packet collision (Thundering Herd).
  • Command Handling: Receives PLAY command. Calculates delay = target_timestamp - current_ntp_time. Sets a specific hardware timer or flags the Audio Task.

Core 1: Real-Time Task

  • Responsibility: MP3 Decoding, I2S DMA transfer, LED timing.
  • Audio Pipeline: Reads file from LittleFS $\rightarrow$ Decodes (MiniMP3 or ESP8266Audio lib) $\rightarrow$ Writes to I2S Buffer.
  • Trigger: Waits for signal from Core 0. Begins decoding exactly when the calculated delay expires.

5. Server Architecture (Node.js)

The server acts as a bridge between the UDP Swarm and the Web Frontend.

  • UDP Listener (dgram): Listens on Port 5555. Updates an in-memory DeviceMap.
  • Staleness Checker: A setInterval loop runs every 2000ms. If a device hasn't reported in >5000ms, status changes to OFFLINE.
  • Web Server (express + socket.io): Serves the dashboard. Pushes the DeviceMap to connected browsers @ 2Hz.
  • Command Broadcaster: When "PLAY" is clicked on UI, calculates T + 2000ms and broadcasts JSON packet to 255.255.255.255:4444.

Implementation Plan

Execute these phases sequentially. Do not proceed to the next phase until the verification step passes.

Phase 1: Network Foundation & Heartbeat

Task:

  1. Set up Node.js server to listen on UDP 5555 and print received packets.
  2. Write ESP32 firmware to connect to Wi-Fi.
  3. Implement JSON serialization (use ArduinoJson).
  4. Implement the Heartbeat loop on Core 0 (include the random jitter).
  5. Verification: Start 3-5 ESP32s. Ensure Server receives clean JSON streams from all distinct IDs without crashing.

Phase 2: Time Synchronization (NTP)

Task:

  1. Implement NTP client on ESP32 (use NTPClient or native sntp).
  2. Tune sync interval (Update every 15 seconds to minimize drift).
  3. Add drift or timestamp to the Heartbeat JSON.
  4. Verification: Output serial logs from two ESP32s side-by-side. Their reported UNIX timestamps must match within +/- 20ms.

Phase 3: Audio Pipeline (Core 1)

Task:

  1. Upload .mp3 files to ESP32 Flash (LittleFS).
  2. Implement I2S Audio Player on Core 1.
  3. Create an inter-task communication method (e.g., xTaskNotify or Queue).
  4. Verification: Hardcode the ESP32 to play a track on boot. Ensure audio is clear and does not stutter while Wi-Fi is connected.

Phase 4: The Scheduled Trigger

Task:

  1. Implement UDP Listening on ESP32 Port 4444.
  2. Implement Logic: if (cmd == PLAY).
  3. Calculate wait time: wait_ms = payload_time - current_ntp_time.
  4. Delay logic (using vTaskDelay or microsecond timer) then trigger Core 1 audio.
  5. Verification: Send a command from the server. Use a high-speed camera or audio recorder to verify two units start effectively simultaneously.

Phase 5: Dashboard & Bi-Directional UI

Task:

  1. Build HTML frontend with a Grid View of devices.
  2. Color code boxes based on state (Green=Playing, Red=Offline, Grey=Idle).
  3. Add "Master Play" button.
  4. Connect Backend DeviceMap to Frontend via Socket.io.
  5. Verification: Turn off an ESP32; ensure UI turns Red after 5 seconds. Click Play; ensure UI turns Green immediately as devices confirm "PLAYING" state.