Using USB Midi Control Change info to control a LEDs

Status
Not open for further replies.

nicnut

Well-known member
Hi,

I am new to Teensy and not the best at writing code.

My goal is to use Midi Control Change info to control multiple LEDs (ultimately 14). I altered some example code and stuff I found on the forum to come up with the code I have now, for 2 LEDs and it works fine, but I am wondering if there is a better way to write this out. Also if the way I have it is the fastest way to transmit the messages over midi to control the LEDs. I want this to be as accurate as possible as I will be syncing this to audio midi messages in the end.

Let me know what you think. Thank you.

Code:
const int MIDIchannel = 2;   // this will only apply to midi channel 2
const int ledPin0 = 0;    // digital pin 0 
const int ledPin1 = 1;    // digital pin 1 
const int ledcontroller15 = 15;    // midi control change 15
const int ledcontroller16 = 16;    // midi control change 16



void setup() {
  pinMode(ledPin0, OUTPUT);
  pinMode(ledPin1, OUTPUT);
  usbMIDI.setHandleControlChange(myControlChange);

 // digitalWrite(ledPin, HIGH);
//  digitalWrite(ledPin, LOW);
}

void loop() {
  usbMIDI.read(MIDIchannel);
}

void myControlChange(byte channel, byte control, byte value)  {

  if (channel == MIDIchannel
      && control == ledcontroller15
      && value == 0) 

    digitalWrite(ledPin0, LOW);

      if (channel == MIDIchannel
      && control == ledcontroller15
      && value == 127) 

    digitalWrite(ledPin0, HIGH);    // note: short leg of LED connected to ground, long leg to digital pin

      if (channel == MIDIchannel
      && control == ledcontroller16
      && value == 0) 

    digitalWrite(ledPin1, LOW);

      if (channel == MIDIchannel
      && control == ledcontroller16
      && value == 127) 

    digitalWrite(ledPin1, HIGH);


  }
 
Seems fine to me. If you really want to be efficient (and we're really nit-picking here) is to restructure the conditional checks such that

- the same data (i.e. MIDIchannel) is not checked multiple times as it moves through the list
- if a condition fails (ledcontroller check), don't bother checking the next thing (value)
- once an LED controller has been matched, don't bother checking the rest of them (just return)

Now keep in mind, these enhancements are purely academic. Given the time it takes to execute the code as you wrote it, compared to something more optimised is negligible with respect to the time to transmit a MIDI message. The compiler will probably optimize your code to something more efficient than it looks anyway.

Code:
// This code assumes you are okay with CC values 0 and 127 being mapped, and 1-126 being ignored.
void myControlChange(byte channel, byte control, byte value)  {
    if (channel != MIDIchannel) return; // don't waste time checking anything else

    if (control == ledcontroller15) { // if this failes, don't bother checking the value
        if (value == 0) { digitalWriteFast(ledPin0, LOW); }
        else if (value == 127) { digitalWriteFast(ledPin1, HIGH); }
        return; /// don't bother checking the rest of the LEDs, we already know it was this one.
    }

    // repeat for each LED ...
}
 
Last edited:
Blackaddr, thank you for your response and feedback.

I tested the code and it seems super fast and responsive. I'll try and implement some of your suggestions and see if I can simplify this.

Thank you for your input!

Nick
 
Er... doesn't the read limit the messages processed to the channel already?

So it will always be true for messages not filtered out by the read command.
 
oddson, Oh yeah you are right. If the message is not on the specified midi channel, then it's not read. Thanks for the observation.
 
Status
Not open for further replies.
Back
Top