Theater Cue Lights (DMX Shield) Code and Advice

Hi gang,

I've cobbled together some code, I'm super new at Arduino, so really a hacky copy/paste job, but it seems to be doing the trick... However I just heard that sometimes there's a lag between a switch flipping and the appropriate change in the lights. All it's meant to do is take physical switches and convert them to DMX on/off values (0-255). Any tips for cleaning up the code, simplifying or making it more redundant? It runs for sometimes 8+hrs a day without reboot through 3 shows before being powered off, then back on the next day. Was designed to just work seamlessly for our Stage Manager to control 8 lights on switches instead of a light board...

/* Welcome to DmxSimple. This library allows you to control DMX stage and
** architectural lighting and visual effects easily from Arduino. DmxSimple
** is compatible with the Tinker.it! DMX shield and all known DIY Arduino
** DMX control circuits.
**
** DmxSimple is available from: http://code.google.com/p/tinkerit/
** Help and support: http://groups.google.com/group/dmxsimple       */

/* To use DmxSimple, you will need the following line. Arduino will
** auto-insert it if you select Sketch > Import Library > DmxSimple. */

#include <DmxSimple.h>
// Initalize variables for 8 channels, default to Off (0 value)
// This gives names to each channel so you can change which "switch" they're attached to later...
  int STAGE = 0;
  int DSR = 0;
  int MSR = 0;
  int USR = 0;
  int USL = 0;
  int MSL = 0;
  int DSL = 0;
  int PIT = 0;
  int SOUND = 0;
void setup() {
  /* The most common pin for DMX output is pin 3, which DmxSimple
  ** uses by default. If you need to change that, do it here. */
  DmxSimple.usePin(3);

  /* DMX devices typically need to receive a complete set of channels
  ** even if you only need to adjust the first channel. You can
  ** easily change the number of channels sent here. If you don't
  ** do this, DmxSimple will set the maximum channel number to the
  ** highest channel you DmxSimple.write() to. */
  DmxSimple.maxChannel(8); // Only using 8 channels, the first switch is a master for the next 6...
  //Set pins 4-12 to Pullup Inputs, each is 1 switch on the board (DON'T CHANGE)...
  pinMode(12, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  }

void loop() {
  // read the input on each switch (On or Off and set the switch variable to match):
  // The switch #s correspond to the board in order (0 being the master on the left):
  int switch0 = digitalRead(4);
  int switch1 = digitalRead(5);
  int switch2 = digitalRead(6);
  int switch3 = digitalRead(7);
  int switch4 = digitalRead(8); 
  int switch5 = digitalRead(9); 
  int switch6 = digitalRead(10); 
  int switch7 = digitalRead(11); 
  int switch8 = digitalRead(12);  

 //Check each variable and set DMX to On (255) or Off (0):
 //This is where you link the Variables to the Switches...
 //Example: Change DSR under switch1 to USR and then USR to DSR it will flip those switches.
 if (switch1 == 0) {
    DSR = 255 ; }
  else {DSR = 0 ;}

   if (switch2 == 0) {
    MSR = 255 ; }
  else {MSR = 0 ;}

  if (switch3 == 0) {
    USR = 255 ; }
  else {USR = 0 ;}

  if (switch4 == 0) {
    USL = 255 ; }
  else {USL = 0 ;}

  if (switch5 == 0) {
    MSL = 255 ; }
  else {MSL = 0 ;}

   if (switch6 == 0) {
    DSL = 255 ; }
  else {DSL = 0 ;}

  if (switch7 == 0) {
    PIT = 255 ; }
  else {PIT = 0 ;}

  if (switch8 == 0) {
    SOUND = 255 ; }
  else {SOUND = 0 ;}

// Override Full Stage, sets all 6 stage lights on. Left Hand "Master" Switch:
// The leftmost switch overrides the next 6 and turns them on.
// NOTE: When the Master is turned off, the 6 stage switches will be active immediately
// so if "3"/"USR" is still on when the Master is turned off, that light won't turn off
  if (switch0 == 0) {
    DSR = 255 ;
    MSR = 255 ;
    USR = 255 ;
    USL = 255 ;
    MSL = 255 ;
    DSL = 255 ;
   }

    // Update DMX channel 1-8 to new level
    // This only sets the values for each DMX channel to match the value from earlier
    // DO NOT CHANGE THIS SECTION, change the swithes above...
    DmxSimple.write(1, DSR);
    DmxSimple.write(2, MSR);
    DmxSimple.write(3, USR);
    DmxSimple.write(4, USL);
    DmxSimple.write(5, MSL);
    DmxSimple.write(6, DSL);
    DmxSimple.write(7, PIT);
    DmxSimple.write(8, SOUND);    
      
    // Small delay to kill flicker    
     delay(5);
  }

Thanks gang!

I can’t see anything that should cause a delay in operation…. What sort of lag are you seeing ?

One thing that may make your code a bit tidier would be to implement arrays for the local values - and possibly a switch () case block instead of all the if() blocks.

When you get more comfortable, you could also start using enums, constants etc to refine the actual logic process - binding the addresses and names, which could shorten the code by a LOT.

I'm going to guess the problem is you're writing to every DMX device every time through the loop instead of only sending a message when something needs to be changed.

My understanding is that the DMX values need to be written every loop or else they default to 0 (Off). I could be wrong.

less than a second, and for some reason, only turning the lights ON, not turning them OFF... But every fraction could matter when you're trying to keep the show on time. If the OFF was ever affected, things could get delayed on stage.

All that advanced stuff sounds good, I guess I'll try to start learning myself at some point, but if you have an idea where to start (especially if it makes the loops a bit shorter or keep it running longer without issue) I'll take it.

That sounds like the same idea used on the CAN bus. Every command is valid for a limited amount of time. I think we used 250 mS for heavy vehicle motion control.
Of course, update immediately when things are changed but update not changed parameters on a time basis.
Check DMX up! What's the time frame there!
Google DMX!

Nothing obvious for what is causing delays.
As an aside to some of the other folks questions, DMX typically streams out data continuously, with a full "frame" rate between 30 and 44 Hz, (although the spec requires a minimum of 1Hz... some gear starts to flicker below this rate.

I redid the code with arrays and loops (obviously not tested on your hardware)

#include <DmxSimple.h>

 int switch_state_array[9];   /* This replaces the individual variables, and allows for easier loops
  Stage =0, DSR = 1, MSR =2, USR =3, USL =4, MSL =5, DSL =6, PIT =7, Sound =8.  
  
  */
  
void setup() {
  DmxSimple.usePin(3);

 
  DmxSimple.maxChannel(8);
  
  int count = 4;   // ********this replaces the individual lines for setting 4- 12 as inputs
  while (count <= 12) {
    pinMode(count, INPUT_PULLUP);
    count++;
  }
  
  }

void loop() {
  int myswitch[8];
  int count = 0;  //********* Also did this as a loop, and it makes switch an array
  while (count <= 8){
    myswitch[count] = digitalRead(count+4); // ********** The +4 is to account for sw 0 being pin4, etc
    count++;
  }
  
  count = 1; // *********** yup, anoyther array and while loop
  while (count <= 8){
    if (myswitch[count] == 0){
      switch_state_array[count] = 255;}
      else{
        switch_state_array[count] = 0;
    count++;}
    }
  
  if (myswitch[0] == 0) { //******** This loop sets all the switches to 255 if Stage is "0"
    count = 1;
    while (count <=8){
      switch_state_array[count] = 255;
      count++;
    }
    
   }

   count = 1;
   while (count <= 8){ // ******* and finally, this loop writes the data
    DmxSimple.write(count, switch_state_array[count]);
    count++; 
   } 
     delay(5);
  }

That looks great, I'll have to check it out at some point.

However, I forgot to post, but this turned out to be a loose wire instead of a software issue... Thanks though! Still might be worth looking into!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.