Send and Receive MIDI with Arduino

 by amandaghassaei
Featured

Step 9: Receive MIDI Messages with Arduino

IMG_9846 copy.jpg
receive schematic.jpg
IMG_9845 copy.jpg
IMG_9840.jpg
IMG_9841.jpg
Screen shot 2012-08-27 at 7.15.34 PM copy.jpg
Most Arduino MIDI projects send MIDI messages out, but you can also use the Arduino to receive MIDI data.  Here are some ideas:

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 adsRemove these ads by Signing Up
soeren says: Jun 13, 2013. 2:03 AM
Hi Paulsoulsby

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
paulsoulsby says: May 5, 2013. 10:51 AM
Hi,
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);
  }
}
amandaghassaei (author) in reply to paulsoulsbyMay 12, 2013. 4:55 PM
that's really interesting! thanks for sharing.
museumoftechno says: Mar 8, 2013. 2:35 PM
Hi there

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!



amandaghassaei (author) in reply to museumoftechnoMar 28, 2013. 11:00 PM
without an oscilloscope it;s really hard to troubleshoot. I had some trouble getting this to work too, the circuit can be a bit finicky. my only suggestion is tot get the optocoupler I recommended and wire it up exactly as it;s shown int eh schematic. sorry!
rad3d says: Dec 29, 2012. 7:32 AM
I'm using the Sparkfun MIDI Shield with this code and not getting MIDI input to work. MIDI out works fine, but not MIDI in. Pretty sure all my connections are good on the shield. Is there anything about the code in step 9 that should not work with this shield? Looks like it uses the same components.

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.
amandaghassaei (author) in reply to rad3dFeb 6, 2013. 10:32 AM
hi, sorry for the late reply, have you figured it out?
jdevs says: Dec 23, 2012. 9:15 PM
Unfortunately, I do not at this time. Is there another way to debug?
amandaghassaei (author) in reply to jdevsDec 23, 2012. 11:18 PM
Yes, unfortunately. Recheck all the connections, check for continuity, if it still doesn't work then you'll have to use an oscilloscope.
jdevs says: Dec 23, 2012. 11:46 AM
First off, thank you for a wonderful MIDI-Arduino instructable. I have been working with the receive circuit set up as instructed (I've triple checked it) using my Arduino Duemilanove, UNO and sending MIDI messages with Reaper (PC).

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.
amandaghassaei (author) in reply to jdevsDec 23, 2012. 1:41 PM
do you have an oscilloscope?
11Point says: Nov 15, 2012. 3:11 AM
Hey first thank you for your amazing instructables. I wanto to ask a question.
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 ;)
amandaghassaei (author) in reply to 11PointNov 15, 2012. 10:14 AM
between the midi jack and the xbee
Pro

Get More Out of Instructables

Already have an Account?

close

PDF Downloads
As a Pro member, you will gain access to download any Instructable in the PDF format. You also have the ability to customize your PDF download.

Upgrade to Pro today!