DMX Moving LEDs
Get the Kit
This project uses an Arduino to control the movement, color, and brightness of an 8x8 NeoPixel panel via DMX 512 and a DMX shield.
GitHub merges are welcome from anyone who improves the servo control, redesigns and adds support for stepper motors, or adds really cool example effects
You will also need the following
What Is DMX 512
DMX stands for Digital Multiplex and is the standard used in theatrical lighting to control dimmers and moving lights. The 512 stands for the number of channels supported by each set of connected devices, called a universe. We call them channels rather than lights because complex lighting instruments require more than one channel to operate. This means each universe can go from being able to control 512 individual lights to just a few dozen. For this reason, most high-end boards can control multiple universes.
First, a slight detour; let's talk about colors and computers. There are three primary colors of light RedGreenBlue which can be combined to form any other color of light (this isn't entirely true, but let's say that it is for the sake of simplicity). Most displays support a method called 24-bit "True Color" which assigns an 8-bit Byte to each primary color per pixel. This gives us a value range of 0 to 255 (2^8 or 256 possibilities) where 0 is off and 255 is full bright. Since light is additive, unlike pigments and gels which are subtractive, having all three colors set to 255 gives the appearance of white light while all three set to 0 is black. Every other combination gives us some color value. This has become the basic way we represent color in code. Here are some examples; I've included the hexadecimal representation which is very closely related to 24-bit.
204153255 = #CC99FF
71173144 = #47AD90
24722774 = #F7E34A
247190232 = #F7BEE8
Back to DMX. The formal description of DMX is that it is an "asynchronous serial digital data protocol." In other words, it can transmit values to any device in the connection chain without knowing anything about the devices themselves. A control board generates a DMX signal that contains some value on channel 15. Any device in the chain that is told to listen in to channel 15 will read that value while those that aren't told will read some other value. This means you can control multiple devices from a single channel without having to change the controller or programming. This also means that the controller will still transmit 512 channels even if only one channel is being used or the board can only control a hand-full of channels.
That covers the "asynchronous serial" part; now let's talk about the "digital data" part. By definition, digital data consists of signals that are either on or off. We generally represent this with 1's and 0's. When a control board generates a single DMX signal, known as a DMX packet, it creates a series of 1's and 0's which are broken down into a short header section and then 512 8-bit channel values. In other words, each channel is given a Byte with 256 possible unique values. It is up to the listening device to decide what to do with these values.
Traditionally, the go-to listening device is called a dimmer and is a specialized digital-to-analog converter, i.e. it is a digitally controlled potentiometer allowing more and more high voltage current through as the channel value increases. It acts as the intermediary to control the brightness of lamps (the theatrical equivalent of a light bulb) or the functionality of any other unintelligent appliance. Commonly, dimmers are used to read the value of multiple channels where the first channel is addressed and the rest are read sequentially. We generally refer these types of dimmers as racks. More and more so, however, traditional dimmers and racks are being replaced by smarter devices we call "intelligent fixtures" whose designs and uses vary wildly. Rather than try to cover specific devices, I'll give a brief overview of four common components of these fixtures. Keep in mind: each component must be controlled only using 256 possible values.
Controlling LEDs via DMX is incredibly straightforward thanks to the way we already represent color digitally. As I talked about above, each RGB color is controlled by a Byte, so we can have one-to-one control. We assign each color to a channel and directly use that channel's value. In addition, we want to assign a fourth channel to easily control the LEDs' brightness without affecting the light's overall color. This is a bit trickier but can be done by applying a simple equation: V=C*B/255 where C is the original color's channel value, B is the brightness value, and V is the value that is actually applied to the LED.
The secret to controlling motors via DMX is understanding value mapping. In short, it is a means of scaling some value range into another value range. For motors, we think of their position as degrees where one full revolution is 360° from the starting point. With DMX, however, we need to change the scale so that one full revolution is 256°. We use value mapping to convert a value in the 256-range so that it has the same relative position in the 360-range. You might also need to restrict a motor's range so a light doesn't hit its control unit. You'd do this by changing the mapping so that a 0-255 range is scaled to fit a 30-330 range.
This method of control is like motors in that the channel value is mapped to some min and max position. For example, a light's lens (focus) can be moved in and out based on a channel's value between 0 and 255. Some lights control color using this method and glass plates. Each plate is made so that a beam of light passes through more and more color as the plate turns around its axis. Treat 0 as transparent, 255 as saturated, and rotate the plate in front of the beam of light. If you have a plate for each color (RGB or CMY), you can control color without using gels or LEDs.
Unlike range, assignment is either one-to-one or, more commonly, range-to one. As an example, interchangeable gobos in larger fixtures can be chosen by setting a channel to a certain value. If there are 50 gobos to choose from, each is assigned a range of five values; #1 gets 0-4, #2 gets 5-9, and so on. Values 250-255 could be interpreted as no gobo. An intelligent board would know to set the channel value in the middle of each range (2, 7, 13, ...) to allow for some buffer room. Effect channels also use assignment to allow a user to choose from several pre-made fixture effects.
There are some limitations to DMX 512 that must always be considered, some of which have work-arounds. From the control board, up to 32 separate devices can be daisy-chained together where the last device terminates the DMX signal. If you need more than 32 devices, high-end boards support multiple universes, or you can use specialty DMX splitters to duplicate an incoming DMX signal. The other workable limitation is that DMX cables can't be longer than 4000ft due to signal degradation, though the recommendation is not to use cables longer than 1000ft. If you really need that distance, DMX repeaters act as a pass-through device to boost the signal but count against that 32 device limit.
There is one last limitation that I need to talk about, and it is important enough to deserve the following warning.
Most of our modern information protocols have some form of error checking to prevent (or at least ignore) anomalies, like high-energy rays from the Sun, from flipping bits in transit over the cables. Since DMX 512 has no way to check if a channel value has been altered en route, a device could read a value that is off by 128 with only one altered bit. Normally, we can overlook such things because these devices are constantly reading in values and people are not endangered by a light quickly flickering on and off. The issue comes when someone tries using DMX for such things as a triggering mechanism. As I said, a single flipped bit can alter a channel's value by up to 128, making trigger-by-range very easy to fire at the wrong time. Even if the trigger was a single value, there's still the slim possibility that it will fire early. For this very reason, DMX is not allowed to control anything that could put people in harm's way, especially pyrotechnics. Pyrotechnics and automation have their own protocols and devices, and it's best to keep all of these systems separate. Nothing can replace a seasoned stage manager and crew.
The circuitry for this project is fairly simple when connecting everything with a breadboard. As with most of my projects, I design them so that no soldering is involved beyond setting the breadboard pins in place. In other words, this project can be taken apart and every component reusable. There are a few things of note when wiring according to the diagram. First, the DMX shield sits on top of the Arduino, so all of the wires plug into it. Second, you can test the circuitry in any configuration you want, but you will still need to wire up every component in place in the enclosure to make sure all of the wires can reach the Arduino. Last, do not apply power to the LED matrix without the resistor and capacitor in place. The capacitor prevents power fluctuations in the LEDs, which both protects the electronics and prevents the LEDs' brightness from flickering.
A few notes about programming the light. By default, the Arduino listens to channels one through six. Right now, these values need to be changed in the code. Therefore, I have left the USB port on the Arduino accessible from the enclosure. However, because of the way the DMX shield operates, you need to alter one of the dip switches on the shield itself before applying power. The top switch (EN) enables and disables power to the shield. When connected to a compter for programming, the switch needs to connect the right-most pins (the side with the ~). When operating the light (ie powered by the AC adapter), the switch needs to connect the left-most pins. Also, the shield requires serial communications to operate, so testing using Serial.println() statements will not work.
The body for this project is divided into three sections with seven or eight pieces depending on how the LED matrix is secured. Each piece in the photos here were printed on a Makerbot 2 with PLA filament. Most of the pieces are flat and rectangular, which easily warps. To minimize the warping effects, each STL file includes the corner-circle-method. Each piece is printed with extremely short circles in each corner. When printed with (and subsequently removed with) a raft, the majority of the warping is absorbed by these circles and kept away from the piece. When the print is done, the circles are removed along with the raft. There is similar functionality built into the Makerware software, but my circles are far less intrusive being only one layer high, effectively just increasing the size of the raft. For those who wish to use other methods, I have included the raw Blender files so a version can be made without the circles. The only piece that needs to be printed with supports is the main body enclosure due to the wide openings.
A few notes about piecing the arm together. The arm has three main pieces: the center and the two vertical. The vertical with the servo horn groove should have that groove facing inward so the horn rests in it with the connector pointed back towards the servo. The other vertical should have the protruded circle pointing inwards for the panel to pivot on. I'd recommend using some glue to keep the verticals connected to the center. The center piece should also have its groove pointed towards the panel. The center servo horn is placed in backwards so that the arm is still supported when hanging upside down. To prevent the arm from falling out of place when the arm is on top, there is a piece in the shape of the horn to prevent it from moving around. I've found that friction between the layers of plastic are enough to keep it in place, so no glue is necessary here.