MIDI in Code, without MIDI Library

Hi, here is a code snippet i use with great success in an arduino midi controller, it does not use the midi library and the code is therefore much smaller. also i had problems using the midi library with an arduino micro, it messed up the usb connection and i had to reflash via headers…

this code handles all the midi messages (with running status) except for system exclusive messages.

so, i thought i share, please correct anything that could be more efficiently done (for speed)! this is based on grumpy mikes code, so thank you grumpy mike!!

//some random cc numbers:
#define SAVE_CC 120
#define CHANNELMODE_CC 119
#define FULLLEGATO_CC 118
#define OCTAVE_CC 117
#define STICK_CC 116

//midi in variables
byte state = 0;
byte statusByte;
byte dataByte1;
byte dataByte2;



void setup() {
  //start serial with MIDI baud rate 31250 or another standard speed for debugging
  Serial.begin(31250);   
}

void loop() {
  // put your main code here, to run repeatedly:
MidiIn();
}

void MidiIn(){
  if (Serial.available() > 0) {
    // read the incoming byte:
   byte incomingByte = Serial.read();
  
   switch (state){
      case 0:
      if (incomingByte > 0x7F && incomingByte < 0xF0 ){    // this reads all statusbytes, realtime stuff is ignored
         statusByte = incomingByte;
         state=1;
        }
        if (incomingByte == 0xF0) state=3;
       case 1:
       // get first databyte
       if(incomingByte < 0x80) {
        dataByte1 = incomingByte;
        //check for two byte messages...
       if ((statusByte & 0xF0) == 0xC0 | (statusByte & 0xF0) == 0xD0) {
        midiParser();
        state = 0; //reset state machine 
       } else state = 2;
       } else{
      state = 0;  // reset state machine as this should be a note number
      }
       break;
       
       case 2:
       // get second databyte
       if(incomingByte < 0x80) {
       dataByte2 = incomingByte;
       }
       midiParser();
         state = 0;  // reset state machine to start
         break;
          //stay here for sysex, wait for it to end...
         case 3:
         if (incomingByte == 0xF7) state=0;
         if(incomingByte > 0x7F && incomingByte < 0xF0) {
              statusByte = incomingByte;
              state=1;   
         }
         break;
  }
}
}
void midiParser(){
  switch (statusByte){
    
    case 0xC0: //program change
    //do something when a program change arrives, prg nr is dataByte1
    break;
    case 0xB0: //cc messages 
    switch (dataByte1) {
      case SAVE_CC:
      //do something here
      break;
      case CHANNELMODE_CC:
      //do something else
      case STICK_CC:
      //again something on this cc
      break;
      case FULLLEGATO_CC:
      //you get the idea
      break;
      case OCTAVE_CC:
     //octaves!!!
    break;
  }
}
}

Hi, I was wondering If you could help me use your method to change this code so that the MIDI library isn't used. I am trying to convert it to raw c, or c ++. Can PM you ? Thanks

Maybe you could have a look to my light midiXParser class released to the open source community, handling also everything from basic midi messages, and more complex like running status and sysex. https://github.com/TheKikGen/midiXparser

example :

midiXparser midiParser;
midiParser.setChannelVoiceMsgFilter(midiXparser::noteOffMsk | midiXparser::noteOnMsk );  
loop() 
{

    if ( Serial.available() && ( midiParser.parse( Serial.read() ) {
    // Do something for notes on/off

    } 
    (...)  
}

This is more "low level" than the very good midi library from FortySevenEffects but it does the job quite well. A bunch of tests are provided with the demo INO sketch...

lokki:
i had problems using the midi library with an arduino micro, it messed up the usb connection and i had to reflash via headers…

and it is not possible that the MIDI library messed up your board…it is probably your hardware causing that.
Remember that USB serial and Arduino UART share RX & TX, so you must isolate them with a switch…or disconnect MIDI cable.