Some time ago I wrote about implementing a DMX master controller using Arduino Uno and MikroElektronika RS-485 click board. Today I will show how to implement a slave DMX node, also based on Arduino and MikroElektronika click boards.
The required hardware is:
3 pcs. Arduino Uno / Genuino Uno (or any other 5V-based Arduino clone).
3 pcs. Arduino Uno Click Shield
3 pcs. RS-485 click boards
2 pcs. 4×4 RGB click boards
As in many other cases, the hardware is extremely simple to implement: just stick the Arduino Uno click shield on top of the Arduino Uno. Install the RS-485 click boards into slot#1 of the Click Shield. Install the 4×4 RGB clicks into slot #2 of the slave DMX boards.

The only thing that requires some care is setting the correct jumper position of the RS-485 click boards: on the master DMX node all jumpers are connected. This setting activates DMX bus terminator and also applies some bias on the RS-485 lines. Biasing has the role in providing a differential voltage to the DMX in idle state so the receivers are held in a known logic state. You can read more about the role of RS-485 / DMX biasing here.
– on the slave node(s) located on ine middle of the DMX bus all jumpers are disconnected.
– on the slave node on the opposite end of the DMX bus only the terminator jumper is connected.
The pictures below show the jumper configuration for all DMX nodes:
To connect the DMX nodes I used Cat5 UTP cable. The wire colors are those recommended by the Electronic Theatre Controls on their DMX-over-Cat5 page: white/orange is for Data+, orange is for Data- and both brown and white/brown wired are connected to the ground terminal. All other data pairs on the UTP cable remain unused.
DMX Master and Slave Arduino code
The code for the DMX master node is largely based on the Conceptinetics DMX library, which I found to be the code library the that works the best with the RS-485 click boards. So, please install this code library first. The same code library is used by the slave nodes. Also, the slave nodes require the Adafruit Neopixel library to be installed. So, as a prerequisite download and install these two code libraries.
Arduino code for DMX master node
Implementation of the code for the master node is explained in detail on my previous post. Here I post only the code for the current project:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/******************************************************************* | |
____ __ ____ ___ ____ ____ __ __ _ ____ __ | |
( __)( ) ( __)/ __)(_ _)( _ \ / \ ( ( \(__ ) / _\ | |
) _) / (_/\ ) _)( (__ )( ) /( O )/ / / _/ / \ | |
(____)\____/(____)\___) (__) (__\_) \__/ \_)__)(____)\_/\_/ | |
Project name: Arduino DMX master | |
Project page: https://electronza.com/arduino-dmx-master-and-slave/ | |
********************************************************************/ | |
/* | |
Example code for using the Conceptinetics DMX library with RS485 click board from Mikroelectronika | |
CH1: Red | |
CH2: Blue | |
CH3: Green | |
Based on: | |
Conceptinetics DMX library, | |
Copyright (c) 2013 W.A. van der Meeren <danny@illogic.nl>. All right reserved. | |
This library is free software; you can redistribute it and/or | |
modify it under the terms of the GNU Lesser General Public | |
License as published by the Free Software Foundation; either | |
version 3 of the License, or (at your option) any later version. | |
http://sourceforge.net/projects/dmxlibraryforar/files/ | |
*/ | |
// Be sure to download and install the library files first 🙂 | |
#include <Conceptinetics.h> | |
// The master will control 3 Channels (3) | |
// depending on the amount of memory you have free you can choose | |
// to enlarge or shrink the amount of channels (minimum is 1) | |
#define DMX_MASTER_CHANNELS 3 | |
// Pin number to change read or write mode on the shield | |
// Need to be 5 if slot#1 is used, or 6 if using slot #2 | |
// The switch on Click Shieeld should be set on Prog when programming the code, | |
// and on UART | |
// | |
#define RXEN_PIN 6 | |
// Configure a DMX master controller, the master controller | |
// will use the RXEN_PIN to control its write operation | |
// on the bus | |
DMX_Master dmx_master ( DMX_MASTER_CHANNELS, RXEN_PIN ); | |
// the setup routine runs once when you press reset: | |
void setup() { | |
// Enable DMX master interface and start transmitting | |
dmx_master.enable (); | |
} | |
// the loop routine runs over and over again forever: | |
void loop() | |
{ | |
// 3 Seconds of red light; | |
dmx_master.setChannelValue (1 , 255); | |
dmx_master.setChannelValue (2 , 0); | |
dmx_master.setChannelValue (3 , 0); | |
delay(3000); | |
// 3 Seconds of blue light; | |
dmx_master.setChannelValue (1 , 0); | |
dmx_master.setChannelValue (2 , 255); | |
dmx_master.setChannelValue (3 , 0); | |
delay(3000); | |
// 3 Seconds of green light; | |
dmx_master.setChannelValue (1 , 0); | |
dmx_master.setChannelValue (2 , 0); | |
dmx_master.setChannelValue (3 , 255); | |
delay(3000); | |
// 3 Seconds off; | |
dmx_master.setChannelValue (1 , 0); | |
dmx_master.setChannelValue (2 , 0); | |
dmx_master.setChannelValue (3 , 0); | |
delay(3000); | |
} |
Arduino code for DMX slave node
In this project, I decided to keep the DMX nodes as simple as possible, and I designed the two nodes to run the same program. Also I have designed the code so all the LED’s on the same node show the same color – just like an architectural light or a PAR projector – as this makes the code easier to understand.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/******************************************************************* | |
____ __ ____ ___ ____ ____ __ __ _ ____ __ | |
( __)( ) ( __)/ __)(_ _)( _ \ / \ ( ( \(__ ) / _\ | |
) _) / (_/\ ) _)( (__ )( ) /( O )/ / / _/ / \ | |
(____)\____/(____)\___) (__) (__\_) \__/ \_)__)(____)\_/\_/ | |
Project name: Arduino DMX slave | |
Project page: https://electronza.com/arduino-dmx-master-and-slave/ | |
********************************************************************/ | |
/* | |
Example code for using the Conceptinetics DMX library with RS485 click board from Mikroelectronika | |
Slave device using 4×4 RGB click and Arduino Uno | |
CH1: Red | |
CH2: Blue | |
CH3: Green | |
Ver.1.0, 2 November 2015 | |
http://microcontroller-projects.com | |
Based on: | |
Conceptinetics DMX library, | |
Copyright (c) 2013 W.A. van der Meeren <danny@illogic.nl>. All right reserved. | |
This library is free software; you can redistribute it and/or | |
modify it under the terms of the GNU Lesser General Public | |
License as published by the Free Software Foundation; either | |
version 3 of the License, or (at your option) any later version. | |
http://sourceforge.net/projects/dmxlibraryforar/files/ | |
Also inspired by: | |
NeoPixel Ring simple sketch (c) 2013 Shae Erisson | |
released under the GPLv3 license to match the rest of the AdaFruit NeoPixel library | |
https://github.com/adafruit/Adafruit_NeoPixel | |
*/ | |
#include <Conceptinetics.h> | |
#include <Adafruit_NeoPixel.h> | |
#ifdef __AVR__ | |
#include <avr/power.h> | |
#endif | |
#define SLAVE_CHANNELS 3 | |
#define RXEN_PIN 6 | |
DMX_Slave dmx_slave ( SLAVE_CHANNELS , RXEN_PIN ); | |
// Which pin on the Arduino is connected to the NeoPixels? | |
// If the 4×4 RGB click is in socket #2 the pin is A2 | |
#define LED_PIN A2 | |
// How many NeoPixels are attached to the Arduino? | |
#define NUMPIXELS 16 | |
// the LEDs should not be drivel at full intensity | |
// or they will overheat | |
#define MAXLEVEL 150 | |
// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals. | |
// Note that for older NeoPixel strips you might need to change the third parameter–see the strandtest | |
// example for more information on possible values. | |
// See the explanations from the Adafruit library | |
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, LED_PIN, NEO_GRB + NEO_KHZ800); | |
void setup() { | |
// Enable DMX slave interface and start recording | |
dmx_slave.onReceiveComplete (OnFrameReceiveComplete); | |
dmx_slave.enable (); | |
// Set start address to 1, this is also the default setting | |
// You can change this address at any time during the program | |
dmx_slave.setStartAddress (1); | |
pixels.begin(); // This initializes the NeoPixel library. | |
// now we turn off the neopixels | |
for(int i=0; i< NUMPIXELS;i++){ | |
// pixels.Color takes RGB values, from 0,0,0 up to 255,255,255 | |
pixels.setPixelColor(i, pixels.Color(0,0,0)); // Off. | |
pixels.show(); // This sends the updated pixel color to the hardware. | |
} | |
} | |
void loop() { | |
// put your main code here, to run repeatedly: | |
} | |
void OnFrameReceiveComplete (unsigned short ch) | |
{ | |
// Called every time when it collected its data | |
// and no interference from other interrupts | |
int red; | |
int blue; | |
int green; | |
// map(value, fromLow, fromHigh, toLow, toHigh) | |
red = map ( dmx_slave.getChannelValue(1) ,0 , 255, 0, MAXLEVEL); | |
blue = map ( dmx_slave.getChannelValue(2) ,0 , 255, 0, MAXLEVEL); | |
green = map ( dmx_slave.getChannelValue(3) ,0 , 255, 0, MAXLEVEL); | |
// now we send data to the neopixels | |
for(int i=0; i< 16;i++){ | |
// pixels.Color takes RGB values, from 0,0,0 up to 255,255,255 | |
pixels.setPixelColor(i, pixels.Color(red,green,blue)); // Moderately bright green color. | |
pixels.show(); // This sends the updated pixel color to the hardware. | |
} | |
delay(10); | |
} |
The above code requires both Neopixel and Conceptinetics libraries to be installed. As recommended by MikroElektronika, this project is designed to drive the LED’s at a fraction of their maximum possible output in order to avoid overheating. The maximum LED level is controlled by the variable MAXLEVEL, which was set at a value of 150 (of the maximum 255).
In the initialization part of the code, some pin attributions are made to match the hardware. The pin that controls if the RS-485 click is set to transmit or receive setting is pin 6. RX and TX pins are pins 1 and 2 of Arduino Uno. As you may already know from other projects, these are pins used also by the FTDI chip responsible for programming. Thus, both master and slave nodes the switch on the Arduino Uno Click shield MUST be placed in PROG position when programming, and on UART position when running on DMX mode. There is no serial monitor available.
Also on the initialization phase we define pin A2 (imposed by hardware) as data pin for the NeoPixels, and we define the number of NeoPixels as 16.
After all the pins are defined we initialize the DMX and the Neopixel libraries.
The most interesting part of the code happens within the OnFrameReceiveComplete function. This function enables us to execute time-sensitive code, as is the case with the Neopixels. So, as a DMS frame is received, the values received are first mapped to match the maximum intensity we previously set, then the new data is sent to the NeoPixels.
That’s all for this code example.
Some ideas to improve the code:
– Each slave node can be set to its own channels, so the slaves will display different color combinations
– Each NeoPixel can be driven independently, a number of three DMX channels being necessary (RGB). Increasing the number of channels will increase the CPU load. At some point, there might even arise the need to switch to a more capable board.
– The code for the master node becomes huge when implementing a larger number of DMX effects, especially when using transitions and fades. I’m working towards an advanced code for the master, using a DMX script stored on SD card.
4 Comments
Hi, I was wondering if you have done a version of this with separate led control? I am trying to create and led dmx fixture with separate led control and i’m a bit stuck.
Thanks
Hi!
By individual control you mean driving the LEDs with PWM? If so, you might take a look to the review of the TINKERKIT DMX receiver MOS. That board does exactly this: it has four DMX channels, so it can drive RGBA LED’s using PWM.
Even if you don’t have that board, you can use its code example as a starting point, and the power stage used to drive the LEDs is easy to replicate.
Hi,
is it possible to address every neopixel to a different start channel?
I need to build up a preview rgb strip where I can preview 4 or 8 channels on a neopixel strip.
I have 4 rgb floorlights connected via DMX to a DMX controller.
Each has a different dmx channel (10,20,30,40)
so I would like to use your project to preview the rgb values on the neopixel strip.
neopixel 1 shows rgb values from channel 10,11,12
neopixel 2 shows rgb values from channel 20,21,22
… etc
could you please help me with this?
thanks
cheers!
Hi,
In my project only channels 1-3 were used. To add more channels you have to do the following in the receiver part:
– change the number of channels to 42
#define SLAVE_CHANNELS 42
– change number of channels to 4 or 8, depending on your strip
#define NUMPIXELS 4
– for Neopixel #1 you will have
red1 = map ( dmx_slave.getChannelValue(10) ,0 , 255, 0, MAXLEVEL);
blue1 = map ( dmx_slave.getChannelValue(11) ,0 , 255, 0, MAXLEVEL);
green1 = map ( dmx_slave.getChannelValue(12) ,0 , 255, 0, MAXLEVEL);
– for Neopixel #2 you will have
red2 = map ( dmx_slave.getChannelValue(20) ,0 , 255, 0, MAXLEVEL);
blue2 = map ( dmx_slave.getChannelValue(21) ,0 , 255, 0, MAXLEVEL);
green2 = map ( dmx_slave.getChannelValue(22) ,0 , 255, 0, MAXLEVEL);
and so on…
Update the Neopixels as follows:
pixels.setPixelColor(1, pixels.Color(red1,green1,blue1)); // Moderately bright green
pixels.show(); // This sends the updated pixel color to the hardware.
pixels.setPixelColor(2, pixels.Color(red2,green2,blue2)); // Moderately bright green pixels.show(); // This sends the updated pixel color to the hardware.
pixels.show(); // This sends the updated pixel color to the hardware.
etc.