How to Control Anything on Arduino Using MIDI

I’ve been messing around with MIDI for my musical floppy drive project, and it was surprisingly difficult to find detailed information on how to get started with Arduino’s MIDI library. So in this post I’m going to show you, in detail, how to use this library to control anything on an Arduino using MIDI.

What is MIDI?

MIDI, an acronym for Musical Instrument Digital Interface, is a protocol and interface standard designed to allow musical instruments and computers to connect and communicate with each-other. It’s widely used in the music world, for everything from digital audio workstations (DAWs) to musical keyboards. See the Wikipedia article for more information on the standard.

How do you use it?

The two most basic MIDI messages are “note on” and “note off” messages, that either start or stop a musical note. These messages have three parts:

  1. Channel: A channel between 1 – 16 that the note is played on. You can think of these as “tracks” for different instruments. Notes can be on any channel, although channel 10 is usually reserved for percussion.
  2. Note: The note being played, from 0 – 127 where 60 is middle C. Each increment is a semitone.
  3. Velocity: The speed at which the note is played, from 0 – 127. Think of it as the difference between hitting a piano key very quickly (high velocity) vs slowly pressing it until it plays the note (low velocity).

There are also a number of other messages, such as pitch bends and continuous controllers, that give you more control over how the instrument plays music (or, in this case, anything!).

So why is this useful with Arduinos?

The obvious reason is that you might be trying to make a musical instrument of some sort – a keyboard, a synthesizer, or something completely unique. But because you can use MIDI to control practically anything, there are some other reasons that may not be so obvious.

Timing Control

MIDI is designed for music, which means it is fundamentally intertwined with time. This means you can build a MIDI track on your computer and use it to control exactly when events will happen on a microcontroller without worrying about tedious (and much more permanent) delay timing.

You can also link many devices together with MIDI, and keep them all in sync with each-other while performing tasks.

MIDI Controllers

These days you can buy all sorts of MIDI controllers, from large digital keyboards to control boards and sample pads. These devices provide you with a whole host of polished physical controls for your devices that can be remapped, interlinked, and activated remotely.

Universal Support

If you need a remote control protocol for anything, MIDI might be a tempting candidate because it is so widely supported. Anything that uses an on/off switch or a potentiometer can be set up for MIDI control with just a few lines of code.

Instead of designing your own custom protocol, it may be easier just to adapt MIDI for your needs.

Getting Started

To do this you’ll need an Arduino of some sort – it doesn’t need to be a model with native USB support (e.g. Leonardo, Pro Micro), although it certainly doesn’t hurt.

The first thing you’ll need to do is to download the Arduino MIDI library by FortySevenEffects, which you can find here. You can also download it in the Arduino IDE by going to the library manager and searching for “MIDI”. Download the ZIP file and extract the contents into your Arduino ‘libraries’ folder.

Note: You don’t need to use the Arduino MIDI library to work with MIDI Messages, although it certainly does make things easier. If you’re writing your own MIDI code, I highly recommend this tutorial on the protocol.

Creating the MIDI Instance

Before we can do anything with MIDI, we need to create a MIDI instance so the Arduino knows where and how to get its MIDI data.

This can be as easy as this one line of code:

This will build the typical MIDI instance usually used on your Arduino board. If you want to customize the parameters, you have a two options:


  • Type is either “HardwareSerial” or “SoftwareSerial” depending on the port type.
  • SerialPort is the name of the serial port from the Arduino’s Serial class
  • Name is the name of the MIDI port you’re creating. This can be anything you’d like.
  • Settings is a custom struct from the MIDI library that contains the settings for a few custom parameters including baud rate.

To change the “settings”, you need to create your own struct:

Any values you put in this struct will overwrite the defaults. If you omit any, the struct will use the default values from the library.

Here are a few instance examples:

For more information on instance creation, look at the source files for the MIDI definitions and MIDI settings in the library’s repository.

Adding Handler Functions

Once your instance is created, the next step is to link some handler functions. The MIDI library works by calling a function pointer when it finds a matching MIDI packet. Here is a list of the available handlers:

You configure these in the setup function, like so:

You can name these functions whatever you’d like, although keeping descriptive names will make your code more readable. The library automatically populates the function parameters with the data it receives for each respective message.

At the end of the setup function you also to call begin() before the library will start reading the incoming MIDI messages. begin() takes one parameter, which is the MIDI channel to listen to. You can use MIDI_CHANNEL_OMNI to listen to all channels at once. If you don’t provide a parameter it listens to channel 1 only.

Read MIDI Messages

The last and crucial step is to make sure you’re calling the library’s read function to parse any incoming MIDI data. Incoming data will be handled by the respective handler functions, but if you don’t call read the library won’t receive any data to process.

Write Your Code!

With the instance created and the handlers in place, now you can write your code to be controlled by MIDI!

A Demonstration: MIDI Visualizer

To demonstrate, I’m going to write the code for a basic MIDI visualizer that uses my favorite WS2812B addressable LEDs. The goal is to have LEDs on the strip correspond to different notes on the keyboard so they light up when a key is pressed, and turn off when the key is released.

To make it slightly more interesting, we can map some continuous controllers to change the colors on the fly.

Custom Instance

This visualizer is going to use an Arduino Uno, which doesn’t have native USB support. To get around this I’m going to use the Hairless MIDI to Serial Bridge to convert the MIDI messages into generic serial messages. You can see this post for more information.

For Hairless we’re going to change the Arduino’s baud rate from 31250 to 115200, which requires a custom MIDI instance:

Adding Handlers

This visualizer makes use of three MIDI messages: note on, note off, and continuous controller:

The “note on” and “note off” functions will mirror each-other: we’re going to check if the note is in the range we can play, set the LED color, and then refresh the LED strip.

To control this visualizer I’m going to use a Novation Launchkey Mk II, which is a class compliant MIDI controller and has 8 rotary potentiometers that act as continuous controllers. These potentiometers are mapped to MIDI controller numbers 21 through 28, respectively.

I’m going to use the first three potentiometers to adjust the LED color channels: red, green, and blue. The code uses a switch() statement to check if the received control number matches one of the three color controls. If it does, the value from the controller is remapped from the MIDI range of 0 – 127 to the 8-bit range 0 – 255, and then the LEDs are updated.

LED Functions

Since I did my testing with an RGBW strip, I’ve written the code to work with both the Adalight NeoPixel and FastLED libraries. To keep the code clean, the specific library functions are encapsulated in their own helper functions.

I’m also using a boolean array to keep track of whether an LED is on or not for the redrawing function. This could be made more efficient, but for this example there’s plenty of memory available on the microcontroller.


Voilà! With just a few lines of code and the Arduino’s MIDI library, I built a basic MIDI visualizer with colors you can tweak via MIDI continuous controllers. Cool, huh?

Here is the full sketch, if you’d like to replicate this yourself. You can also find it on Github.

Note that WS2812B LEDs are a poor choice for this because you’ll lose data during the LED latching, which can cause LEDs to be “stuck” on until they receive a MIDI off packet. But they’re one of the most common addressable LED types, and I still had plenty left over from the ambilight project.


This post is meant to be a primer – there is much more to MIDI and the Arduino’s MIDI library that I didn’t have time to touch on, notably how to send data back over MIDI. But hopefully you learned how to get started with the library and how to use MIDI data in your code.

For my example I used some addressable LEDs, but this can truly be used to control absolutely anything – servo motors, relays, speakers, serial messages… the list goes on and on. If you can control it with an Arduino and receive serial data, you can control it with MIDI.

If this tutorial helped you to build something controlled with MIDI, I’d love to see what you’ve come up with!

One thought on “How to Control Anything on Arduino Using MIDI”

Leave a Reply

Your email address will not be published. Required fields are marked *