Files
jimmyandCursor fea6dffa74 Add ArtNetDMX Pico W firmware with dual DMX and docs.
Art-Net to two RS-485 outputs over Wi-Fi (AP or STA with SoftAP fallback), web UI, mDNS, and QLC+/ArtPoll notes for unicast on STA.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-11 00:00:23 +12:00

119 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ArtNetDMX — Pico W Art-Net → Dual DMX
Firmware for **Raspberry Pi Pico W** that receives Art-Net over Wi‑Fi and outputs **two DMX512 universes** through RS‑485, using **PIO + DMA** at **40 Hz**. A web UI configures Wi‑Fi (STA / AP) and shows / sets all 512 channels per universe.
## Hardware
| Signal | Pico W | RS‑485 module |
|--------|--------|----------------|
| DMX A data | GP0 | DI (universe A) |
| DMX B data | GP1 | DI (universe B) |
| GND | GND | GND |
| Power | 3V3 or 5V | VCC (many MAX485 boards want 5V) |
TX‑only: tie **DE** and **/RE** high (to VCC) on each module. XLR pinout is typically 1=GND, 2=Data− (B), 3=Data+ (A) — match your module labels.
Pins are defined in [`include/board.h`](include/board.h).
```
Pico W GP0 ──► MAX485 A DI
Pico W GP1 ──► MAX485 B DI
Pico W GND ──► both module GND
VCC ──► both module VCC
DE,/RE ──► VCC (TX enable)
A/B ──► XLR / DMX cable
```
## Build
Requires [Pico SDK](https://github.com/raspberrypi/pico-sdk) and an ARM GCC toolchain.
```bash
export PICO_SDK_PATH=/path/to/pico-sdk
mkdir -p build && cd build
cmake -DPICO_BOARD=pico_w ..
make -j$(nproc)
```
Flash with BOOTSEL + drag-and-drop, or:
```bash
picotool load -f build/artnetdmx.uf2
```
USB serial (115200) prints boot status, Wi‑Fi mode, and IP addresses.
Do not `cp` the UF2 onto a path that is not the mounted `RPI-RP2` volume (a failed copy can leave a plain file instead of flashing).
## First boot (AP)
1. Join Wi‑Fi **ArtNetDMX** / password **artnetdmx**
2. Open **http://192.168.4.1/** (or **http://artnetdmx.local/** once mDNS is up)
3. **WiFi** page: choose mode, credentials, Art‑Net universe numbers, mDNS hostname
4. Save — device reboots
### Wi‑Fi modes
| Mode | Behaviour |
|------|-----------|
| **Access Point** | SoftAP only (default `ArtNetDMX` / `artnetdmx` @ `192.168.4.1`) |
| **Station** | Joins your LAN only. If join fails, SoftAP starts for recovery |
There is no concurrent AP+STA mode (legacy “AP+Station” configs are treated as Station). SoftAP is paused while STA obtains DHCP, then left off if join succeeds.
mDNS hostname defaults to **`artnetdmx`** → **http://artnetdmx.local/** (configurable on the WiFi page).
## Art-Net
- UDP port **6454**
- Replies to **ArtPoll** / sends **ArtPollReply** (QLC+ and similar discovery)
- Maps configured universes to physical ports A (GP0) and B (GP1)
- Defaults: universe **0** → A, universe **1** → B
### SoftAP vs Station (important)
| Mode | Art-Net transport |
|------|-------------------|
| **SoftAP** | Controller joins the Pico’s AP. **Broadcast** ArtDmx usually works. |
| **Station** | Pico and controller share a home/office AP. Many APs **drop Wi‑Fi broadcast**, so ArtDmx broadcast never arrives. Use **unicast** to the Pico’s STA IP. |
Unicast ArtDmx on STA has been verified end-to-end; subnet broadcast often is not delivered by the upstream AP.
### QLC+ setup
1. Put the Pico in **Station** mode and note its IP (web UI, serial, or mDNS).
2. **Inputs/Outputs** → Art-Net plugin.
3. You will typically see **two nodes**: **QLC+ itself** and **ArtNetDMX**. Select **ArtNetDMX** (not the QLC+ loopback node).
4. Set output to **unicast** → Pico STA IP (e.g. `10.1.1.190`), not broadcast and not `192.168.4.1` unless you are on SoftAP.
5. Enable the Art-Net **output** line (icon lit).
6. Map universes: **0** → DMX A, **1** → DMX B (or match the WiFi page).
7. Patch fixtures to those universes.
Confirm on **http://&lt;pico-ip&gt;/** (Channels): Art-Net packet count should rise and channel values should follow faders. If the web UI updates but fixtures do not, check RS‑485 wiring / DE·/RE / cabling.
## Web UI
- **Channels** — tabs for universe A/B; all 512 values; edit live; Clear / All 255
- **WiFi** — AP or Station, credentials, Art‑Net universes, mDNS hostname, live debug line
- Status strip: mode, IP, Art‑Net packet count, age since last packet per port
Manual channel edits drive the same buffers as Art‑Net; new Art‑Net packets overwrite those channels.
Embedded pages live in `src/http_server.c`. The `www/` tree is a reference copy of the HTML structure.
## Project layout
| Path | Role |
|------|------|
| `src/main.c` | Boot, DMX timer, poll loops |
| `src/wifi_mgr.c` | SoftAP / STA, DHCP, mDNS hooks |
| `src/artnet.c` | ArtDmx + ArtPoll/ArtPollReply |
| `src/dmx_out.c` + `.pio` | PIO + DMA DMX TX |
| `src/http_server.c` | Web UI + JSON API |
| `src/config.c` | Flash config (CRC, versioned) |
| `lwipopts.h` | lwIP tuning (UDP PCBs, SoftAP DHCP, broadcast) |
## License notes
DMX PIO timing is adapted from [jostlowe/Pico-DMX](https://github.com/jostlowe/Pico-DMX) (BSD‑3‑Clause). DHCP server is from MicroPython / pico‑examples (MIT).