Simple LED/MIDI setup but only 3 leds will light...

Hi,

I have a simple breadboard setup where I have four leds connected to pins digital pins 13, 12, 11 & 10. I have a midi feed coming in via hairless midi that plays notes 60 (kick drum), 64 (snare), 69 (tambourine) and 71 (hi hat).

Code is very simple, below, I borrowed it and tweaked a bit. It works fine on the first three leds, flashing in time to the different instruments, but always ignores the fourth. I know the fourth works because if I change the code so it does digitalWrite in the order 13, 12, 10, 11, I find that 13, 12 & 10 work but 11 doesn't.

This feels like some kind of logical limit: "Thou shalt not write to more than 3 leds on separate digital pins". Or am I missing something obvious in the code?

byte commandByte;
byte noteByte;
byte velocityByte;

byte noteOn = 144;

//light up led at pin 13 when receiving noteON message with note = 60

void setup(){
  Serial.begin(57600);
  pinMode(13,OUTPUT);
  pinMode(12,OUTPUT);
  pinMode(11,OUTPUT);
  pinMode(8,OUTPUT);
  digitalWrite(13,LOW);
  digitalWrite(12,LOW);
  digitalWrite(11,LOW);
  digitalWrite(8,LOW);
}

void checkMIDI(){  
  do{   
    if (Serial.available()){  
      commandByte = Serial.read();//read first byte
      noteByte = Serial.read();//read next byte
      velocityByte = Serial.read();//read final byte
      
      if (commandByte == noteOn){//OB4 if note on message
        //check if note == 60 and velocity > 0
      
        if (noteByte == 60 && velocityByte > 0){  
          digitalWrite(13,HIGH);//turn on YELLOW led
        }
        if (noteByte == 64 && velocityByte > 0){  //OB5
          digitalWrite(12,HIGH);//turn on BLUE led
        }   //CB1
        if (noteByte == 69 && velocityByte > 0){  //OB5
          digitalWrite(10,HIGH);//turn on RED led
      
        if (noteByte == 71 && velocityByte > 0){  //OB5
          digitalWrite(11,HIGH);//turn on GREEN led 
        }
       }
      }   
    }    
  }   
  while (Serial.available() > 2);// when at least three bytes available
}  
    

void loop(){
  checkMIDI();
  delay(100);
  digitalWrite(13,LOW);//turn led off
  digitalWrite(12,LOW);//turn led off
  digitalWrite(11,LOW);//turn led off
  digitalWrite(10,LOW);//turn led off  
}

Thanks

I think you misplaced one '}'. You are closing the if statement 'if(noteByte == 68 && velocityByte ) 0)' after the enxt iff statement.

Does this code work:

byte commandByte;
byte noteByte;
byte velocityByte;

byte noteOn = 144;

//light up led at pin 13 when receiving noteON message with note = 60

void setup(){
  Serial.begin(57600);
  pinMode(13,OUTPUT);
  pinMode(12,OUTPUT);
  pinMode(11,OUTPUT);
  pinMode(8,OUTPUT);
  digitalWrite(13,LOW);
  digitalWrite(12,LOW);
  digitalWrite(11,LOW);
  digitalWrite(8,LOW);
}

void checkMIDI(){  
  do{   
    if (Serial.available()){  
      commandByte = Serial.read();//read first byte
      noteByte = Serial.read();//read next byte
      velocityByte = Serial.read();//read final byte
      
      if (commandByte == noteOn){//OB4 if note on message
        //check if note == 60 and velocity > 0
      
        if (noteByte == 60 && velocityByte > 0){  
          digitalWrite(13,HIGH);//turn on YELLOW led
        }
        if (noteByte == 64 && velocityByte > 0){  //OB5
          digitalWrite(12,HIGH);//turn on BLUE led
        }   //CB1
        if (noteByte == 69 && velocityByte > 0){  //OB5
          digitalWrite(10,HIGH);//turn on RED led
        }
        if (noteByte == 71 && velocityByte > 0){  //OB5
          digitalWrite(11,HIGH);//turn on GREEN led 
        }
      }   
    }    
  }   
  while (Serial.available() > 2);// when at least three bytes available
}  
    

void loop(){
  checkMIDI();
  delay(100);
  digitalWrite(13,LOW);//turn led off
  digitalWrite(12,LOW);//turn led off
  digitalWrite(11,LOW);//turn led off
  digitalWrite(10,LOW);//turn led off  
}

Hope this fixes your problem!

Yes that's fixed it - thanks!

I counted the { and thought there were the same number of matching }. Is that the right approach?

Yes, but it is error prone, as you have found. Having the correct number of matching brackets means that your sketch should compile, but if some of those brackets are in the wrong place, your code won't work as you intended it, and the compiler can't spot that for you.

The IDE has a couple of useful features that will help. One is Tools-->Auto Format. This will help you by indenting the code so that you can see which lines belong to the same block of code. Also, if you put the cursor next to a { or }, it will highlight the corresponding } or { for you.

For example, if you take your sketch above and apply Auto Format, you get:

void checkMIDI() {
  do {
    if (Serial.available()) {
      commandByte = Serial.read();//read first byte
      noteByte = Serial.read();//read next byte
      velocityByte = Serial.read();//read final byte

      if (commandByte == noteOn) { //OB4 if note on message
        //check if note == 60 and velocity > 0

        if (noteByte == 60 && velocityByte > 0) {
          digitalWrite(13, HIGH); //turn on YELLOW led
        }
        if (noteByte == 64 && velocityByte > 0) { //OB5
          digitalWrite(12, HIGH); //turn on BLUE led
        }   //CB1
        if (noteByte == 69 && velocityByte > 0) { //OB5
          digitalWrite(10, HIGH); //turn on RED led

          if (noteByte == 71 && velocityByte > 0) { //OB5
            digitalWrite(11, HIGH); //turn on GREEN led
          }
        }
      }
    }
  }
  while (Serial.available() > 2);// when at least three bytes available
}

You can see immediately that the if() that deals with code 71 is at a different level of indentation to the other 3 if() that deal with codes 60, 64 & 69.

As PaulRB already explained, counting the brackets doesn't mean that they are at the right place. Indeed there were enough }'s, but one of them was in the wrong place.