31 August 2013

DMXBridge, a wireless DMX sender and receiver

There are situations where DMX cables are unwanted or just not practical. This project implements a wireless transfer of a DMX signal in the 2.4 GHz band using the Arduino platform and the popular transceiver module nRF24L01+ from nordic semiconductor.

The DMX protocol

Receiving and sending the DMX protocol from the ATmega chip is done by using the DMXSerial library and the built-in serial port. This implementation is using interrupts and is a good base for implementing a second protocol on the same chip.

The DMX Serial library has a built-in 512 byte buffer for a DMX universe that is accessible using the functions provided by the library. After initializing the library and starting the communication the interrupts ensure the communication in the background.

You can find a lot of details in the article about the DMXSerial library.

The Wireless protocol

The 2.4GHz RF Transceiver is connected to the Arduino board or ATmega processor by using the SPI interface. The library for driving this chip I used is the library from Greg Copeland that you can find at https://github.com/gcopeland/RF24. After initializing the library it is possible to send and receive data by using the provided functions of the library. The library transfers all the commands and data to the nRF24L01+ chip will also handle all the transfer details in the background.


Because the libraries handle most of the communication details the implementation of this project only has to close the gap between the 2 protocols. The main differences between them are

Frame size: DMX is using a max. 512 byte long frame for sending all the values of all channels at once. The Transceiver uses a much shorter protocol that can transfer up to 32 bytes in one frame. I have seen controllers that do not send all the 512 bytes when only some channels are used in the setup.

Transfer speed: DMX is constantly using a 250 kBaud serial transfer speed on the DMX wire. There may be longer gaps between the frames and also between the individual bytes of a frame but it is common to use the maximum possible transfer speed. The Transceiver is supporting 3 different transfer modes

The solution I found and implemented here is to break up the 512 channels of the DMX information into smaller packages.

The sender

There are 2 buffers of DMX values. One contains the values I have received lately from the DMX protocol. The DMXSerial library is used to listen to the DMX protocol and fill this buffer.

The second buffer contains the values that have been sent over the wireless.

The values of both buffers are compared to find the recent changes and to send them with priority. If there is no difference between the 2 buffers no priority data will be sent.

To enable the addition of new receivers and to heal dropped packages all the DMX data is sent from time to time regardless whether there are changes on not.

The package transferred wirelessly contains a start-address and the actual 8 values starting at this address. The sender just sends the package without requesting any handshake from the receiver. This is called the broadcast mode of the nRF24L01+ modules that enables to use multiple receivers.

The receivers

The receiver only needs a single DMX buffer. All data from the incoming packages is directly taken into this buffer.

The DMXSerial library is used to send this information using the DMX protocol.

Setup the hardware

Both, the sender and the receivers need the DMX interface hardware attached to the serial interface and a nRF24L01+ module attached to the SPI bus. A prototype for this setup I used is the DMX Shield I published and a hand-soldered nRF24L01 adapter. The DMX shield is not forwarding the ICSP pins yet so this will only work on the Arduino UNO and older boards. (See discussion in Arduino Shield for NRF24L01+ post).

You need 2 of these at minimum.

Setup the software

Now you should be able to open and compile the provided sketches and upload them to the Arduino hardware.

The sketches I can provide for now are working in my environment and are not yet optimal for rough environments like stages. There are still some optimizations to do like sending smaller or larger packages and testing different transfer speeds. I like to get feedback from you.