A collection of DMX512 examples

DMX/sACN Intro Arduino:
Arduino DMX
Arduino sACN

This project is maintained by tigoe

Arduino sACN Source

The Arduino sACN Source library

Bill of Materials

For reference, The Arduino circuits described here use these breadboard layouts and these microcontroller pin arrangments.

It’s helpful to understand the basics of sACN and sACN control from a laptop before you continue.

These examples were tested using an ETC Source4 LED Lustr series 2 ellipsoidal and various other ETC fixtures, but anything that can receive DMX will work.


There’s no extra hardware needed to send sACN messages, but you will need to add external components if you want to add user control from sensors.

You will need to set up your lighting system using an ethernet-to-DMX controller that can receive sACN packets like the DMXKing eDMX1 Pro and know its IP address before you begin. All of these examples assume you’ve already got a working sACN network.


On all interactive examples, it’s a good practice to comment out the .sendPacket() line until you know your sensors are behaving as you expect locally, so as not to overwhelm the network with traffic.

The two most frequently used commands in the sACNSource library are the .setChannel() command and the .sendPacket() command. The .setChannel() command does not actually send data to the network, it just updates an array on the microcontroller with the values to be sent next time .sendPacket() is called.

Because you are on a network when sending ACN messages, you need to be careful not overwhelm the network’s bandwidth by sending too frequently. There are two good times to send:

Here’s a way to implement a once per second regular update:

 // global variables:
 long lastSendTime = 0; // the timestamp of the last send time
 int sendDelay = 1000;  // send once per second

 // if enough time has passed since last send:
  if (millis() - lastSendTime > sendDelay) {
    // send the data
    lastSendTime = millis();

Here’s how you could send only when a sensor has changed. In this case, it will only send when you’ve changed the sensor by a little over 1%:

 // global variables:
 int lastLevel = 0;      // previous value of the sensor level
 int changeThreshold = 3; // trheshold of change

   // read the knob's value, divide by 4 to get 0-255:
    int level = analogRead(A0) / 4;
    // if the sensor's changed significantly since last send:
    if (abs(level - lastLevel) > changeThreshold) {
      // set the value of the current channel
      myController.setChannel(1, level);       // set channel 1
      Serial.println(level);                    // print level
      myController.sendPacket(receiverAddress); // send the data
      // save current level for comparison next time:
      lastLevel = level;

It’s not a bad idea to combine both of these techniques, as you’ll see in the sACN Fade knob example. With a send delay of about 100ms, the effect on the physical interaction is relatively minimal, but the traffic reduction for the network is big.