auto-dj-arduino-switch
Arduino Giga R1 + WIZnet W5500 that automatically logs auto DJ tracks into a college radio station's copyright flowsheet over HTTPS.
Why a College Radio Station Is Replacing Wi-Fi with W5500 — Auto DJ Arduino Switch
In One Sentence
"An Arduino + W5500 system that automatically logs every track played by the auto DJ into the station's copyright flowsheet — so no one has to do it manually."
WXYC (89.3 FM), the student-run radio station at the University of North Carolina at Chapel Hill, put an Arduino into its live broadcast infrastructure. When no DJ is on air, the auto DJ software plays music automatically — but those tracks weren't being logged. The Arduino detects when the auto DJ is active via a relay contact on the mixing board, polls for the currently playing track, and writes each entry into the station's flowsheet (playback log).
It started on Wi-Fi. Three real-world problems pushed the project toward Arduino Ethernet Shield Rev2 (WIZnet W5500) as the primary transport.
Background
What is a flowsheet? A radio station's playback log. Stations are required to record what was played and when, for copyright reporting and broadcast history. Live DJs log entries manually — but when the auto DJ is running with no one logged in, those tracks go unrecorded. This device fills that gap.
What is AzuraCast? Open-source web radio management software. It runs the auto DJ and exposes currently-playing track data via a REST API and a real-time Centrifugo WebSocket.
The Three Wi-Fi Problems
Problem 1: The campus Wi-Fi password changes every year
UNC rotates its Wi-Fi password (UNC-PSK) annually. When Wi-Fi is the only network transport, a password change takes the device offline — and someone has to physically walk to the studio, connect via USB, and reflash the firmware to restore it.
[Wi-Fi only]
UNC rotates password → Arduino loses Wi-Fi → no network → physical visit required
[After W5500]
UNC rotates password → Wi-Fi fallback breaks → Ethernet stays up
→ push new password over Ethernet → Wi-Fi restored
Problem 2: Wi-Fi reconnection blocks for up to 36 seconds
This is a known firmware bug in the Arduino Giga R1. When the Wi-Fi connection drops, WiFi.begin() blocks execution for up to 36 seconds while attempting to reconnect. During that window, the state machine is completely frozen — any track changes that happen go unlogged.
The README's Known Limitations section states this explicitly:
"WiFi reconnection blocks for ~36 seconds (known Giga R1 firmware limitation). During this time, the state machine is frozen."
The W5500 has a hardwired TCP/IP stack. With an Ethernet cable plugged in, reconnection is near-instant and non-blocking.
Problem 3: A WiFiSSLClient crash bug forces a structurally limiting workaround
Using a global WiFiSSLClient object crashes the Giga R1. The current code works around this by creating a new WiFiSSLClient for every HTTP request and destroying it immediately after.
// Current workaround — create and destroy on every request
case AUTO_DJ_ACTIVE:
if (...) {
WiFiSSLClient ssl; // created here
inputs.pollNewTrack = azuracast.poll(ssl);
// ssl destroyed here
}
This makes persistent WebSocket connections impossible over Wi-Fi. AzuraCast supports real-time push via Centrifugo WebSocket, but the current Wi-Fi transport can't use it — so the device is stuck polling every 20 seconds. With W5500, a persistent WebSocket connection becomes viable and track changes can be detected in real time.
What's Running Today
The W5500 Ethernet code hasn't been implemented yet, but the Wi-Fi-based core logic is fully operational.
Flow:
Mixing board AUX relay closes (D2 LOW)
↓
STARTING_SHOW: POST to tubafrenzy to open a new show
↓
AUTO_DJ_ACTIVE: poll AzuraCast every 20s (HTTPS GET)
↓ new track detected
Add flowsheet entry (HTTPS POST)
↓
Relay opens → ENDING_SHOW: close the show
All state transition logic lives in a pure function — tick(Context, Inputs) → TickResult — with no I/O or side effects. This makes the entire decision logic testable on desktop without any hardware. 82 GoogleTest tests run on every push via GitHub Actions CI.
| Module | Tests |
|---|---|
| state_machine (pure transition logic) | 32 |
| utils (URL encoding, time calculations) | 19 |
| relay_monitor (debouncing) | 12 |
| flowsheet_client (HTTP POST) | 10 |
| azuracast_client (HTTP GET + JSON parsing) | 9 |
What Changes After the W5500 Switch
The planned architecture is fully documented in networking-spec.md:
| Current (Wi-Fi) | After W5500 | |
|---|---|---|
| Track detection | Poll AzuraCast every 20s | Real-time push via Centrifugo WebSocket |
| Management channel | None | Persistent WebSocket (remote monitoring, commands) |
| Credential rotation | Physical visit required | Push over Ethernet remotely |
| Reconnection delay | Up to 36s blocking | Near-instant |
| Wi-Fi | Primary transport | Fallback only |
Tech Stack
| Component | Details |
|---|---|
| MCU | Arduino Giga R1 WiFi (STM32H747, Cortex-M7 480MHz) |
| Ethernet | WIZnet W5500 (Arduino Ethernet Shield Rev2) |
| Firmware | C++ (Arduino / Mbed OS) |
| External APIs | AzuraCast Now Playing API, tubafrenzy Flowsheet API |
| Testing | 82 GoogleTest cases, desktop CI, no hardware required |
FAQ
Q. The Ethernet code isn't implemented yet — why was the hardware added first? A. The 3D-printed enclosure was designed with cutouts for the Ethernet Shield Rev2's RJ45 port and SD card slot from the start. Hardware preparation and software implementation are running in parallel.
Q. Why keep Wi-Fi at all instead of dropping it entirely? A. As a fallback for when the Ethernet cable is unplugged or the campus wired port goes down. As long as at least one transport is up, broadcast logging continues. The only scenario that requires physical intervention is both transports failing simultaneously.
Q. Why is the state machine a pure function? A. To make the entire transition logic testable on desktop without hardware. The tick(Context, Inputs) → TickResult structure lets 32 state machine tests run in CI with no Arduino attached. Separating I/O from logic is the core design principle of the project.
Project Links
- GitHub: https://github.com/WXYC/auto-dj-arduino-switch
- Station: WXYC 89.3 FM (UNC Chapel Hill)
- Hardware: Arduino Giga R1 WiFi + Arduino Ethernet Shield Rev2 (WIZnet W5500)
