# Send and Receive MIDI with Arduino

This instructable will show you how to use an Arduino to send and receive a variety of MIDI messages so you can start building your own MIDI controllers and instruments.  First I'll talk a little bit about MIDI protocol, if you're just looking for sample code skip ahead to steps 5-9.

If you know absolutely nothing about MIDI note, velocity, and pitchbend or are confused about what MIDI does and why you would want to use it, check out my What is MIDI? instructable.
Remove these ads by Signing Up

## Step 1: Bytes and Bits

To understand MIDI communication, you have to understand a little about bytes and bits.  A byte is a packet of data used to store information.  In MIDI protocol, each byte is made up of 8 bits; bits can only equal to 0 or 1.  A sample byte is given below:

11010111

Each 1 or 0 in this byte is a bit.  The leftmost bit is called the most significant bit (or MSB) and the rightmost bit is called the least significant bit (or LSB).

Bytes of the form above are binary numbers because they are expressed using only 1's and 0's.  We can convert this number to base ten as well:

11010111 in binary (base 2) = 215 in decimal (base 10)

If you need help converting numbers from binary to decimal or vice versa check out Wolfram Alpha.  Type in a binary number followed with "from binary to decimal" to get the decimal equivalent.  Wolfram Alpha is also great for converting to and from hexadecimal.

Wikipedia is a good resource for more information about bytes and binary.
 1-40 of 151 Next »
fizzlesticks19 days ago

I'm unclear on some things. Well written instructable, but I'm not fully understanding MIDI yet. Will the master midi device send a constant bitstream, with every single bit being part of a command byte or data byte? If not, I'm guessing that if I wanted to read midi into my Nexys-3 board, I'd need to create a clock to check the data input pin 31250 times a second, listen for a logic high, and then proceeding to store the data bytes and the rest of the command byte. For my project, I intend to only care about the Note On and Note Off commands, but will expand in the future.

Also, would you know of any program that could either A) take guitar input to the computer (through a Scarlett 2i2) and convert to midi and then output to a usb port (that will have a usb to midi cable), or B) take a .mid file and output it to the same usb cable as in A? My project is an audio modulated Tesla coil, and the Tesla coil works. I have my bridge circuit and protection circuit hardware ready, just need to understand how to read midi input. Any help would be greatly appreciated!

ariel.delrio.321 days ago

Thank you for this great tutorial! I've tried the midi out and works perfectly, I even managed to have arduino play poliphony in my synth. I haven't tried the midi in because I don't have the octocoupler yet but in the meanwhile I've been having a look at the schematics and the photos and there's something I don't understand (I'm a just a beginner in arduino/electronics): in the schematics, the cable with the 220ohm resistor comes out from the octocoupler's pin 2, but in the photos the resistor is soldered to the yellow cable, which in turn comes from pin 3.

Should I solder the resistor to the yellow or the green cable? To which pins in the octocoupler should the yellow and green cable ba connected?

Many thanks! :-)

rice_crisp6 months ago

I've been having problems reading the midi data once I start playing more than one note at a time (polyphony). Does this have to do with the note on command with 0 velocity and the note off command? Does it send both commands when a note is released?

amandaghassaei (author)  rice_crisp5 months ago

yeah the code I have there isn't setup to handle polyphony. The way that works is two note on messages are sent to the arduino at approx the same time, and then two note off messages are sent when you release the note. Remember note off messages specify the pitch they are turning off, so each note off command is specific to a certain pitch. What are you planning on making?

1 month ago
Could you give an example of how you send two messages at a time? I am hoping to use this brilliant tutorial to help me integrate my controllers and some messages it sends are two note messages.
4 months ago

I've attached an led strip, and I'm trying to assign a note to each led on the strip. One note seems to work fine, but things just start getting wonky when I play more than one note. Did I not implement the note off message correctly, or does the circuit just not handle polyphony?

Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);

byte commandByte;

byte noteByte;

byte velocityByte;

byte noteOn = 144;

byte noteOff = 128;

void setup(){

Serial.begin(31250);

strip.begin();

}

void loop(){

checkMIDI();

strip.show();

delay(10);

}

void checkMIDI(){

do {

if (Serial.available()){

if (commandByte == noteOn){//if note on message

if (velocityByte > 0) {

strip.setPixelColor(noteByte-30, 0, 0, velocityByte);

} else {

strip.setPixelColor(noteByte-30, 0, 0, 0);

}

} else if (commandByte == noteOff) {

strip.setPixelColor(noteByte-30, 0, 0, 0);

}

}

}

while (Serial.available() > 2);//when at least three bytes available

}

chrisrobertsonuk2 months ago

Hi Amanda,

Great Tutorial. However when it comes to Electronics my knowledge is limited at best. I was wondering whether you would mind further explaining the use of the optocoupler for receiving data... If I could understand WHY we use it the rest will become clearer to me. Many Thanks. Chris

Leinard3 months ago

sorry, apparently that error appears when I connect to the MIDI output, how do I connect to the application of the piano?

3 months ago

does not matter because I decided it was custión create a virtual MIDI port, I installed "loopMIDI" and it worked. thanks for the tutorial, this rather detailed.

Leinard3 months ago
when I try to use the MIDI Hairless and try to connect with the port of arduino, the error "this application has Requested the Runtime to terminate it in an unusual way" shows how I can fix this?
edil106 months ago

Hi Amanda,

Thanks for the excellents Midi Instructables you have shared!

I am a newbie with Midi and Arduino and no experience in programing, I am looking for a simple Arduino sketch to read the output from the Midi In board and print it in the serial console.

I am planning to build a wireless midi transmissor and that sketch will be the first step.

Edilberto

amandaghassaei (author)  edil105 months ago
have you tried Serial.println(Serial.read()) ?
frikkn7 months ago

hello,

I've got my arduino hooked up to my PC with the MIDI-USB cable. the baudrate is set to 31250 but still my computer is not picking up any midi signals. I use the software of this tutorial. if i hit my piezo my tx light will light up so thats not the problem. what can my problem be?

forgoden8 months ago

This Code below here from you doesn't work to me.
The Serial.read() only put values in commandByte, but not noteByte and velocityByte? I can be sure that commandByte is always bigger than 127 and the other values 0-127 can be noteByte or velocityByte?

ISR(TIMER2_COMPA_vect) {//checks for incoming midi every 128us
do{
if (Serial.available()){
}
}
while (Serial.available() > 2);//when at least three bytes available
}

amandaghassaei (author)  forgoden7 months ago
Yes the command byte is always >127 and the note and velocity (or whatever other parameters come after the command are <= 127. This code can be really finicky depending on your setup. Try removing the > 2 in the code able and see if it helps. You might want to add some additional logic to be sure that the command byte is set correctly (check if it is > 127)
AmpOwl10 months ago

Is there a way you could send the signal through USB directly, without having to use a separate adapter?

10 months ago

To be more clear, I want to use a digital pin to send the signal, instead of the arduino's USB interface. I'm using a barebones arduino that requires an FTDI adapter (that I only have one of).

amandaghassaei (author)  AmpOwl10 months ago

if you're sending MIDI to your comp, you could run an application like this to convert serial to MIDI and pass the MIDI messages through the USB connection. You could also get your Arduino to act as a USB/MIDI device through firmware.

10 months ago

I see; are there any necessary changes (using the first method) to the code described in the instructable? How would you wire the USB connection from the Arduino pin? Thanks for the help.

amandaghassaei (author)  AmpOwl10 months ago
You can use the USB on the arduino, I added some info in step 5
10 months ago

Ok, thanks. Would it be possible to use a digital pin on the arduino to send the serial signal, instead of the programming port? Again, I am using barebones arduinos that require a separate FTDI adapter, and I only have one of those.

amandaghassaei (author)  AmpOwl10 months ago

no, I don't think so.

10 months ago

What if you used this library I found; it's called SoftwareSerial, and it says it allows you to send serial data through a digital pin. Would it be compatible with Hairless MIDI?

http://arduino.cc/en/Reference/SoftwareSerial#.Uv8...

http://arduino.cc/en/Tutorial/SoftwareSerial#.Uv8g...

amandaghassaei (author)  AmpOwl9 months ago

you can use this to send serial data to electronics, but I'm not sure it will communicate with your computer.

I want to making you know that I had some trouble making my arduino speaking MIDI. Finally I got it with Hairless Serial<>MIDI converter and a MIDIPort, but I must set the serial baudrate at a different speed (38400). In Hairless' Settings MENU I must choose at which speed is Arduino sending serial information and there isn't 31250.
I can't solve this issue and I need to because MIDI Library work at 31250 by default and because I imagine a physical USB converter (as yours) expect to receive data at that frecuency.
I tried to use a Midiman MIDISPORT 2x2 without success. I don't know how to solve this problem and also It get me a bit frustrated because all DIY projects use that MIDI default MIDI without problems.

I haven't tried to receive, manage and process incoming MIDI data. I'm going step by step.

Anyway I found your channel really well made with detailed informations and clear explications. I'm also having benefits from the other instructables about Timer Interrupts. It's great!

Alberto
amandaghassaei (author)  albertocarlassare1 year ago
which arduino board are you using?
1 year ago
Yes! I'm sorry!
I'm Using:
-Arduino Uno Rev3
-Midiman MIDISPORT 2x2 (old version -> http://www.wikizic.org/Midiman-Midisport-2x2/)

-Hairless MIDI<>Serial Bridge (very good tool)
-LoopBe1 as primary Virtual Port (because your Max patch doesn't recognize me MIDI Yoke - Thanx also for the patch, very useful to).
-MIDI-OX for monitoring MIDI activity (before checking in DAW - Mainly ProTools/Cubase/Traktor/Live)

1 year ago
On Hairless FAQ section I found out that Hairless can't work at 31250. Also they explain that isn't standard recuency for serial ports. So they say to use a 'compatible' serial baudrate. That's ok for me just for building up code, classes and libraries and switch to 31250 at the final stage; My doubt is: Why MIDISPORT doesn't react to incoming messages at 31250 and Serial-to-Midi software neither. Serial-to-Midi is supposed to work at that baudrate.
amandaghassaei (author)  albertocarlassare10 months ago

I ended up using Hairless MIDI for a class and I came across the problem you were describing, I think I did not understand the problem before. You can change the baud rate in all the Arduino sketches to something that Hairless MIDI accepts. The baud rate only needs to be 31250 if you are connecting to something that is expecting MIDI, not Serial.

Just be sure that you set the rate in Hairless MIDI to whatever you set in Arduino, I added a section about this (step 5). I used 9600 baud and it worked great.

amandaghassaei (author)  albertocarlassare1 year ago
if you want to send midi into a piece of hardware like a synthesizer, you will have to output at 31250, it's possible to send messages at other baud rates and then convert it to a midi signal in your comp, that's probably what's happening
1 year ago
http://spikenzielabs.com/SpikenzieLabs/Serial_MIDI.html
Use this link from Spikenzie Labs, which has a Serial <> MIDI sketch made in processing already set-up. It does have the correct baud rate for me, you just have to know which serial port to use, what device to output TO, and what device to input FROM
DeathSuperMario10 months ago

I'm thinking can I make my midi cotroller to cotrol any sound generator.

One idea is with PWM

MIDI controller -> Arduino -> PWM output -> analog output

X1L311 months ago
Thanks amanda. Appreciate the help. Really cool project and a brilliant and easy to grasp introduction to midi.
e.ma.niak11 months ago
I'm building my own midi controler, now i know how to handle incoming midi. Great instructable.
amandaghassaei (author)  e.ma.niak11 months ago

awesome!

X1L311 months ago
Hi. I'm just wondering how you'd go about filtering out unwantwd midi controler date. The project I've built with this works fine but any pitch/modwheel data etc freezes / unfreezes it. Is it a case of telling it to read these messages and then do nothing?
amandaghassaei (author)  X1L311 months ago

yes definitely, you should add an if statement that checks to the value of commandByte to see if it's what you want. commandByte = 144 is note on, you can find the rest of the commands here

Team3G12 months ago
The shake to clear feature is genius. Inspiration points++
jhenrique31 year ago
Hello, Amanda! Your projects are awesome :D I don't have an arduino yet, but I'm planning to use two of your instructables (Arduino Audio Output and Send and Receive MIDI with Arduino) and some other projects to modify a toy casio keyboard, so that I can control the arduino with the toy keyboard's keys or another keyboard to play some NES-like music. I would like to know if it is possible to change the pin where the arduino receives MIDI data, because the D0 pin of the arduino is already used in the Arduino Audio Output project, as I plan to do these projects with a single arduino. Thanks in advance.
1 year ago
It is not possible to change the MIDI send/receive pins because MID requires serial data and pin D0 is the serial receive while pin D1 is the serial transmit pin. If you need more than one serial TX/RX pin, I would recommend and Arduino MEGA 2560, which has 4 of each.
 1-40 of 151 Next »