not all midi controller messages are parsed in arduino midi

I'm building a midi LED controller using the Arduino Playground - MIDILibrary

The LEDs do their thing and I can switch modes on MIDI CC messages, but for some reason, not all MIDI CC messages are parsed.

I'm puzzled. The hardware is fine, I'm sure. I tested it with simple code and everything works. I tested with a midi monitor and all messages are sent. I tried slowing down the rate of the messages being sent to eliminate overflow problems, but everything remains the same...
the magic happens inside the "HandleControlChange" function. If I hardcode a certain playmode in void setup() it will work fine.
I can't really debug as the Serial.print can't be combined with Midi as far as I know.
I tried changing the sequence of the "if" statements, didn't help, I tried using less ifs and all that...
sometimes it kinda works, but it gets stuck...

thanks.

K

void HandleControlChange (byte channel, byte number, byte value) {
 if (number == 29) {
      if (playmode4 == 0) { 
        fourstep();
      }
      else if (playmode4 == 1) { 
        foursteprev();
      }
      else if (playmode4 == 2) {
        if (state2 == 0) {
          turnall4on();
        } else {
          turnall4off();
        }
      }
      if (playmode4 == 3) { 
         flipAll();
      }
      
      if (playmode8 == 0) { 
        eightstep();
      }

      else if (playmode8 == 1) { 
        eightsteprev();
      }

      else if (playmode8 == 2) { 
        if (state6 == 0) {
          turnall8on();
        } else {
          turnall8off();
        }
      }

      else if (playmode8 == 3) { 
        two8();
      }
   }
    else if (number == 37) {
    Serial.print(number);  ///can't test if this works, Midi interferes   
    playmode4=0;
    
  }
    else if (number == 38) {  
      Serial.print(number);  
    playmode4=1;
  }
    else if (number == 39) {  
      Serial.print(number);  
    playmode4=2;
  }
    else if (number == 40) {  
      Serial.print(number);  
    playmode4=3;
  }
    else if (number == 27) {  
    playmode8=0;
  }
    else if (number == 28) {  
    playmode8=1;
  }
    else if (number == 32) {  
    playmode8=2;
  }
    else if (number == 30) {  
    playmode8=3;
  }
  
  else if (number == 18) {
   stroberate = 2*value; 
  }
   
}

When you say not all messages are parsed do you mean specific types or instances of messages that were successfully parsed before.
The problem is you are using a libary not writing the code yourself so you have no control over how it works. I have found that libary to be les than perfect, I normally write my own parser.

Ok, given the simple nature of the parsing, I might try. The handy thing for me was the library provides easy access to interrupt/callback mechanisms, a technique I’m not used to.

I’ll try code based on this (2007) forum post
http://forum.arduino.cc/index.php/topic,22447.0.html

Thanks

This is a better parser:-

void checkIn(){
  static byte note = 60;
  static byte state = 0;
  if (Serial.available() > 0) {
    // read the incoming byte:
    byte incomingByte = Serial.read();
    Serial.write(incomingByte);

  switch (state){
      case 0:
    // look for as status-byte, our channel, note on
         if (incomingByte == ( 0x90 | channel)){  // read only one channel
            noteDown = HIGH;
            state=1;
         }
    // look for as status-byte, our channel, note off
         if (incomingByte == (0x80 | channel)){   // read only one channel 
            noteDown = LOW;
            state=1;
        }
         // look for any after touch, or program message
         if ((incomingByte & 0xE0) == 0xC0){ 
            state=4;  // just wait for the data      
         }
         // look for any control or polyphonic after touch
         if ((incomingByte & 0xE0) == 0xA0){ 
            state=3;  // just wait for two bytes of data      
         }
         // look for any pitch wheel or Channel Mode data
         if ((incomingByte & 0xF0) == 0xA0 || (incomingByte & 0xF0) == 0xB0){ 
            state=3;  // just wait for two bytes of data      
         }
         break;
       case 1:
       // get the note to play or stop
          if(incomingByte < 128) {
             note=incomingByte;
             state=2;
          }
          else {
            state = 0;  // reset state machine as this should be a note number
          }
         break;      
       case 2:
       // get the velocity
          if(incomingByte < 128) {
              doNote(note, incomingByte, noteDown); // do something with the note on message
          }
          state = 0;  // reset state machine to start  
         break;
       case 3: // first of two bytes to discard
       state = 4; // next byte to discard
         break;       
       case 4: // data to discard
       state = 0; // reset state machine
     }
  }
}

If I get it correctly I should call my function at "case 3:" before the state is set to 4 and pass it the incoming byte to see if it matches my CC number (e.g. CC37 -> 0x25)
according to

while checking this I thought I might have found the bug: Could my problem simply be that I'm comparing the

void HandleControlChange (byte channel, byte number, byte value) {
if (number == 29) {

and I'm comparing the "number , a 'byte' with an integer? or is that not a problem? Can I compare integers with bytes?

K

If I get it correctly I should call my function at "case 3:"

No not if it just a note on / off message you are looking for, your call replaces this:-

doNote(note, incomingByte, noteDown);

Can I compare integers with bytes?

If you are not sure then you can always cast them:-

f (number == (byte)29) {

Lately the compiler has become a bit fussy about this sort of thing. The software heads are cool with it but it pisses me off.

Yeah, but I can't change the midi source, it's CC 29 and on .

back at the arduino, let's try the bytecasting

problem solved!

the source was sending dirty messages along with the correct messages completely flooding the main messages. so I’m filtering (what I was doing in my monitor app, but not on the main midi out ) before the data reaches the arduino, my code was fine.
you made me think of changing the source and this is how I found it. Thanks!

Thanks!