Go Down

Topic: Arduino Midi to Gate (Read 193 times) previous topic - next topic

Raymond_Bagdust

Sep 25, 2017, 03:41 pm Last Edit: Sep 25, 2017, 04:36 pm by Raymond_Bagdust
I am building a MIDI to gate converter using Arduino Mega to trigger a analogue drum machine circuit via the PWM pin outputs.

I have the MIDI input working (see http://www.instructables.com/id/Send-and-Receive-MIDI-with-Arduino/) and am successfully triggering the drum circuit using midi notes.

My problem is it is quite sporadic when playing a midi sequence. Some midi notes are being ignored/ not read and it is completely random. The timing is correct, but it ignores some messages.

It may have something to do with interrupts? I am unsure. There is some interrupt code in the link above but this doesn't work for me.

Any ideas? my code is attached

code receives midi messages (60, 61 and 62) and outputs 5ms pulse from PWM pins

Code: [Select]

/*Receive MIDI and check if note = 60
By Amanda Ghassaei
July 2012
*/

byte commandByte;
byte noteByte;
byte velocityByte;

const int pulsePin = 11;
const int pulsePin2 = 12;
const int pulsePin3 = 10;

byte noteOn = 144;

//light up led at pin 13 when receiving noteON message with note = 60

void setup(){
 Serial.begin(31250);
 pinMode(13,OUTPUT);
 digitalWrite(13,LOW);
 pinMode (pulsePin, OUTPUT);
 pinMode (pulsePin2, OUTPUT);
 pinMode (pulsePin3, OUTPUT);

}



void checkMIDI()
{
 do{
   if (Serial.available()){
     commandByte = Serial.read();//read first byte
     noteByte = Serial.read();//read next byte
     velocityByte = Serial.read();//read final byte
     if (commandByte == noteOn){//if note on message
       //check if note == 60 and velocity > 0
       if (noteByte == 60 && velocityByte > 0){
         digitalWrite(13,HIGH);//turn on led
         digitalWrite(pulsePin,HIGH);
         delay(5);
         digitalWrite(pulsePin,LOW);
         
       }
     }
         if (commandByte == noteOn){//if note on message
       //check if note == 61 and velocity > 0
       if (noteByte == 61 && velocityByte > 0){
         digitalWrite(13,HIGH);//turn on led
         digitalWrite(pulsePin2,HIGH);
         delay(5);
         digitalWrite(pulsePin2,LOW);
         
       }
     }
         if (commandByte == noteOn){//if note on message
       //check if note == 62 and velocity > 0
       if (noteByte == 62 && velocityByte > 0){
         digitalWrite(13,HIGH);//turn on led
         digitalWrite(pulsePin3,HIGH);
         delay(5);
         digitalWrite(pulsePin3,LOW);
         
       }
     }
   }
 }
 while (Serial.available() > 2);//when at least three bytes available
}
   

void loop(){
 checkMIDI();
 delay(2);
 digitalWrite(13,LOW);//turn led off
}





MasterArchi

It may be an issue related to timing, try to remove delay(2) and digitalWrite(13, low) from the main loop.

Archi

Grumpy_Mike

#2
Sep 26, 2017, 07:16 am Last Edit: Sep 26, 2017, 07:17 am by Grumpy_Mike
Code: [Select]
if (Serial.available()){
     commandByte = Serial.read();//read first byte
     noteByte = Serial.read();//read next byte
     velocityByte = Serial.read();//read final byte

So read three bytes from the serial port if one or more are available? Not a very good strategy. The while condition at the end only kicks in at the end.

Avoid the 'do' - 'while' structure, it is not needed and only leads a beginner into confusion.

Also reading three bytes at a time assumes you are not going to get any one or two byte MIDI messages, can you guarantee that?

Go Up