Step 9: Receive MIDI Messages with Arduino
an Arduino synthesizer that uses MIDI messages to construct audio waveforms
a device which uses MIDI to trigger mechanical events, like the ringing of different sized bells
a MIDI to control voltage(CV) device- communication between MIDI and analog synthesizers
Parts List:
MIDI connector Digikey CP-2350-ND
220Ohm 1/4watt resistor Digikey CF14JT220RCT-ND
1N4148 diode Digikey1N4148-TAPCT-ND
10kOhm 1/4watt resistor Digikey CF14JT10K0CT-ND
470 Ohm 1/4watt resistor Digikey CF14JT470RCT-ND (I used 2x220 instead)
6N138 optocoupler Digikey 751-1263-5-ND
The hardware setup is slightly more complicated for receiving MIDI than it is for sending. As you can see in the schematic above, you have to set up an optoisolator in between the MIDI jack and the Arduino. If you are confused about the MIDI pin connections, refer to fig 1. I set this circuit up on a breadboard in figs 4 and 5.
The following code receives these messages, reads them, and stores them appropriately. See the comments for more information.
To make sure that everything is working properly, try the code below. This code turns the led at pin 13 on briefly when it receives a note on message for MIDI note 60 (middle C). Notice how I included "&& velocityByte>0" in the if statement- this makes sure that we are dealing with a note on statement, if you don't include this the light will blink for both note on and note on with velocity = 0 (note off) messages.
If you want to do a lot of stuff in the main loop, or if you are expecting to receive a lot of MIDI data and timing is important to you, you can also try using a timer interrupt to periodically pause the main loop and check if there is incoming MIDI. It will look something like this:
Remove these ads by
Signing Up














































Visit Our Store »
Go Pro Today »




I'm really having issues getting midi input as well. I've tried many different setups and opto couplers, including this exact instructable - without luck.
I tried your code, but you haven't defined NOTE_ON, NOTE_OFF, PITCH_WHEEL and CONTROLLER anywhere. What did you intend to put into these variables, or are they #define instructions that you forgot to include here?
all the best
Søren
Thanks for this instructable. It's been really handy. I had problems with the MIDI input, with some MIDI devices. I discovered that this was to do with MIDI active sensing. Here's my code for reading the MIDI port that takes into account for MIDI active sensing.
byte incomingByte=0;
byte notebyte=0;
byte velocitybyte=0;
byte statusbuffer=0;
boolean arp_triggernext=false;
boolean firstbyte;
void MIDI_Poll(){
if (Serial.available() > 0) {
do {
// read the incoming byte:
incomingByte = Serial.read();
if (incomingByte>247) {
// this is where MIDI clock stuff is done
switch (incomingByte){
}
}
else if (incomingByte>240) {
statusbuffer = 0;
//sysex stuff done here
}
else if (incomingByte>127) {
statusbuffer = incomingByte;
firstbyte = true;
notebyte = 0;
velocitybyte = 0;
}
else if (statusbuffer!=0) {
if (firstbyte == true) {
// must be first byte
notebyte = incomingByte;
firstbyte = false;
}
else {
// so must be second byte then
velocitybyte = incomingByte;
//process the message here
if (statusbuffer == NOTE_ON && velocitybyte != 0) {
//MIDI note on subroutine
}
else if (statusbuffer == NOTE_OFF || (statusbuffer == NOTE_ON && velocitybyte == 0)) {
//MIDI note off subroutine
}
else if (statusbuffer == PITCH_WHEEL){
//pitch bend wheel
}
else if (statusbuffer == CONTROLLER){
if (notebyte==1) {
//MIDI_modwheel_level = velocitybyte;
}
}
//now clear them for next note
notebyte = 0;
velocitybyte = 0;
firstbyte = true;
}
}
} while (Serial.available() > 0);
}
}
Thanks for the Instructable - the MIDI out section's fantastic, and the tutorial as a whole inspired me to buy an Arduino. Great work!
I've not been able to get MIDI in messages to light an LED though. It's to do with the non-Arduino components, I think: I took a risk and connected the MIDI In directly to my Arduino Nano, and it then works fine - so the issue's not Arduino compatibility. I've tested continuity where I can (resistors, diode) and tried 2 different optocouplers. My optocoupler was Lite-On brand, but I've compared the specs and the pinout/internal circuitry are the same as the device you specify. No oscilloscope here I'm afraid!
I'm new to all of this so I'm not quite sure what I can check on MIDI In for continuity. I've noticed that testing Pin4 on my MIDI Out against the TX send tests fine, but none of the Pins on the MIDI in test against the RX pin. Not sure how the optocoupler affects basic continuity testing though.
I've been trying to get the MIDI note 60 (middle C) code working but no matter what I've tried, the circuit doesn't seem to receive a MIDI signal.
A couple of things I've tried for debugging:
- Changing the code to accept ANY MIDI message (removed noteByte == 60 && velocityByte > 0), no success.
- Tested digitalWrite(13,HIGH) in the main loop to test LED output, which worked.
I'm doing the same project to receive midi message with arduino, the things is that I send the midi message through an xbee connected to a midi jack that send midi message through my laptop, and the 2 xbee receive the midi message and send it to the lilypad arduino. So in that case the optocupler has to be connected between the lilypad arduino and the 2nd xbee or between the jack midi and the 1xbee, thqt send the signals??
thanks ;)