www.mathertel.deArduino ProjectsDMXSerial2 DMX+RDM Library

Using Arduino for sending and receiving DMX RDM

Here you can find a library to implement a DMX devices that also listen and respond to RDM commands. The library is compatible to the Arduino specification and the DMX Shield described in the article DMXShield describes the hardware needed to communicate DMX in both directions.

Extending DMXSerial to DMX RDM communication

From the beginning the DMXSerial library was designed to send and receive DMX data packets. Now it is extended to support RDM packets as well. I had to overcome several pitfalls and stumbling blocks while extending the DMXSerial implementation and I will keep the current version because it needs only a very small amount of program data.

The RDM extended version will be DMXSerial2.

What you can find in the attached zip file is a ARDUINO library including a sample project for implementing a simple RDM Device.

The basic DMX (no RDM) implementation of the library is available in DMXSerial.aspx.


The Hardware you need is a RDM compatible shield. I used my own design for a DMX Shield with isolation that you can find on http://www.mathertel.de/Arduino/DMXShield.aspx

The hardware requirements for the sample is a DMX line attached to the serial port, the data direction switch at pin 2 and some led to the ports 5, 6 and 9. My DMX shield can be used as well.


By using the Library Manager built into the Arduino Environment you can always download the latest stable version that comes directly from my github repository.

The library includes a example for implementing a RDM device for receiving DMX messages and responding on the most common RDM commands.

You can find that repository and download directly at:

If you like the latest version including work in progress please use the download from github directly by using the "Download ZIP" button or any git or subversion client.

Why you should implement RDM?

...because it is „faster than the ladder“ [www.rdmprotocol.org]

So you are familiar with DMX you know that every device must be programmed to have the right DMX starting address for to be controlled correctly by the controller of the DMX line. If you often add new devices or exchange devices you know that sometimes mistakes in the right DMX setup costs you a lot of time. Because pure DMX only can send data through the line you cannot detect what effect will really be enabled by a specific DMX value. You need a plan before you start.

RDM now enables a controller to ask for information from all the devices on the line and send out commands without having a right DMX addresses configured for all devices.

My personal benefit from this implementation is that I need no further hardware to setup DMX Addresses like DIP switches or advanced LCD Panels for my projects.

But there is more than the DMX address setup that can be done with RDM and I like to explain some of the concepts of RDM in short – the way I see them.

Good starting points for finding information about the RDM protocol are the following links:

The DMX Shield on top of an Arduino working as an RDM device.

The DMX Shield working as an RDM device.

Current development of the library

The current implementation already fully functional and implements all RDM commands tagged as minimum required by the RDM standard. However I still see place for improvements. There is one example sketch included that implements a 3 channel (RGB) device.

RDM Data on the DMX line

DMX packets are sent on an DMX line by starting with a long „silence“ also called Break, then a startcode byte with a value of 0 and the up to 512 bytes of data. RDM uses the same pattern except that the startcode has a value of 0xCC and then a variable count of bytes I’ll explain later.

On pure DMX lines only the controller sends data and all devices only listen. With RDM the devices also are allowed to send data on the line but only when they are asked to do so!

This approach was chosen because it is compatible with the old DMX behavior and enables to leave old DMX devices on the same line with newer RDM devices.

Addressing a RDM device

RDM (very similar to the Ethernet) requires that each individual device has a global unique number that can be used to address it. This Device ID in RDM has 6 bytes where the first 2 bytes identify the manufacturer of the device. You can find a list of all registered manufacturers at rdm.openlighting.org. The other 4 bytes are assigned by the manufacturer itself to each individual device.

It was an easy job to register a manufacturer id to myself as explained on http://tsp.plasa.org/tsp/working_groups/CP/mfctrIDs.php. Feel free to use my manufacturer id yourself if you promise only to use it for experiments and never to put a real device that leaves your hands.

If you plan for more please request your own manufacturer id and adjust the _devID definition to use it.

For my implementation there is a constant that you have to give to the DMXSerial2 library when initializing the communication. As of this writing I use 0x2345 as a manufacturer code, because it seems to be unused to avoid conflicts. For the other 4 bytes I use the date of creation, for example: 0x2012 0x11 0x02

If you build more than one device you have to take care of this and give every device its own number.

RDM Command sample

Here is a sample of a SET Identify command send to device 234520121102:

>> CC 01 19 234520121102 4164FF000001 nn 01 00 0000 30 1000 01 01 cscs
  • CC and 01 are the start code bytes identifying a RDM packet
  • 19 is the total length of the packet.
  • 234520121102 is the DEVICEID of the device
  • 4164FF000001 is the DEVICEID of the controller
  • nn is the transaction counter defined by the controller
  • 01 is the ResponseType
  • 00 (is _unknown)
  • 0000 (is number of a subdevice)
  • 30 means that it is a SET command
  • 1000 is identifying the IDENTIFY_DEVICE command
  • 01 is the length of the following data (one byte/boolean in this case)

Now the command specific data follows:

  • 01 means that Identify Modes should be switched on.
  • 2 bytes checksum marks the end of the transmission.

The answer from the device is built almost identically:

<< CC 01 18 4164FF000001 234520121102 nn 00 00 0000 31 1000 00 cscs
  • CC and 01 are the start code bytes identifying a RDM packet
  • 18 is the total length of the packet.
  • 4164FF000001 is the DEVICEID of the controller (now switched)
  • 234520121102 is the DEVICEID of the device
  • nn is the transaction counter.
  • 00 is the ResponseType
  • 00 (is _unknown)
  • 0000 (is number of a subdevice)
  • 30 means that it is a SET command
  • 1000 is identifying the IDENTIFY_DEVICE command
  • 00 is the length of the following data (none in this case)
  • 2 bytes checksum marks the end of the transmission.

The transaction counter is incremented every time the controller is sending a new command to the line. The answer from the device has to contain the same transaction number so the controller knows that the answer corresponds to the command.

Timing issues

The first versions (up to version from 22.01.2013) of DMXSerial2 was not stable during several tests I did and often a response package did not reach the controller as expected. After some testing with inserted delayMicroseconds() functions and time probes in several places I found that the implementation with the Arduino processor and the DMX Shield was sometimes too fast for the used controllers and the DMX line.

In several publications for example in http://www.soundlight.de/techtips/dmx512/dmx_rdm.htm you can find the timing requirements defined by the RDM standard and it seems that it is very important to follow them strictly.

The one timing condition that is indeed implemented by the RDM client is the time between the end of a RDM command that is sent by the controller and the start of the RDM response that is sent by the client. Because the answer to a command is created asynchronously in the tick() function this time was varying and was often shorter than the expected minimal 176 µsec .

The version from 01.03.2013 and later now saves the time when the last byte of a command was sent into a global variable and delays the start of the answer when appropriate. After implementing this delay mechanism the RDM communication was much more stable then before.

And there is the RDM-BREAK that is longer than the DMX-BREAK: min. 176 µsec instead of 88 µsec. 


Opendmx has a good article on the discovery process, see http://www.opendmx.net/index.php/RDM_Discovery.

There is also an article of Simon Newton

After searching all the devices the controller knows all DeviceIDs of the devices that are attached to the DMX Line it is possible to ask for more information or set parameters in the devices. All these SET and GET commands will use the DeviceID to address the device.

Device Info

The DEVICE_INFO message is very important and MUST be implemented by every device because it enables the controller to ask for the basic information of a specific device.

The Major and minor protocol version

Device Model,  Product Category, Software Version (don’t exactly know what this is for in detail)

The current DMX start address (It can also be retrieved by using DMX_START_ADDRESS)

The current footprint (the number of channels used)

The current personality, the number of supported personalities.

The number of existing sub devices (I haven’t looked at this feature yet)

The number of existing sensors (I haven’t looked at this feature yet)

Todo: The DMXSerial2 library supports this command and returns adequate values for devices with only 1 personality.

The current DMX address and the footprint are available in the according DMXSerial2 attributes.

Device descriptions

There are multiple commands: DEVICE_MODEL_DESCRIPTION, MANUFACTURER_LABEL and DEVICE_LABEL that are used to get short descriptions from the device.

The values for MANUFACTURER_LABEL and DEVICE_MODEL_DESCRIPTION are intentionally fixed for specific device and defined by parameters to the initRDM method whereas DEVICE_LABEL can be changed by using RDM Command so you can name each device according to your local setup.

This is initialized to the device model description but when changed it is stored into EEPROM for further use even after a power off.

Identify mode

The IDENTIFY_DEVICE is used to switch on and off the IdentifyMode.

After the discovery procedure you still might have the questions which of the devices is at what specific position, especially when you have more than one device of a given type. So here comes the identify mode that can be switched on and off by RDM commands. When switched on the device should identify itself on the stage in a specific way for example by blinking constantly.

TODO: This command is implemented in the library by the isIdentifyMode flag. This flag is set to true/false according to the last received command.

DMX Address Patch

The DMX start address has to be supported when any DMX slot is used by the device. The DEVICE_INFO message contains already the DMX start address but it can also be retrieved and changed by using the DMX_START_ADDRESS command.

When setting a new DMX start address the value is persisted into EEPROM.

The library handles this command.

Persisting RDM parameters

In the current implementation the following values are persisted into EEPROM memory, the DMX start address, the Device Label and the Device ID. It’s implemented by defining all the bytes from the EEPROM memory in the structure EEPROMVALUES including 2 signature bytes.

When initializing the library the EEPROM data is read out it is checked whether the 2 leading bytes in EEPROM are as expected. If not some default values are used and persisted.

The values are changed by using RDM commands and also persisted in the EEPROM.

Some words about the official RDM specification

The RDM is called "ANSI E1.20 - 2010 - Entertainment Technology-RDM-Remote Device Management over USITT DMX512 Networks".

It is now available for free by using the download available at http://tsp.plasa.org/freestandards.


There is some information about RDM on the internet and here are some Links I used to find out how it works:


The RDM Manufacturer Library oft he Open Lighting Project. On this web site you can find many short descriptions of RDM compatible devices. Especially here you can find a lot of information about the supported parameters.


The Open Lighting Project WebSite with a Wiki full of information. Search for RDM and you find a lot of helpful pages.

The OLA source code can be found on http://code.google.com/p/open-lighting/



Here you can find the RDM specification download.


A detailed and good article on the discovery process.


This is a web site from the some people around the company PLASA where you can find a lot of useful information. Especially the forum is helpful.

In the downloads you can find the RDM.h file for E1.20 and E1.37 that includes a lot of usable #defines.



Especially the software from Hendrik Hölscher was a great help. He published some work upon DMX and RDM and especially a USB to RDM interface he called OpenRDM that I used for testing: http://www.hoelscher-hi.de/hendrik/light/openrdm.htm.

He also has implemented an experimental RDM device. The source code and some RDM specific details can be found on his resource page. For his dimmer project a compiled RDM firmware available.

The implementation I did is very similar to the version of Hendrik Hölscher in some aspects: he also uses the ATMEL microprocessor and also uses the internal UART to communicate with DMX. I checked his implementation some times for clarifying questions that came up during development and test.


At ESTA you can find and purchase the official RDM specification.


The company has published some good articles.


Also good to mention is wikipedia





An RDM compatible coffee machine.


  • 22.01.2013 First published version.
  • 01.03.2013 Updated version with better timing, still work in progress.
  • 08.03.2013 Version 1.0 published as an Arduino library with sample code.
  • 19.09.2013 Update including:
    • The serial port definitions now also support Arduino MEGA 2560 (port 0 and 1) and Arduino Leonardo (port 1) boards.
    • I registered my own manufacurer id, now #0987 for mathertel.de.
    • There is a functionality that creates random device ids in the code. If a board once has started to work the device id will be stored into the eeprom and will remain there even when new software is uploaded.
    • I added the required RDM parameters SOFTWARE_VERSION_LABEL and SUPPORTED_PARAMETERS to comply with the standard.
    • Finally I removed some DMX-only specific code and did some simplifications and memory optimizations.
    • The initialization data for the library is now combined into a new structure.
  • 21.11.2013 Bug fixing missing response for MUTE messages.