Connect your Interactive Experiences to a DMX Lighting Controller with Node.js

Andreas Schallwig
The Startup
Published in
9 min readJan 27, 2020
Photo by Mahkeo on Unsplash

If you have ever built applications for interactive experiences it’s likely you had to integrate some kind of external light controls along with your application. Maybe you added some simple blinking LED lights around your kiosk application, or maybe you had to go all out and control a room scale lighting setup.

In any case, the basic question is always the same — How do you control external lights from within your application? How can you interface between the software and the hardware worlds?

tl;dr If you already know your way around DMX and don’t need the introduction part you can directly download the source code from my GitHub repository:

The initial idea — Use a Raspberry Pi

One solution often suggested is to use an Arduino or Raspberry Pi and control the lights via the GPIO pins. While this can work in some scenarios it comes with drawbacks which (in my opinion) make it not a viable solution especially for larger installations. Here is why:

  • Event or stage environments can put a lot of (physical) stress on your application. GPIO connections are brittle and tend to fail easily unless you carefully fix everything in place.
  • LED lighting elements usually need a power supply with 5V, 12V or even higher voltages, along with some serious amps (around 1A per meter of LED strip). Means you need to design a basic circuit to control the LED power circuit with the Raspberry’s 3.3V and 5V GPIO pins.
  • The distance between your interactive element (user interface) and lighting elements may be a couple of meters or even larger. You need sturdy and reliable cabling to bridge such distances.
  • Lighting setups are usually built and installed by a construction company or an electrician. These guys know their end of the project but know nothing about how to interface with your Raspberry Pi. It’s absolutely a non-standard way of connecting stuff.
  • Finally consider the safety of your setup. Seriously, you don’t want to play around with 110/230V ️stuff unless you know what you are doing ⚡
Raspberry PI LED light controller setup
This is NOT how your lighting setup should look like

A quick introduction to DMX

Ask any seasoned light engineer or set builder what technology they use to control lights and other equipment, the unanimous answer will be “DMX”.

If you’ve never heard of the DMX (or DMX512) standard, Wikipedia describes it as:

DMX512 (Digital Multiplex) is a standard for digital communication networks that are commonly used to control stage lighting and effects. It was originally intended as a standardized method for controlling light dimmers, which, prior to DMX512, had employed various incompatible proprietary protocols. It soon became the primary method for linking controllers (such as a lighting console) to dimmers and special effects devices such as fog machines and intelligent lights.

Essentially, DMX512 is a decades old standard. Today its applications have expanded far beyond stage environments and (quoting Wikipedia again) “DMX can now be used to control almost anything, reflecting its popularity in theaters and venues.”

DMX512 Light Controller (left) / XLR three-pin connector (right)

This sounded exactly like what I was looking for. So I started researching what hardware was required and what options I had to connect and control DMX equipment.

My goal was to create a proof-of-concept application with Node.js which lets me control a single RGB light 💡 via USB or serial port. With that in mind I went on a shopping tour to source the required parts. This is what I came back with:

  • An OpenDMX compatible USB to DMX dongle (Alibaba)
  • A 3-channel DMX512 RGB light decoder (Alibaba)
  • Some 12V RGB LED tape (Alibaba)
From left to right: USB to DMX dongle , DMX512 decoder, 12V RGB LED tape

How to use a RGB LED light DMX controller

Let’s have a look at the front side of the DMX512 decoder first. You will find the following inputs and outputs which are pretty common amongst all DMX enabled devices:

  • A set of dip switches to set the DMX address (more on that in a second)
  • RJ-45 style DMX input / output (looks like ethernet ports)
  • XLR3 style DMX input / output (the round ones)

A DMX512 universe lets you daisy-chain up to 32 devices with a total of 512 control channels.

The RJ-45 and XLR3 style inputs are identical in function. You can use your preferred style of cable although many prefer XLR3 cables due to their robustness.

Since you can daisy-chain multiple DMX devices to form a single “DMX Universe” there is always an output connector to connect the next device in the chain. It is also best practice to use a DMX terminator (120Ω resistor) with the last device in the chain.

DMX512 decoder LED and Power connectors
LED strip and power connectors

On the backside of the decoder you find the connectors for the LED strip (R, G, B and control channel) also the power connectors (12V or 24V). This particular model can only connect a single light, but there are many other decoders available which support 4, 8 or even more lights. And if that isn’t enough you can always daisy-chain DMX devices.

Configuring the device address

The device address is the channel that the DMX device begins. In a DMX512 universe there are a total of 512 addressable channels the controller can use. For the controller to talk to a device it needs to know at which address to find the device. Hence you need to configure a device address.

In addition to the device address you also need to know the number of channels the device is using. For example a RGB light will use 3 channels (R, G and B), so if you set its address to “42”, it will use channels 42, 43 and 44. When using multiple devices make sure their channels do not overlap!

DMX decoder address dip switches

Setting the device address is often done by numbered dip switches. Each switch number is assigned a DMX channel value through binary code. So if you want to set the address “42” you’d need to set switches 2, 4 and 6 which translates to “2 + 8 + 32 = 42”.

DMX address configuration by dip switches

Wiring up power and lights to the DMX decoder

With the address configured the next step is the wiring of the power supply and LED strip to the DMX decoder.

In my setup I’m using a standard 12V/2A power brick with with a barrel jack. Attached to the barrel jack is an adapter which splits the positive and negative wires. These wires go directly into the V- and V+ inputs of your decoder.

Next the 4 wires of the LED light need to be connected to the output channels of the decoder. Usually COM takes the (black) control wire while CH0, CH1 and CH2 take the R, G and B wires. If in doubt refer to the manual of your decoder.

From left to right: LED strip with 4 wires, 12V DC power brick with barrel jack adapter, final wiring result

Testing your setup

Before you continue it’s very helpful to test your wiring to make sure everything is properly connected. Most DMX light decoders have a built-in test function which can be enabled via a dip switch or button. My decoder has a dip switch labeled “FUN” which probably means “Function”, but I prefer to think of it as “Let’s have some fun”. I’ll see myself out.

The setup is working- Yay!

Building the DMX controller application

With the electronics side of the project working I could move on to building the controller application. My idea was to create a simple color picker together with a brightness slider to test whether I could control the LED strips color and brightness.

DMX light controller app done with Node.js and Electron
A super simple Light Controller App

Connecting the USB to DMX adapter

I totally expected this part to be biggest challenge in this project. My USB to DMX dongle came with no manual or drivers, just the seller assured me that “it works as a serial device” and “it’s OpenDMX compatible”.

To my surprise the dongle worked out of the box with Windows 10 and MacOS. Windows recognized the dongle as “USB Serial Port” connected to COM3, MacOS recognized a new device at /dev/tty.usbserial-AD0JLFXK.

Out of curiosity I also plugged it into a Raspberry Pi 4 running Raspbian Buster and the dongle was instantly recognized as USB serial device at /dev/ttyUSB0. Yay!

USB to DMX dongle is immediately recognized in Windows 10
Windows 10 recognizes the dongle as USB Serial Port

Now it was finally time to write some code. Following my own tutorial on how to create an Electron kiosk application I quickly created a skeleton app.

A quick Google search revealed that someone had already created a basic DMX controller library for Node.js. So instead of digging through the DMX protocol and figuring out the connection parameters I could use this library as a drop-in solution.

The resulting controller code looked like this:

import DMX from 'dmx';export default class DMXController {  constructor() {    const dmx = new DMX();
this.universe = dmx.addUniverse('demo',
'enttec-open-usb-dmx', 'COM3');
this.universe.updateAll(0);
}
setColor(startChannel, r, g, b) {
this.universe.update({
[startChannel]: r,
[startChannel + 1]: g,
[startChannel + 2]: b
});
}
}

This DMXController class basically just handles the creation of a new DMX universe. In my example it is connected at port COM3 and using the Enttec OpenUSB connection driver. The universe is then initialized with all zero values which resets all devices to their default states.

On the frontend side I created a color picker (RGB values from 0 to 255) and an intensity (brightness) slider (values from 0 to 99). The final output RGB value is the product of RGB values and intensity.

Relevant parts of the source code below. This code was written for Vue.js, but you can easily adopt it to any other framework or vanilla JS.

import DMXController from 'DMXController'export default {
name: 'controller',
watch: {
colorResult(newVal) {
this.controller.setColor(
this.startChannel, newVal.r, newVal.g, newVal.b
);
}
},
computed: {
colorResult: function() {
let i = this.intensity / 99;
return {
r: Math.round(this.color.r * i),
g: Math.round(this.color.g * i),
b: Math.round(this.color.b * i)
};
}
},
data() {
return {
color: { r: 255, g: 255, b: 255 },
startChannel: 1,
intensity: 0,
controller: null
}
},
mounted() {
this.controller = new DMXController();
}
}

And here is the final result \o/

The final Node.js Application controlling a DMX lighting fixture

You can download the source code for this demo from my GitHub repository:

This is the end of my tutorial. Feel free to use my source as a base for your own applications. If you have any comments, questions or suggestions please start a conversation in the comments.

❤️ Thank you very much for reading! And I’d love to see all the cool stuff you come up with! ️❤️

--

--

Andreas Schallwig
The Startup

A 20-year veteran in Asia's digital industry and an expert in creating immersive digital experiences using innovative technology.