Source: https://mokxi.com/libraries/midi
Updated: 2026-11-02

Libraries / Communication
Arduino library · Communication

# The Arduino MIDI Library: send and receive notes over serial

The MIDI Library from FortySevenEffects is how an Arduino becomes a MIDI instrument or controller: it builds and parses MIDI 1.0 messages (note on and off, control change, program change, pitch bend, SysEx) on a serial port running at MIDI’s 31250 baud, through a 5-pin DIN socket with an optocoupler on the input side.

Open the example in the editor See the calls

Built in on Mokxi: #include <MIDI.h> and it builds, with nothing to install. Free, and no account needed.

## What MIDI Library does

MIDI_CREATE_DEFAULT_INSTANCE() makes an object called MIDI on the board’s first serial port. On an Uno that is the same Serial the USB monitor uses, so a MIDI sketch and Serial.print() debugging cannot share it; boards with a second port use MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI) instead.

Reading works through handlers. You register functions such as setHandleNoteOn(), call MIDI.read() on every pass of loop(), and the library calls the right handler for each message. By default begin() also turns on Thru, echoing everything that comes in back out, which surprises people whose controller suddenly doubles every note.

Library Manager name | MIDI Library

Author | Francois Best, lathoub

Include | #include <MIDI.h>

Boards | every board Mokxi compiles for but ATtiny85

In the simulator | Runs, with a gap the note below names.

## Install it

It builds on every board Mokxi compiles for but ATtiny85.

In Mokxi it is built in: #include <MIDI.h> and the sketch compiles, with no download, no zip and no Library Manager.

On a real board, install "MIDI Library" by Francois Best, lathoub from the Arduino IDE’s Library Manager (Sketch, Include Library, Manage Libraries), or add MIDI Library to lib_deps in PlatformIO. Mokxi follows the calls of release 5.0.2, so a sketch written here builds there too.

What to know in the simulator: There is no MIDI instrument part, so the bytes reach the serial monitor raw. A transport class of the sketch’s own works as upstream.

ESP32-C3 · Arduino Uno · Arduino Nano · Arduino Mega 2560 · Arduino Leonardo · SparkFun Pro Micro · Arduino Micro · ESP32-C6 · Raspberry Pi Pico · Raspberry Pi Pico W · Seeed XIAO SAMD21 · STM32 · STM32 Nucleo-F411RE · STM32 Blue Pill · micro:bit V2 · Arduino Uno R4 · ESP32 DevKit · ESP32-S3-DevKitC-1 · ESP8266 NodeMCU · Arduino Pro Mini 3.3 V · Seeed XIAO ESP32-C3 · ESP32-C3 SuperMini · Seeed XIAO ESP32-C6 · ESP32-DevKitC V4 · LOLIN32 Lite · Wemos D1 R32 · Cheap Yellow Display · TTGO T-Display · Seeed XIAO ESP32-S3 · Arduino Nano ESP32 · Arduino Nano RP2040 Connect · Seeed XIAO RP2040 · Waveshare RP2040-Zero · Arduino Uno R4 WiFi

## The calls you will use

In the order a sketch meets them.

### MIDI_CREATE_DEFAULT_INSTANCE()

Declares the MIDI object on the default serial port. Put it at the top of the sketch, outside any function.

### MIDI.begin(MIDI_CHANNEL_OMNI)

Starts the port at 31250 baud and listens on every channel. Pass 1 to 16 to listen on one channel only.

### MIDI.sendNoteOn(60, 127, 1)

Sends middle C at full velocity on channel 1. Follow it with sendNoteOff(60, 0, 1) or the note hangs.

### MIDI.sendControlChange(7, analogRead(A0) / 8, 1)

Sends a control change, here controller 7 (volume) from a potentiometer scaled to 0 to 127.

### MIDI.sendProgramChange(5, 1)

Asks the receiving synth to switch to patch 5 on channel 1.

### MIDI.setHandleNoteOn(handleNoteOn)

Registers void handleNoteOn(byte channel, byte pitch, byte velocity), called from read() for each incoming note.

### MIDI.read()

Reads what has arrived, runs the matching handler and returns true when a message was read. Call it on every pass of loop().

### MIDI.turnThruOff()

Stops echoing incoming messages to the output, which begin() turns on by default.

## Example: MIDI messages sent and read back through a loopback transport

On the Arduino Uno R3. It runs in the browser exactly as printed.

sketch.ino · Arduino Uno R3

Open it in the editor, wired and ready to run

## Common errors and how to fix them

### The serial monitor shows garbage once MIDI.begin() runs

MIDI takes over the serial port at 31250 baud, which the monitor cannot show as text. Debug on a second port, or use a USB MIDI board such as the Leonardo with MIDIUSB, or a serial to MIDI bridge on the computer.

### Every note is played twice, or a loop of notes builds up

Thru is on by default and echoes incoming messages back out, which a DAW then sends back again. Call MIDI.turnThruOff() after begin() unless you want the echo.

### Handlers never run

MIDI.read() must be called often, on every pass of loop(), with no long delay(). Also check that begin() listens on the channel the sender uses, or use MIDI_CHANNEL_OMNI.

## Keep going

### Learn

- UART Serial Explained: Baud, Frames and the Wire

### More communication libraries

- OneWire
- TinyGPS
- TinyGPSPlus
- MFRC522
- SoftwareSerial
- AltSoftSerial
- i2cdetect
- Keyboard

Every built-in library · Open the editor

## Try MIDI Library without installing anything

Open the example, change the sketch, and keep your version in a free account.

Start building free

Open the editor
