Arduino MIDI interface (updated)26 Dec 2016
MIDI: an introduction
MIDI (Musical Instruments Digital Interface) is the name of a communication protocol amongst musical instruments and devices developed by some musical instruments manufacturers in the early ’80s.
Other communication protocols already existed but MIDI soon became more valuable as it was recognised as a market standard and it made use of digital signals (streams of bytes) instead of analog.
From a more technical point of view, MIDI is an asynchronous serial communication protocol with a transmission speed of 31250 baud. On the physical layer it uses the classic 5 pin DIN connector and cable.
Here’s a picture of a standard MIDI message:
As you can see, inside a MIDI message there are two main bytes categories:
- Status Byte;
- Data Byte;
Suppose we are a MIDI device and we are receiving MIDI messages from a MIDI controller: how can we differenciate between status bytes and data bytes? The main difference between them lies in their values: Status Bytes are bytes which value is greater than 127 while Data Bytes always have values comprised between 0 and 127.
From a binary point of view it means that the leftmost bit of a status byte is always 1 while it is 0 for the data byte.
What is a MIDI channel? Suppose we have only one MIDI keyboard/controller connected to many stacked synths.
How can we use all the synths sounds each one mapped on a certain portion of the keyboard, so we could play different sounds with different notes?
Here comes the MIDI channel! Using MIDI channels we can say to each synth to listen only at messages coming from a specific MIDI channel, discarding all the others. We can do the same with our MIDI keyboard, setting it to send messages to different MIDI channels according to the notes being plated or the control used.
The MIDI protocol provides up to 16 different MIDI channels. Each MIDI message contains information regarding the MIDI channel used to send it; we can retrieve the information reading the lower nibble of the status byte
If you need more information about MIDI and how it works I’d warmly recommend reading the book “MIDI computer e musica” by Giovanni Perotti, I’ve found it a precious resource in many sitations. It’s written in italian but I think you’ll find good alternatives in English (if so, please let me know!)
Arduino simple MIDI IN interface
Let’s try a new experiment: why don’t we build a MIDI interface using Arduino board?
First, we want our Arduino UNO board to receive and debug the MIDI messages it receives from the outside world.
We could use the default hardware serial port (the RX pin on the board) to receive bytes. Anyway, since we want to debug our code using the Serial Monitor, we need to use this serial port for the communication with the PC, thus we can’t use RX as a MIDI port.
We need and additional hardware serial port for our MIDI interface: we can use the Arduino Software Serial library!
First of all we have to build the circuit. We can take advantage of this beautiful illustration by pighixxx as a reference for the schematics:
Or maybe we can use the one from the Wikipedia MIDI page:
Or maybe use this other one from the Giovanni Perotti book:
Schematics illustrated in these images are a bit different from each other but the working principle stays the same.
Let’s focus on the MIDI In section. We need:
- two 220 Ohm resistors;
- an 6N138 optocoupler. We may also use a 4n28 optocoupler as Joshua Noble explains in his “Programming Interactivity” book;
- an 1N4148 high speed diode;
- and - obviously - one 5 pin DIN.
Here’s the Fritzing scheme of our circuit.
Let’s move to the code:
In order to examine the MIDI messages flow we have to connect a MIDI device (such a MIDI keyboard or controller) to our Arduino MIDI interface.
Now that everything is set up, let’s upload the sketch. We play some notes on the keyboard and see what happens. Here’s a screenshot of the Serial monitor output:
Wow! It works!
This is very exciting. All the numbers we see here are the bytes sent from the MIDI keyboard to our Arduino MIDI interface and, again, from Arduino to the PC.
We can see clearly the 144 byte and, because its value is greater than 127, we know it’s a Status Byte and a Note ON status byte in particular.
We also know that the MIDI channel we are receiving messages from is the channel 1, 0 in binary; actually, the Status Byte contains both the status information and the MIDI channel number. In our case:
or in binary
We can also see bytes values which are lower than 127: these are Data bytes.
For example, the bytes pairs following the Note ON status byte are the Data bytes representing a note number and a velocity value.
So, for example, the sequence
144 76 50 means the I’ve played an E5 (note number 76) with a velocity of 50.
After that sequence there’s a new bytes sequence testifying that I’ve also released the note:
144 76 0 (same note, velocity 0).
Observation 1: We don’t see the “Note OFF” status byte, why? Clearly it’s because my MIDI keyboard is not programmed to send it. MIDI devices are commonly programmed to send “Note ON” MIDI messages with a 0 velocity value in place of “Note OFF” messages.
If we examine more in depth our software serial output, we see a long list of consecutive data byte. One single status byte at the beginning (
144) and then lots of note and velocity pairs. Why the Status byte is not repeated?
Observation 2: this is called Running Status. MIDI standard states that the status byte is sent only when it changes from the previous one. So, if we are playing a long series of notes, without modifying any other control, the status byte sent at the beginning of the sequence is always the same so we don’t need to send it againg for every new note. This way we can save a third of time in sending MIDI data! This is the same reason why Note ON messages (with a 0 velocity value) are preferred to Note OFF ones.
Arduino simple MIDI OUT interface
Now, let’s try with the opposite approach: we want to create an Arduino MIDI instrument.
This would be our studio configuration:
What we need is a synth to be connected to our Arduino MIDI interface output.
We have to create a MIDI out interface so we need only:
- two 220 Ohm resistors;
- and one 5 pin DIN.
Here the Fritzing scheme of our circuit.
Here we have a simple code to make our Arduino instruments plays random notes:
Arduino simple MIDI IN & OUT interface
Great! Now it’s time to make it more complicated: we will create a new circuit and write new code to make our Arduino get MIDI messages in and send them out.
What we need to build our circuit:
- an 6N138 or a 4n28 optocoupler.
- an 1N4148 high speed diode;
- four 220 Ohm resistors;
- and two 5 pin DIN.
Here’s the Fritzing scheme:
We are going to connect our MIDI keyboard/controller to the Arduino MIDI interface. Then we connect the interface to the synth. We can possibly use the USB serial communication to debug our code using the PC.
The first thing to pay attention to is that the SoftwareSerial Library cannot send and receive data simultaneously as stated here:
SoftwareSerial can not simultaenously transmit and receive, so it should be used with a device that never sends in both directions at once.
We have made some tests and we can confirm that. So we have to use a different library. The AltSoftSerial worked well for us: we have to remember that on the Arduino UNO the library uses:
- pin 8 for receiving;
- pin 9 for transmitting.
We have built our simple MIDI interface with Arduino; good job! Now the only limit is our imagination: what about adding a piece of code that modifies MIDI data in and send them back to create particular harmonizations or other kind of musical effects?
Now we are happy with it but stay tuned for future developements…