Intermittent Failure Reading MIDI Messages

I've built a circuit for receiving MIDI messages following sa design posted to these forums (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1187962258/), and I've encountered an odd problem. The arduino receives only a fraction of the midi messages that I send, as evidenced by the blinking of the Rx LED--maybe one in ten if I send a message every second. If, however, I wait about five seconds or more between messages, the arduino receives each one. It needs this recovery time even though it doesn't do much, if anything after receiving a message.

My code is identical to that of the post linked to above, except that I call blink() from the playNote method. The MIDI signal is sent from MAX/MSP via a MOTU Traveler. I'm completely baffled. Ideas?

Patrick

as evidenced by the blinking of the Rx LED

That might be your problem. The time taken to blink could be blocking the receiver and overflowing the input buffer, try something like just toggling the LED.

@GrumpyMike,

I've been thinking along the same lines; that the execution of some task blocks the input buffer, but I haven't been able to figure out what that task would be. And when I wrote "blink," I meant toggle. To clear things up, here's the code I'm using, which is a simplified version of the original sketch, which listens only for Note-Ons:

//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
Serial.begin(31250);
digitalWrite(statusLed,HIGH);
}

//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
action=1;
}else if ( (action==1)&&(note==0) ){ // if we received a "note on", we wait for the note (databyte)
note=incomingByte;
}else if ( (action==1)&&(note!=0) ){ // ...and then the velocity
velocity=incomingByte;
playNote(note, velocity);
note=0;
velocity=0;
action=0;
}
}
}

void playNote(byte note, byte velocity){
toggle();
}

void toggle(){
digitalWrite(statusLed, HIGH);
delay(10);
digitalWrite(statusLed, LOW);
delay(1);
}

To recap, if I wait about five seconds between notes, I can toggle the LED. Note-ons sent more frequently will toggle the LED about one in ten times. Also strange is that I can get the same behavior, keeping the code the same, with any status byte between 144 and 149, inclusive. Even though the sketch is supposed to look for status byte 144, 145 through 149 are treated equivalently. I can toggle the LED with 149-38-100 (once every five seconds, roughly) even though that shouldn't work at all.

To make sure the problem isn't with the MIDI cable or the Traveler, I've plugged the Traveler's output back into itself and read the input in MAX. Everything checks out there.

What is particularly frustrating is that I have gotten this circuit to work in the past and have used it successfully for months! I had uploaded a different sketch to troubleshoot an unrelated (probably) problem, and when I uploaded the old code, it didn't work. I've now isolated just the MIDI In circuit on a breadboard to make sure no other components are interfering, and I'm still getting this strange, lazy serial reader problem.

I know you said that this code has worked before I cant help but notice it is rather trusting in that it expects data to be consistent. There is no provision for re synchronizing the data or doing a running status byte. It is a weakness of the MIDI system that the system exclusive message is one of undetermined length. This means it is imposable to always synchronise what you expect to what you get.
The upshot of this rambling is that there may be something extra getting in the data stream and messing things up.
Have you tried looking at the raw MIDI data coming out of your system with some sort of MIDI monitor?
Why not take out the delay altogether and actually toggle the LED on each note on event.

Problem solved. It was the running status byte (thanks, Mike!) that threw everything off. The code that I had gotten to work must have used a slightly different logic, which is easy to do when you spread a project across three computers.

The risky code that I posted above came from the original MIDI In sketch and schematics posted to these forums a year or two ago, which makes me wonder how many other people have and will encounter this problem. It would corrupt any effort to turn off notes by sending a Note-On message with 0 velocity.