algorithm Arduino hardware software

Playing MIDI files on Arduino – Part 3 Hardware and MD_MIDIFile Library


Part 1 and part 2 covered Standard MIDI Files and playing music at the right tempo. Once we have a MIDI stream, we need hardware that can play the notes.

In this part we’ll look at how to finally make a sound and how the MD_MIDIFile library supports this in software.

Making a Sound

Making a MIDI sound using the Arduino comes to a choice of

  1. Making your own musical instrument and actuating the right note based on the MIDI instructions, or
  2. Sending the MIDI message to a MIDI synthesiser to make the sound for you.

The key to both these options is that the MIDI note-on and note-off messages are mapped to specific digital or analog actuations in the real world. The first option is very specific to the project you are working on and is beyond the scope of this article.

The second, and probably easier, option is to ‘outsource’ the sound generation to another device. This can be an instrument like a MIDI keyboard, computer sound generation software or other specialised hardware. A good summary of the computer based options for processing MIDI messages can be found here.

Sending MIDI data into the real world

One of the simplest ways to interface to a MIDI instrument is to acquire or build a MIDI interface for the Arduino.  A MIDI hardware interface is simply an opto-isolated byte-based serial interface configured at 31,250 baud (bps).

The standard MIDI connector is a 5 pin DIN, however other types of connections (like MIDI over USB) have become increasingly common as alternative interfaces serial, joystick, etc. have disappeared as standard features on personal computers.

midi_DIN_plug+socketStandard MIDI cables terminate in a 180 degree five-pin DIN connector with applications using only three of the five conductors – a ground wire and a balanced pair of conductors that carry a +5 volt signal. This connector configuration can only carry messages in one direction, so a second cable is necessary for two-way communication. These are usually labeled IN and OUT designating the messages going into, and coming out of, the device respectively.

Most devices do not copy messages from their IN to their OUT port. A third type of port, the THRU port, emits a copy of everything received at the input port, allowing data to be forwarded to another instrument in a daisy-chain arrangement. Not all devices contain THRU ports, and devices that lack the ability to generate MIDI data, such as effects units and sound modules, may only have IN ports.

Opto-isolators keep MIDI devices electrically separated from their connectors, which prevents the occurrence of ground loops and protects equipment from voltage spikes. There is no error detection capability in MIDI, so the maximum cable length is set at 15 meters (50 feet) in order to limit interference.

A MIDI communications circuit for use with the Arduino Serial interface is shown below. This can be built as a stand-alone interface or incorporated into an Arduino shield and is based on the device described in this article. Note the addition of a switch to isolate the MIDI circuit as pins 0 and 1 do double duty as the standard Arduino and MIDI serial ports.


My own version of this circuit is built as an Arduino shield and is shown below. In order to keep a stackable shield height, the DIN sockets are mounted on a daughter board and positioned over the end of the shield. This shield has worked well to interface to a MIDI synthesizer keyboard.

As an alternative MIDI synthesizer device, I also mounted this Sparkfun VS1053 breakout (unfortunately now discontinued, but Adafruit has a similar product) on a prototyping shield, configured to boot in special MIDI mode so that it reads MIDI data on a UART pin from its serial interface.

This breakout also has audio output to directly drive earphones or an amplifier. With this shield, I connected the VS1053 Serial Receive through a jumper block to a number of Arduino pins to allow a separation between Arduino and MIDI serial streams.

Bringing it all together with software – the MD_MIDIFile Library

Designing a library to play Standard MIDI Files (SMF) on an Arduino microcontroller requires a few design decisions.

The first is how to store the files. The MD_MIDIFile library uses SD cards to store SMF for processing, only reading a few bytes at a time for each MIDI track. The advantage is that SMF can be much larger than would fit in the MCU memory (basically unlimited in size). With the SD library buffering the data from the SD card, the read latency is insignificant compared to the time between processing MIDI events for each track.

The second design decision is how to output the MIDI stream. The MD_MIDIFile library passes the MIDI and SYSEX events to the calling program through callback functions. This allows the calling application to manage sending to a MIDI synthesizer through a serial interface or to another output device, such as a MIDI shield or a musical instrument implementation.

To simplify the management of SMF playback, the MIDI stream is controlled through library methods to start(), pause() and restart() playback. SMF may also be looped automatically play continuously.

Additionally, while time ticks are normally generated by the library during playback, this function can be taken over by the user program if different time signal or synchronization with external MIDI clock is required.

See Also:

Playing MIDI files on Arduino – Part 1 Standard MIDI Files

Playing MIDI files on Arduino – Part 2 Keeping to the Beat

7 replies on “Playing MIDI files on Arduino – Part 3 Hardware and MD_MIDIFile Library”

Marco, thanks for sharing this wonderful library, it’s proven very useful to me, though i don’t fully understand the code. Maybe you could give me a hint on how to use it to obtain the midi note numbers and duration from the file instead of writing the information to serial? Thanks a lot anyways… Lode.


The callback function from the library (that writes to serial) has all the info about the notes – that is what is is writing to serial. If you want to do something else with it, intercept it at that point. The library has a lot of documentation that you can read as well that explains how the application should process the information received. It is located in the docs folder of the library.


Hello Marco,
Thanks for your reply, i’m struggling to get the rev variable in the right place, but I’ll work it out. It seems strange to me that noone in the synth community implemented this with mozzi for example, it could be very useful. Thanks again for a great library!


It’s all very interesting…
it will be better make it in practise doing it with an Arduino shield ; can you have the firmware for the shield ?
Thank you !!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s