Look, no computer! Arduino-based Touch-Sensitive DMX Lighting Controller.
In a recent dash to update our documentation to include the Arduino API, I had to get up to speed with how it works and figure out a simple example to share and show off.
After tossing around some different ideas (robot arm was already taken!) and doing some research, I found a DMX shield for Arduino that looked like it would be a great way to try something new without a lot of hardware engineering. After all, I wanted to focus on the API, not soldering, cutting, and gluing bits and pieces. And as a bonus, we were headed to the NAMM convention to show off all the fun music things the Morph can do, and we thought the added bonus of a lighting controller would really blow some minds.
Here's how I made it.
The Shopping List
- Arduino MEGA 2560
- TinkerKit DMX Sheild
- Cheap DMX controllable lights
- DMX Cables
- XLR Adapter cable
- Sensel Morph
- Innovator's Overlay
- Developer's Cable
The Software List
The Arduino IDE has its own installer - just follow the directions. The Sensel API and DMXSimple folders can be unpacked and installed to the Arduino libraries folder, usually in your user's Documents/Arduino/libraries folder.
Connections
Now that everything arrived, I needed to connect everything and setup the hardware. Here's an image detailing all the connections
The first thing I had to figure out was how to talk to the Litake DMX lights. Although DMX is a control standard, different lights have different schemes. In the case of these RGB lights, I had to set their jumpers to the correct position to put them in DMX mode and set a root channel. I was new to this, and found some documentation on the little piece of paper that shipped with the lights, but I still ended up having to tinker and search to get it right. To spare you the trouble I went through, here's some pictures detailing how I set those jumpers:
Code Part I: Fade Red, Green, and Blue
Before I did anything, I wanted to make sure I could talk to the lights from the Arduino. I used the "Fade" examples in DMX Simple and modified them to suit the communication to the RGB lights I had. Here's an excerpt (you can see the whole sketch in my code repo):
void loop() { int brightness; /* Simple loop to ramp up brightness */ for (brightness = 0; brightness <= 127; brightness++) { /* Update DMX channel 1 to new brightness */ DmxSimple.write(1, 127); //brightness DmxSimple.write(2, brightness); //R DmxSimple.write(3, 255); //G DmxSimple.write(4, 255); //B /* Small delay to slow down the ramping */ delay(10); }
For confidence, I played with moving the "brightness" variable to the different channels and re-uploading the sketch to the Arduino. Everything worked!
Code Part II: Make a UI
Now that I had figured out how to talk to the light from the Arduino, I had to come up with a control scheme using the Morph and the API. I wanted it simple to demonstrate, but I did want to be able to use pressure and create some simple UI controls that I could print out and place under the Innovator's Overlay.
I worked in Adobe Illustrator to create my interface. I set my units to "millimeters" and created an artboard the size of the active area of the Morph 120mm x 70mm. This not only made sure everything fit, but it simplified the coding, since I could easily plot my "hot zones" for conditional statements, simply by referring to the graphic objects in Illustrator.
As you can see, I've set up controls for 2 different lights, controlling their colors by position and brightness by distance from center. Not obvious is pressure: this will control the "strobe" rate. Fortunately, the lights have a built-in strobe feature, so I don't need to do any timing programming! I've also reserved a couple other zones with the dotted lines for future buttons or modes that I could switch.
Code Part III: Morph Control
I knew this would take some time to figure out, but the main functions I needed to create were
- RGB lookup table
- Linear Interpolation scheme for RGB values
- Parsing contact data from Morph API to create "hot zones"
- Cartesian to polar conversion that returns a 0-15 value for lookup table
- Radius calculation for distance from center of the color wheels
To create the color lookup table, I researched various color wheels to see how to optimally lay it out. I created a 16 member array of RGB values that matched the colors in my Illustrator sketch.. You can see this at the top of the DMXmorph.ino sketch.
In order to figure out what a contact would do, I needed to look at the stream of contact data, determine if a contact was in a particular zone, then call the appropriate functions based on location and pressure.
If you dive into the code, you can also see that I started to create a "gesture recorder." The idea here is to hold a button, and record the color sweeps and strobes, and have it loop through that data. I never really finished that - I needed to pack up this project and get to NAMM!