MIDI to DMX Simple light controller issues

Hi there! I've built a MIDI to DMX converter around an Arduino Nano board and written a simple program that converts MIDI note and velocity information into DMX light Channel and Intensity information. It's largely based on this project: MIDI to DMX using Arduino with a few slight changes - I used an H11L1 IC for the MIDI side, added some LEDs for power and MIDI data indicators. The code uses DmxSimple.h and MIDI.h libraries.

After some troubleshooting I've got the project built and working, but I had to add a bit of code that doesn't make any sense to me and I'm trying to figure out why it's needed and/or if I did something wrong.

I'm controlling two lights with four personalities each (1: Intensity 2: Red 3: Green 4: Blue), so I'm using DMX Channels 1-8. My code turns the intensity of both lights to 255 when it boots up, then cycles through each color light to test that they're all working.

The code then translates MIDI Note and Velocity info to DMX Channel and Intensity info respectively. So if you play MIDI note 2 on a keyboard (or through my DAW) at velocity 127 it turns on light channel 2 (red on light fixture 1) at intensity 255. All well and good, works like it should.

However...

For the longest time I couldn't get the second light fixture to work. Eventually I discovered that after I played MIDI note 12, so, sending some information, any value, to DMX channel 12, then the second light would work without any further issue. I've added a line to turn channel 12 to full intensity when the device boots up, and now it works as originally expected. This makes no sense to me, since DMX channel 12 is out of the scope of both the code I've written and the fixture I'm using.

Here's my code:

// MIDI to DMX converter / controller

#include <MIDI.h>
#include <DmxSimple.h>
#include <avr/pgmspace.h>
#include <millisDelay.h>

// Define global variables

#define POWER_LED 3
#define TEMPO_LED 8
#define DMX_OUT 13
#define DMXCHANNELS 8

// Local variables

bool initialized;
bool tempoLedOn;
int tempoLedCycles;
millisDelay ledDelay1;
millisDelay ledDelay2;
millisDelay ledDelay3;
millisDelay ledDelay4;
millisDelay ledDelay5;
millisDelay ledDelay6;
millisDelay ledDelay7;

// Create instance of MIDI library with default name, serial port and settings

MIDI_CREATE_DEFAULT_INSTANCE();

// Program setup, runs once:

void setup() {

  // Setup LEDs
  pinMode(POWER_LED, OUTPUT);
  pinMode(TEMPO_LED, OUTPUT);
  digitalWrite(POWER_LED, HIGH);
  digitalWrite(TEMPO_LED, HIGH);
  // Timers for boot cycle/light test
  ledDelay1.start(1000);
  ledDelay2.start(1100);
  ledDelay3.start(1200);
  ledDelay4.start(1300);
  ledDelay5.start(1400);
  ledDelay6.start(1500);
  ledDelay7.start(1600);
  
  // Setup MIDI behavior
  MIDI.begin(16);                        // Sets the MIDI channel to 16
  MIDI.setHandleNoteOn(OnMidiNoteOn);    // Sets the response to a 'Note On' MIDI event to the MIDINoteOn function
  MIDI.setHandleNoteOff(OnMidiNoteOff);  // Sets the response to a 'Note Off' MIDI event to the MIDINoteOff function

  // Setup DMX behavior
  DmxSimple.usePin(DMX_OUT);
  DmxSimple.maxChannel(8);
  // !!! ??? WHY DO I NEED THIS ??? !!! //
  DmxSimple.write(12, 255);
  // Turn on the lights to test them
  DmxSimple.write(1, 255);
  DmxSimple.write(2, 255);
  DmxSimple.write(3, 255);
  DmxSimple.write(4, 255);
  DmxSimple.write(5, 255);
  DmxSimple.write(6, 255);
  DmxSimple.write(7, 255);
  DmxSimple.write(8, 255);
}

// Program loop, runs continuously:

void loop() {
  // Dim lights and tempo LED after a second
  if (ledDelay1.justFinished()) { 
    digitalWrite(TEMPO_LED, LOW);
    //DmxSimple.write(1, 255);
    DmxSimple.write(2, 0);
    DmxSimple.write(3, 0);
    DmxSimple.write(4, 0);
    //DmxSimple.write(5, 255);
    DmxSimple.write(6, 0);
    DmxSimple.write(7, 0);
    DmxSimple.write(8, 0);
  }
  if (ledDelay2.justFinished()) { 
    digitalWrite(TEMPO_LED, HIGH);
    DmxSimple.write(2, 255);
    DmxSimple.write(6, 255);    
  }
  if (ledDelay3.justFinished()) { 
    digitalWrite(TEMPO_LED, LOW);
    DmxSimple.write(2, 0);
    DmxSimple.write(6, 0); 
  }
  if (ledDelay4.justFinished()) { 
    digitalWrite(TEMPO_LED, HIGH);
    DmxSimple.write(3, 255);
    DmxSimple.write(7, 255); 
  }
  if (ledDelay5.justFinished()) { 
    digitalWrite(TEMPO_LED, LOW);
    DmxSimple.write(3, 0);
    DmxSimple.write(7, 0); 
  }
  if (ledDelay6.justFinished()) { 
    digitalWrite(TEMPO_LED, HIGH);
    DmxSimple.write(4, 255);
    DmxSimple.write(8, 255); 
  }
  if (ledDelay7.justFinished()) { 
    digitalWrite(TEMPO_LED, LOW);
    DmxSimple.write(4, 0);
    DmxSimple.write(8, 0);   
  }

  // MIDI Read to for 'handler' functions
  MIDI.read();

}

// Function for MIDI Note On behavior:

void OnMidiNoteOn(byte channel, byte pitch, byte velocity) {
  if (pitch != 1 && pitch != 5) {
    //DmxSimple.write(1, 255);
    //DmxSimple.write(5, 255);
    DmxSimple.write(pitch, velocity * 2);
  }
  digitalWrite(TEMPO_LED, HIGH);
}

// Function for MIDI Note Off behavior:

void OnMidiNoteOff(byte channel, byte pitch, byte velocity) {
  if (pitch != 1 && pitch != 5) {
    //DmxSimple.write(1, 255);
    //DmxSimple.write(5, 255);
    DmxSimple.write(pitch, 0);
  }
  digitalWrite(TEMPO_LED, LOW);
}

I also tried removing all the boot-up light-check code in case that was somehow causing the problem, but it didn't help, I still needed to send MIDI note 12 info to the device before channels 5-8 would work. Similarly, reassigning the light fixtures' channels didn't make a difference - the problem followed whichever light was assigned to channels 5-8.

Hoping someone out there knows what I did wrong and/or what I could do more right?

Thanks!

What device are you sending commands to?

Using the pin 13 as output on Nano is not a good idea because the on-board led...

1 Like

Well you could switch to a dmx library that uses the UART rather than using one that bit-bangs the 250kbps signal. The answer to your question

is most likely in the dmxSimple.h & .cpp files.
Looking at it it doesn't actually quite make sense, because the default is sending to the first 16 channels.
Still even though it gives you the ease of choosing your own output pin, dmxSimple is very CPU intensive and a UART based library is much preferred. Midi can easily be received on swSerial anyway, (which is of course also cpu intensive but much lees than this solution)

1 Like

The Arduino Nano, which is passing it along to a pair of DMX lamps.

Did not know that, thanks! What is the disadvantage?

This is great info, thanks! I'm pretty nooby, so DmxSimple seemed a good point of entry, but I guess I have some more reading to do... thanks again!

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