The 16-outputs USB DMX interface based on the RP2040

1,820 views
Skip to first unread message

Jannis Achstetter

unread,
Feb 2, 2021, 2:39:29 PM2/2/21
to open-lighting
Hi all,

As you might have heard, the RaspberryPi Foundation has released their
own microcontroller (RP2040), including the development board dubbed
"Pico" that sells for $4:
https://www.raspberrypi.org/blog/raspberry-pi-silicon-pico-now-on-sale/.

When I read the specs and found out about the "Programmable IO" blocks,
I wanted to send DMX512 with it. Lots of DMX512 ;)

The result is an USB DMX interface that sends 16 universes in parallel.
And of course I wanted it to be controlled from OLA since that gives me
the possibilities to go from sACN to the RP2040-based interface (and all
the other goodies I don't need to tell you about).

The DMX-generation idea is taken from
https://web.archive.org/web/20190307175432/http://www.jonshouse.co.uk/rpidmx512.cgi:
A wavetable is generated by the CPU and then "clocked out" the GPIOs
pins by the PIO, 16 bits parallel at a time.

One of the requirements I had in mind is that it should work in QLC+ and
QLA without any changes to the existing software (at least with one
universe output) and ideally on Windows (which some of my friends
"still" use) and Linux.
The great thing about the RP2040 is that in contrast to many (all?)
ESP32-based boards, it doesn't have an USB-to-Serial chip with hardcoded
VENDOR and PRODUCT id. Instead, the USB stack is fully
software-controllable. And it supports host and device role. That means
that one is pretty free regarding the USB interface to the host.

Taking all this into account, I decided to mimic a "DMXControl Projects
e.V. Nodle U1" = "Digital Enlightment Interface USB DMX" = "Frank
Sievertsen FX5". They are based on the HID-protocol (as such, they work
driverless in Windows and Linux) and are supported out-of-the-box in
QLC+ and OLA (OLA uses libusb instead of the HID-driver). The protocol
does have its own limitations, but it can also be easily extended to
support more then one universe.
I decided against emulating an ENTTEC-based device, although they are
quite popular (including clones) since QLC+ usually supports them only
via libftdi and I fear that it might raise legal problems when the
dongle pretends to be a device including a FTDI chip.

The code is (of course) not 100% finished and polished but it works. In
addition to the HID interface, the USB devices provides a CDC ACM
"serial" interface that I currently use for debugging. However, that
could also be used to emulate a "serial" based interface protocol (maybe
even a new one with advanced features).

In theory, DMX IN or even RDM would be possible. The code to do UART TX
and UART RX using the RP2040's PIO-blocks is ready to be used:
https://github.com/raspberrypi/pico-examples/tree/master/pio/uart_rx
https://github.com/raspberrypi/pico-examples/tree/master/pio/uart_tx
I guess that implementing RDM would reduce the number of ports to 4. Or
8 with a good bit of additional code.

However, my personal interest is more into DMX sending and I don't have
access to RDM-capable fixtures to do some real life tests.

Enough talking, code for the Pico board is here:
https://github.com/kripton/pico-examples/tree/DMX16/dma/dmx16

Code/Branch for ola is here:
https://github.com/kripton/ola/tree/RP2040UsbDmx/plugins/usbdmx

It basically introduces multi-universe-sending for "all usbdmx" widgets.
It's not the cleanest change, but it works for a proof-of-concept.

TODO for the pico code is to use one GPIO PIN to drive WS2812 LEDs for
status (USB interface activity, Universe X != all zero, ...)

Of course, one cannot drive the DMX512-lines directly from the GPIOs,
RS-485 drivers are required. That makes the complete interface "a
little" more expensive than $4 but with the µC and the USB interface
already THAT cheap ...


Any comments or ideas are welcome!

Best regards,
Jannis

Hippy

unread,
Feb 3, 2021, 7:49:27 AM2/3/21
to open-lighting
Very cool,  nice work!

Stefan Krüger

unread,
Feb 3, 2021, 3:32:36 PM2/3/21
to open-lighting
cool!!!
thanks for sharing this with us!

E.S. Rosenberg

unread,
Feb 7, 2021, 4:57:33 PM2/7/21
to open-l...@googlegroups.com
Very cool indeed.
Are you also able to listen (ie. do RDM/DMX in)?

Thanks,
Eli

Op wo 3 feb. 2021 om 22:32 schreef Stefan Krüger <ste...@s-light.eu>:
--
The Open Lighting Project: open-l...@googlegroups.com, #openlighting (irc.freenode.org)
To unsubscribe from this group, send email to open-lightin...@googlegroups.com
For more options, visit https://groups.google.com/groups/opt_out?hl=en
---
You received this message because you are subscribed to the Google Groups "open-lighting" group.
To unsubscribe from this group and stop receiving emails from it, send an email to open-lightin...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/open-lighting/04b1de95-a82b-4b79-b308-a3b484fb195an%40googlegroups.com.

Justin Herman

unread,
Feb 7, 2021, 5:12:46 PM2/7/21
to open-l...@googlegroups.com
I think listening to DMX might be an easier order than RDM.

E.S. Rosenberg

unread,
Feb 7, 2021, 5:28:45 PM2/7/21
to open-l...@googlegroups.com
With FTDI I found RDM was easier then DMX in, though I haven't revisited DMX in in ages (and getting FTDI RDM into mainline OLA has stalled)

Op ma 8 feb. 2021 om 00:12 schreef Justin Herman <jus...@gmail.com>:

Kripton

unread,
Feb 8, 2021, 4:23:50 PM2/8/21
to open-lighting
Hi, thanks for your feedback :)
Regarding DMX Rx (DMX In) and RDM: It's currently not implemented but it should be technicaly possible. The RP2040 hast 8 state machines that can run in parallel. The current code uses one! of them to output 16 universes in parallel. That is rather easy since we can dictate the timing and do not need to wait for certain condition or timing given by another device. With DMX In, the dongle is the one that needs to sync on another device's bus timing. And that most probably might not work well with one state machine. Just thinking about it: it might. We just sample the line, store the data in memory and let the CPU (not the PIO state machine) do the interpretation ... Need to try this :D

RDM is even more complex since one needs to switch between Tx and Rx fast enough. It might be that this would consume one PIO state machine for sending one! universe and another state machine for receiving. With 2 state machines per universe and 8 available that would reduce the number of RDM universes to 4. It might be that we can achieve RDM with one state machine per universe by swapping out the code running on the PIO between sending the RDM request and waiting for answers. That would allow 8 RDM universes. But right now I cannot judge how fast that code switching works. It needs to be done after sending the request but it needs to be ready (= Rx code running in the state machine) before the first bits of the RDM reply fly in ...

Furthermore, RDM needs two Pins per universe, one for the data and the other one for switching the direction of the bus driver. That limits us to 8 universes RDM anyways.

Regarding the USB interface and the code in OLA: I'm not so happy with the HID-based approach. HID limits you to max 64 Byte per Transfer. That means that 9 transfers are required to update one universe. If you have a fixture on channel 1 and one on 512 and you toggle them from full to blackout (or vice versa), that info will arrive at the RP2040 at different times. Since the DMX Tx sending rate is so fast, you can see that both fixtures don't switch at exact the same time. This is no problem for Tungsten/Dimmer based lighting, but is noticable with LEDs and can have pretty bad effects for moving heads with 16bit "2 channel" or even 32bit "4 channel" functions (pan/tilt/gobo rotations ...).
Therefore, I will play around a little with some other solutions, such as a "sync" command to not apply the partial universe changes until the whole universe is consistent. Or even better: a USB Serial based approach. Either compatible to "OpenDMX", the Enttec Pro devices or a custom protocol employing data compression so we don't run tinto bandwidth problems when all 16 universes are in use. We will see :)

Simon Newton

unread,
Feb 8, 2021, 4:29:13 PM2/8/21
to open-lighting
You may want to look at what I did for the pic32 device:
http://docs.openlighting.org/ole/doc/latest/md_doxygen_message-format.html
(see the end of the page)
> To view this discussion on the web visit https://groups.google.com/d/msgid/open-lighting/82304d00-4b73-4515-bf80-0930687f565fn%40googlegroups.com.

Kripton

unread,
Feb 8, 2021, 4:46:03 PM2/8/21
to open-lighting

Indeed, that looks like a well designed protocol. I will try to build upon that, adding some more commands as required (for example "Send DMX512 with universe id and compressed data".

You are getting around the "universe out of sync" problem by just sending one DMX frame when the complete command has been processed in the device, right? So when the host stops sending that command, the dongle would not send any DMX frames as well?
That's a bit problematic with the RP2040 code since all 16 universes run continuously. If one universe would wait for data from the host, all universes would stall. Some kind of double buffering would work. However, that increases latency :/

Simon Newton

unread,
Feb 8, 2021, 5:00:43 PM2/8/21
to open-lighting
On Mon, Feb 8, 2021 at 1:46 PM Kripton <kri...@gmail.com> wrote:
>
>
> Indeed, that looks like a well designed protocol. I will try to build upon that, adding some more commands as required (for example "Send DMX512 with universe id and compressed data".
>
> You are getting around the "universe out of sync" problem by just sending one DMX frame when the complete command has been processed in the device, right? So when the host stops sending that command, the dongle would not send any DMX frames as well?
> That's a bit problematic with the RP2040 code since all 16 universes run continuously. If one universe would wait for data from the host, all universes would stall. Some kind of double buffering would work. However, that increases latency :/

IIRC it uses double buffering. It was important not to 'tear' dmx frames.

Simon
> To view this discussion on the web visit https://groups.google.com/d/msgid/open-lighting/08e89caf-9767-45ec-bdb5-c0e615caf0b9n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages