Getting DMX data in a PIC


When I need to change the functions of a fixture I use the DMX bus to drive them. This article presents you the software code I use (in C language) to decode the data. I’m using it on PIC MCU from Microchip. It may be possible to adapt the code for other hardware.

DMX protocol presentation

Before going deeper in the code, I recommend you to have look on Wikipedia website. Nevertheless here after the frame:

When the bus is idle, the line is in a high level. The beginning is marked with a break. The break is 88µs long at minimum and 100ms maximum. After the break with have the Mark After Break of 8µs at least.

The first data send is the « Start Code ». The start code is used to select a part or a specific function of the fixture. in the general equipment, the start code is waited at 0x00. This code is for dimmer in the standards. Other codes are available in the ESTA liste. After the start code we have 512 bytes, one for each channel. Each byte is marked with a start and 2 stops.

It’s an easy protocol.

How to get data?

To get the data we will use the PIC’s UART. To decode the frame, we will use a state machine.

  • IDLE : It’s the default state.
  • When the UART get a FRAME ERROR it means that the ligne state to long at 0. It’s the BREAK. During this period we have to read the 0x00 in the UART until we get a new FRAME ERROR. This happens when we are in the MAB.
  • The state machine is then in START. As long as we detect the FRAME ERROR we are in the MAB of the DMX bus. But as soon as the data is 0x00 we get the START CODE. We can go to the DATA state.
  • In DATA, we simply get the 512 channels. In the program, we only store in memory the data we have to use. When the internal counter is at 513, the FLAG is set to say that we have a new data available.

The code

UART configuration

First, the UART has to be configured in receive mode at 250kpbs. To be more flexible with the Software, I do a re-naming of the registers with a #define.

Than in the DMX library we have the initialization function.

Some functions to start and stop the UART.

The interruptions

To get the state machine operating, we need events. To get them, we use the IT coming from UART.

Decode function

Don’t forget to add in the h. file of the library the enumerator declaration

And naw we have the function

Data structure

As you have seen in the code, I use the DMXRx variable. It’s a structure who contains, the device address, a table sized for the number of channels and a flag new data.

The timeout

You can make the code work without timeout. On my point of view it’s better to have. It’s a simple counter and when it’s higher than 100ms it push an IT who will reset the state machine and the UART.

What’s next?

In your main() function, who can have a loop and when a new data received, you can generate a PWM, analog output etc. I use the flag DMWRx.NEW_DATA to detect the new data and to update the output.

That’s all.