Go Down

Topic: Receiving MIDI Signals (Read 3286 times) previous topic - next topic

Hi everybody,

I have been trying to receive MIDI messages using my Arduino Uno and the circuit shown here...


I have built the MIDI interface on a breadboard and am receiving signals from a keyboard.
Instead of connecting LED's like in the above post I am trying to control an 8x8 LED matrix. So far the MIDI input works however the response is slow and unreliable. If I play notes slowly the LED's will turn on and off as they are suppose to however if you play a note quickly the noteOff messages are missed. More specifically, striking a key quickly turns the LED on but not off.

Similarly, playing runs of notes quickly produces unreliable results with most of the messages on and off being missed.

On the other hand, if I play 4 of 5 notes at the same time the appropriate LED's turn on and off as expected. As long as you play slowly (keep each key pressed for at least a full second) the lights turn on and off.

I have modified the the code to use the Arduino Midi library instead of listening to the serial port like in the original post. This works slightly better however it still seems to be lagging behind.

Code: [Select]
  if (MIDI.read()) {
    if (MIDI.getType() == NoteOn) {
     // get note value
      byte dat1 = MIDI.getData1();
      // get velocity (though I'm not using it)
      byte dat2 = MIDI.getData2();
      // map MIDI note value to 8x8 array
      int row = dat1/8;
      int col = dat1%8;
      // my keyboard sends noteOn with 0 velocity instead of noteOff messages
      if (dat2 > 10) {
        displayGrid[row][col] = 1;
      else {
        displayGrid[row][col] = 0;


The semantics on controlling the lights are not really important here. The 8x8 array is controlled by a 8x8 array on ints in memory. 0 for off, 1 for on. I simply change these values and refresh the display. This code comes from an old project and works fine.

Is the issues here the MIDI interface and am I better off building the one prescribed here.

Thanks heaps


am I better off building the one prescribed here.

The MIDI schematics described in those two links you posted are virtually the same are they not?

Your problem might be in using the MIDI library, I am not a great fan of libraries because all the code is hidden away. I think it is best to write your own, after all it is not at all a hard thing thing to do. The code in this project of mine shows you how to do it:-


Hi Grumpy_Mike,

Thanks for the reply. I guess the circuits are the same however I thought the speed of the opto-isolator might be causing an issue. Just something I was reading in other posts but if they are the same I doubt it will matter.

In regards to the code, I didn't originally start with the MIDI library. I was using the code from the blog, I just changed it to turn on LEDs in the matrix instead of LEDs connected to pins 2-9. However, with this setup playing chords would only turn on one LED instead of multiple.

The following code is from the forum entry I got the circuit from. The only thing I have changed is the playNote method which now turns on LEDs in a matrix instead of LEDs connected directly to a port.
Code: [Select]
//variables setup

byte incomingByte;
byte note;
byte velocity;

int statusLed = 13;   // select the pin for the LED

int action=2; //0 =note off ; 1=note on ; 2= nada

//setup: declaring iputs and outputs and begin serial
void setup() {
  pinMode(statusLed,OUTPUT);   // declare the LED's pin as output
  //start serial with midi baudrate 31250 or 38400 for debugging

//loop: wait for serial data, and interpret the message
void loop () {
  if (Serial.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial.read();

    // wait for as status-byte, channel 1, note on or off
    if (incomingByte== 144){ // note on message starting starting
    }else if (incomingByte== 128){ // note off message starting
    }else if (incomingByte== 208){ // aftertouch message starting
       //not implemented yet
    }else if (incomingByte== 160){ // polypressure message starting
       //not implemented yet
    }else if ( (action==0)&&(note==0) ){ // if we received a "note off", we wait for which note (databyte)
      playNote(note, 0);
    }else if ( (action==1)&&(note==0) ){ // if we received a "note on", we wait for the note (databyte)
    }else if ( (action==1)&&(note!=0) ){ // ...and then the velocity
      playNote(note, velocity);

void blink(){
  digitalWrite(statusLed, HIGH);
  digitalWrite(statusLed, LOW);

void playNote(byte note, byte velocity){
  int value=LOW;
  if (velocity >10){

//since we don't want to "play" all notes we wait for a note between 36 & 44
if(note>=36 && note<44){
   //byte myPin=note-34; // to get a pinnumber between 2 and 9
   //digitalWrite(myPin, value);

  //modified to control an 8x8 array
      // map MIDI note value to 8x8 array
      int row = note/8;
      int col = note%8;
        displayGrid[row][col] = value;


With this approach the response seems to be a bit faster (the delay between pressing and releasing a key can be smaller) but when you play chords only one LED lights up. Using the MIDI library seems to be slower (the delay between releasing the key must be at least a second for the note off to register) but playing chords causes multiple LED's to turn on and off.  I basically want the lights in the 8x8 matrix to turn on and off as I play the keyboard.

I had a look at your glockenspiel project the other day. Really cool. The code you have implemented is similar to the original approach I used. I will have a go at it with your code in the morning.


Yes that looks like my code with some hacking done to it.  :) ( I wrote it from scratch and those are my variable names and comments )

but when you play chords only one LED lights up.

The bit of code that does the LED lighting is not posted so I can only guess.
However, make sure that the note on message turns on the LED only and doesn't turn any off and the note off message turns off the LED.
I think you will find that the note on message is turning off existing LEDs.

:) Snippets on that code appear in almost every MIDI in reference I have looked at lol.

I'm not to sure what your saying. A noteOn message changes the values in displayGrid
  • [y] to 1 and a noteOff (or noteOn with velocity <10) sets the value to 0. Based on that I update the matrix with the method below.

    This is the code that updates the matrix. It is called each time the loop iterates.
    Code: [Select]
    void refreshDisplay() {
    for(int x=0; x<LEDs; x++) {
        for (int y=0; y<LEDs; y++) {
          if (displayGrid[x][y] == 1) {
          else {


It's libraries again, I have no idea what lc.setLed() does with its parameters, especially as the first one is always zero. 
By the way there is no need to do the two stage approach, setting an array and then transferring it into your library functions, just use the lc.setLed() function directly in the place where you set an array at the moment.

(or noteOn with velocity <10) sets the value to 0.

acording to the MIDI standard it should be:-
noteOn with velocity == 10 sets the value to 0.

Yes fair enough. That library controls the max7219 that runs the matrix.
Code: [Select]

lc.setLed(int deviceID, int col, int row, boolean isOn);

And good point about not needing the array. That's just habbit from the last project. To put this in context, I have wired up a LED matrix ( as shown here http://arduino.cc/playground/Main/LedControl as a set of Christmas lights for my tree. I currently have them doing various effects and flashing along to a few Christmas carols but I thought why not go all out and put those hours I spent as a child learning Christmas carols to good use and sync it up with my keyboard.

I'll sleep on it and tackle this again after work tomorrow.

Thank you for you help


If you want to continue to use the MIDI library, you can simplify your code a lot by using the event handlers. To do that, in your setup function:
Code: [Select]
  // Initiate MIDI communications, listen to all channels, turn off thru mode
  // By default, the MIDI library sends everything THRU. We do NOT want that!

  // Connect MIDI status changes involving a channel to handlers

Then, create a function for handling note on and note off:

Code: [Select]
void HandleNoteOn(byte channel, byte pitch, byte velocity) {
// check your pitch, velocity, and channel here
// turn on the LED matching pitch
void HandleNoteOff(byte channel, byte pitch, byte velocity) {
// check your pitch, velocity, and channel here
  // turn off the LED matching pitch

Now your loop function is simple:
Code: [Select]

void loop() {

Hi mymeastro,

Thanks for the post. I tried it that way and it is working much better. Its still not fast enough to keep up with me playing though.

I'm gonna break this down and start from scratch as Im on holidays for 2 weeks in 2 days. Well not from scratch, just simplify the project a little and try to control a couple of LED's like in the original post I looked at. That way I can test the MIDI interface and code a little more accurately rather than stuffing around with the matrix.


You don't need to refresh the entire grid each time!
Just change the specific LED that relates to the MIDI note. The 7219 will take care of the rest.

Thanks mymeastro,

yes I am aware of that. My note on and note off handlers address the LED's directly.
A note value is converted to an x,y co-ordinate and that single LED is turned on or off.

Still not fast enough,


I wonder if the on notes and hence LEDs are falling between the cracks. That is if the duration of the note is less than the time it takes to reload the data into the matrix driver.
Just as a test. Comment out the LED off part and see if those notes are actually being caught.



Do you have a mean of measuring the time spent in MIDI.read? (which is the time used to parse MIDI input messages).

I did some tests while developing the new input processing code (parser) that is used since version 2.5 (if I remember correctly), and with a little bit of processing code (like toggling lights), the lag was not a problem. However, if you are doing more in your handling code, it will slow the loop thus slow the speed at which input MIDI is read.

If the read() method is not fast enough for you, I can try and find where the parser is taking too much time, and see if I can do something about it.

Anyway, make sure you are using the latest version of the library (available on Sourceforge).

Arduino MIDI Library:
GitHub: https://github.com/FortySevenEffects/arduino_midi_library
Playground: http://ww

Dec 22, 2011, 02:53 pm Last Edit: Dec 22, 2011, 03:44 pm by fireman_sam6986 Reason: 1
I think the issues is the MIDI interface I made or the delay in talking to the LED matrix. Im going to rebuild the interface with one of Grumpy Mike's designs.

Anyway, I am going to try to drive a few LED's directly rather than manipulating the matrix. Simplify and remove possible sources of error. The only issue now is I seems to have blown up my Arduino :P (or at least the USB or Serial part) Serves me right for trying to re-wire the MIDI interface after a 13 hour day. Plugged the wrong MIDI cable in, smelt smoke, now the Uno doesn't do much but power up.

Guess i'll have to wait for a new one to ship unless Santa is feeling generous.

Thanks for the help on this everyone, I will post back when I have made some more progress.


I have just had a thought, maybe your keyboard is going into the rarely used follow on mode. This is where the note on / note off byte is dropped and just the other two bytes are sent. My code does not cater for this but this modification will:-

Code: [Select]
  if (Serial.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial.read();
     digitalWrite(strobe,LOW);    // clear any previous strobe
   switch (state){
      case 0:
    // look for as status-byte, our channel, note on
    if (incomingByte== (144 | channel)){
         noteDown = HIGH;
    // look for as status-byte, our channel, note off
    if (incomingByte== (128 | channel)){
         noteDown = LOW;
      // consider follow on mode
       if(incomingByte< 128){
        // use same noteDown as last time
       case 1:
       // get the note to play or stop
       if(incomingByte < 128) {
       state = 0;  // reset state machine as this should be a note number
       case 2:
       // get the velocity
       if(incomingByte < 128) {
         playNote(note, incomingByte, noteDown); // fire off the solenoid
         state = 0;  // reset state machine to start           

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131