I wanted to drive stage lights from software I had written. I had a USB-DMX interface that worked with nothing but the manufacturer’s own program.
First I had to understand the protocol. Learning DMX512 took less time than expected — because there is almost nothing to learn.
That is the entire protocol
BREAK line low for ≥ 88 µs "a new frame starts"
MAB line high for ≥ 8 µs "stand by"
START CODE 1 byte, 0x00 "this is dimmer data"
CHANNEL 1 1 byte (0–255)
…
CHANNEL 512 1 byte
That is all. The controller sends this frame forty-odd times a second, continuously. Fixtures listen to the wire, read however many channels they use starting from their address, and ignore the rest.
No checksum. No acknowledgement. No retransmission. No device discovery. No address conflict detection. No error reporting. No return channel — a fixture cannot tell the controller anything, not even whether it is lit.
Why it is this primitive, and why it survives
At first these look like flaws. The more I thought about it the more they inverted.
If a concert’s controller and fixtures shook hands, one unresponsive device would make the controller wait. While it waited, the other 40 lights would freeze.
In DMX, if a fixture drops, only that fixture drops. The wire keeps flowing. Plug a new device in and it joins on the next frame — no setup, no discovery, no delay.
And every frame carries the complete state, not a delta. Lose a frame and the next one 23 milliseconds later repairs it. Loss heals itself.
A protocol whose reliability comes not from error checking but from repeating the state forever.
Getting the device to speak
I understood the protocol; the interface was the problem. The device enumerated but Windows did not see it as any known class — it declared its own and expected its own driver.
Two options: use the manufacturer’s closed SDK, or talk to the device directly. I chose the second. I replaced its driver with a generic USB driver so I could write raw data with the operating system out of the way.
1. read the device descriptors → which endpoint, what type?
2. found the bulk OUT endpoint
3. write 513 bytes: [0x00] + 512 channels
4. keep the loop at 44 Hz
On the third attempt the lights came on.
Right after plugging in, the device swallowed the first frames. The reason: its internal circuitry takes a few hundred milliseconds to be ready. The fix is to send all-zero frames for the first second — it wakes the device and stops attached fixtures sitting in their previous state.
A device saying “powered” and being “ready” are not the same instant.
The most tedious part: which channel does what
Decoding the protocol took a day. The real work was this: on the fixtures I had, which channel controls what?
Manuals are missing, wrong, or belong to a different model. The only reliable method is measurement: drive one channel slowly from 0 to 255 and watch the light.
| channel | measured result |
|---|---|
| ch1–ch4 | pan / tilt (coarse + fine) |
| ch5 | colour wheel — discrete steps, no intermediate values |
| ch6 | gobo; a “shake” range between 200–230 |
| ch9–ch12 | dead — no effect at all |
| ch13–ch15 | must be held at zero: leave them populated and the fixture’s built-in program takes over |
That last row cost me two evenings. The light was dancing on its own and I was looking for a bug in the values I was sending. There was no bug in what I sent — it was in what I did not send.
Leaving a channel empty does not make it zero; it depends on what the device finds there.
And the truth about the lenses
On a multi-arm effect fixture I had assumed each arm could produce intermediate colours. I measured: the lenses cannot blend. Each arm can only be red, green, blue or white.
That is a constraint. But building the choreography on top of it produced a better result: sharp, stable colours instead of a muddy image imitating in-between tones. Use what the hardware can do rather than forcing what it cannot — the same rule in lighting and in software.
What I learned
A forty-year-old protocol survives because it asked the right question forty years ago: what does a lighting controller actually need?
The answer: to repeat the state, continuously. Everything else — handshakes, acknowledgements, discovery — is not a benefit on a stage. It is a risk.