MIDI CC Serial - LED Brightness Issue

Hi Friends,

I'm attempting to receive MIDI IN data on my Arduino to automate the brightness of an LED.

I don't have very much experience with coding and this project is a complete introduction to MIDI for me. I based my project off the information from this Instructable. http://www.instructables.com/id/Send-and-Receive-MIDI-with-Arduino/step9/Receive-MIDI-Messages-with-Arduino/

I can get the basic idea to work. As I change cc value the LED will dim. However, rather frequently the LED will bounce up to full brightness. This leads me to think that there's a way better way of receiving MIDI Serial Data. I've also noticed that the higher delay time I use, the less likely the LED is to misfire.

I found this Arduino Library Arduino MIDI Library: MIDI_Class Class Reference and was pretty excited at first, but then noticed that the Third Data Byte is conspicuously missing. Perhaps it goes by another name? Not sure how to go about using it for this project.

So, I'm looking for general guidance on how to accurately receive and implement MIDI Serial CC data. In the end this project will use three CCs and 3 LEDs.

Thanks!

PS. My circuit is good to go.

int led = 11;

byte firstByte;
byte secondByte;
byte thirdByte;

void setup(){
  pinMode (11, OUTPUT);
  Serial.begin(31250);
  analogWrite(11, 100);
}

void checkMIDI(){
  do{
    if (Serial.available()){
      firstByte = Serial.read();//read first byte
      secondByte = Serial.read();//read next byte
      thirdByte = Serial.read();//read final byte
        }
      }
  while (Serial.available() > 24);//when three bytes available
}
 
void loop(){
  checkMIDI(); 
  if (firstByte == 176 && secondByte == 48){
    analogWrite(led, thirdByte * 2); 
  }
  delay(50);
}

I've also tried using the Interrupt Code mentioned in the Instructable with zero results.

int led = 11;

byte firstByte;
byte secondByte;
byte thirdByte;

void setup(){
  pinMode (11, OUTPUT);
  analogWrite(11, 100);
  Serial.begin(31250);
  cli();//stop interrupts
  //set timer2 interrupt every 128us
  TCCR2A = 0;// set entire TCCR2A register to 0
  TCCR2B = 0;// same for TCCR2B
  TCNT2  = 0;//initialize counter value to 0
  // set compare match register for 7.8khz increments
  OCR2A = 255;// = (16*10^6) / (7812.5*8) - 1 (must be <256)
  // turn on CTC mode
  TCCR2A |= (1 << WGM21);
  // Set CS11 bit for 8 prescaler
  TCCR2B |= (1 << CS11);   
  // enable timer compare interrupt
  TIMSK2 |= (1 << OCIE2A);  
  sei();//allow interrupts  
}


ISR(TIMER2_COMPA_vect) {//checks for incoming midi every 128us
  do{
    if (Serial.available()){
      firstByte = Serial.read();//read first byte
      secondByte = Serial.read();//read next byte
      thirdByte = Serial.read();//read final byte
    }
  }
  while (Serial.available() > 24);//when three bytes available
}

void loop(){
  if (firstByte == 176 && secondByte == 48){
    analogWrite(led, thirdByte * 2); 
  }
}
  do{
    if (Serial.available()){
      firstByte = Serial.read();//read first byte
      secondByte = Serial.read();//read next byte
      thirdByte = Serial.read();//read final byte
        }
      }
  while (Serial.available() > 24);//when three bytes available

The body of a do/while loop is executed at least once. Suppose that there is only one byte of data to be read. You check that, and then read all 3 of the one available. Oops.

Then, you check that there are at least 24 before the loop is executed again.

A while loop, on the other hand, would not require 2 calls to Serial.available() and would assure that the mistake made here didn't happen.

PaulS,

My feeble mind is just barely capable of grasping this concept, but I think I got it.

Is this what you had in mind?

BTW it appears to be working properly.

Thanks for your help!

void checkMIDI(){
    while (Serial.available() > 24){
      firstByte = Serial.read();//read first byte
      secondByte = Serial.read();//read next byte
      thirdByte = Serial.read();//read final byte
        }
      }

Is this what you had in mind?

Yes, but I'm curious why you need there to be 25 bytes in the buffer before you read 3, over and over, until there are less than 25 bytes to read, leaving 23 or 24 bytes in the buffer.

I actually don't know at all.

I'm very new to programming and was really just using this person's code as a base. Not sure why she constructed it this way.

I'm sorry to ask this, but what would the preferable code look like?