skip navigational linksPJRC
Shopping Cart Checkout Shipping Cost Download Website
Home MP3 Player 8051 Tools All Projects PJRC Store Site Map
You are here: Teensy Teensyduino Libraries MIDI

PJRC Store
Teensy 3.1, $19.80
Teensy 2.0, $16.00
Teensy++ 2.0, $24.00
USB Cable, $4.00
Teensy
Main Page
Teensy 3.1
Getting Started
How-To Tips
Code Library
Projects
Teensyduino
Reference

MIDI Library

MIDI, by Francois Best, allows you to control and receive data from musical instruments.

Download: MIDI_3.2.zip, Version 3.2 (GPLv3)
MIDI_2.6.zip, Version 2.6 (public domain)

MIDI 2.6 and 3.2 and later support all Teensy models.

Hardware Requirements

MIDI uses the UART to communicate with standard MIDI devices at 31250 baud. This is completely separate from, and can be used together with USB MIDI.

You can use Serial.print() to observe what your program is doing, while using MIDI, or USB MIDI.


MIDI connects using the UART's transmit and receive pins.

SignalTeensy 1.0Teensy 2.0Teensy 3.0Teensy++ 1.0Teensy++ 2.0
Receive (Rx)Pin 2Pin 7Pin 0Pin 2Pin 2
Transmit (Tx)Pin 3Pin 8Pin 1Pin 3Pin 3

MIDI input requires an optically isolated input. Output requires only 2 resistors. The following schematic is recommended.


Teensy 3.0: Use two 47 ohm resistors on MIDI OUT, with the pin 4 resistor to +3.3 volts. For MIDI IN, connect the 270 ohm resistor to +3.3 volts. (TODO: add a Teensy 3.0 specific schematic here)

When connecting the signals, be sure to connect to the correct pins.



Basic Usage

MIDI.begin(MIDI_CHANNEL_OMNI);

Initialize the MIDI library. The receive channel may be specified, or MIDI_CHANNEL_OMNI to receive all 16 channels. This only affects reception. You can send on any MIDI channel regardless of this setting.

MIDI.sendNoteOn(note, velocity, channel);
MIDI.sendNoteOff(note, velocity, channel);
MIDI.sendProgramChange(note, velocity, channel);
MIDI.sendControlChange(note, velocity, channel);
MIDI.sendPitchBend(note, velocity, channel);
MIDI.sendPolyPressure(note, velocity, channel);
MIDI.sendAfterTouch(note, velocity, channel);

Transmit basic MIDI messages. These allow you to easily send each MIDI message.

MIDI.read();

Receive a MIDI message. This returns true if a message has been received, or false if no new message has arrived. After returning true, the get functions can be used to obtain the MIDI message information.

MIDI.getType();

Returns the type of message received. The types are:
       NoteOff
       NoteOn
       AfterTouchPoly
       ControlChange
       ProgramChange
       AfterTouchChannel
       PitchBend
       SystemExclusive

MIDI.getData1();
MIDI.getData2();

These return the 2 data bytes of the received MIDI message.

Example Output Program


This simple examples sends a rapid sequence of notes. Not very exciting, but a simple and easy test.

#include <MIDI.h>

const int channel = 1;

void setup() {
  MIDI.begin();
}

void loop() {
  int note;
  for (note=10; note <= 127; note++) {
    MIDI.sendNoteOn(note, 100, channel);
    delay(200);
    MIDI.sendNoteOff(note, 100, channel);
  }
  delay(2000);
}

Example Input Program


/* MIDI Input Test - for use with Teensy or boards where Serial is separate from MIDI
 * As MIDI messages arrive, they are printed to the Arduino Serial Monitor.
 *
 * Where MIDI is on "Serial", eg Arduino Duemilanove or Arduino Uno, this does not work!
 *
 * This example code is released into the public domain.
 */
 
#include <MIDI.h>

void setup() {
  MIDI.begin(MIDI_CHANNEL_OMNI);
  Serial.begin(57600);
  Serial.println("MIDI Input Test");
}

unsigned long t=0;

void loop() {
  int type, note, velocity, channel, d1, d2;
  if (MIDI.read()) {                    // Is there a MIDI message incoming ?
    byte type = MIDI.getType();
    switch (type) {
      case NoteOn:
        note = MIDI.getData1();
        velocity = MIDI.getData2();
        channel = MIDI.getChannel();
        if (velocity > 0) {
          Serial.println(String("Note On:  ch=") + channel + ", note=" + note + ", velocity=" + velocity);
        } else {
          Serial.println(String("Note Off: ch=") + channel + ", note=" + note);
        }
        break;
      case NoteOff:
        note = MIDI.getData1();
        velocity = MIDI.getData2();
        channel = MIDI.getChannel();
        Serial.println(String("Note Off: ch=") + channel + ", note=" + note + ", velocity=" + velocity);
        break;
      default:
        d1 = MIDI.getData1();
        d2 = MIDI.getData2();
        Serial.println(String("Message, type=") + type + ", data = " + d1 + " " + d2);
    }
    t = millis();
  }
  if (millis() - t > 10000) {
    t += 10000;
    Serial.println("(inactivity)");
  }
}


Demo Board, PCB Design Files

The demo board shown above was created to test the MIDI library with Teensy 2.0. It is not sold by PJRC. However, if you would like make this same board, here are the files:

Single Side Version
Standard Version

The board in the photos was fabricated by Futurlec. Their single-side service is probably the least expensive for only a single piece. When PJRC made this prototype, Futurlec's service was very slow.... so slow that we have not used them since.

For the highest quality, OSH Park is usually best. Using the normal files, you should see this preview when using their website.

The extra diode between the 2 MIDI connectors is a 5.6V zener. Other than this extra diode, the circuit board followed the schematic shown above. The zener diode is not necessary for normal opertation, but does provide extra protection if external voltage is applied to the MIDI OUT port.

Details

The official MIDI library is hosted on SourceForge. This older Arduino Playground page has additional information.