empowering creative people

USB MIDI With Teensy

If you’re a musician or have had anything to do with the entertainment industry, you may have heard of the term MIDI before. MIDI stands for Musical Instrument Digital Interface and was created in the mid-80’s as a way to standardize the connection of digital instruments and hardware. MIDI is used in everything from keyboards and synthesizers, lighting cues and stage data, to specific MIDI controllers which are hardware interfaces designed to send MIDI commands to other MIDI-enabled devices. This won’t be a tutorial covering how MIDI works at a lower level and the specifics of the protocol, that’s a conversation for another time so keep an eye out for that one, however, today, we’ll be looking at how we can use a Teensy board to easily create a powerful MIDI device.

DIN-5 MIDI vs. USB MIDI

MIDI association logo

When MIDI was first introduced, it utilized the DIN-5 connector because it was a fairly unique connector that couldn’t be connected the wrong way, and allowed for a robust connection. As the name implies, DIN-5 is a 5 pin connector with 4 data wires and a ground wire which also doubles as a shield to prevent interference and protect signal integrity. Standard MIDI communication only uses 2 wires for communication, however, the DIN-5 connector was chosen to allow for future expansion of the protocol if need be. Mostly, though, the outer two wires on a DIN-5 connector remain unconnected. Because it is a form of serial communication, standard MIDI can be transmitted and received using a UART (TX/RX) port on a microcontroller using a special baud rate of 31250.

However as technology has shifted and developed, with the USB protocol becoming universal for most devices, almost every MIDI device now offers a USB connector as well as/instead of the typical DIN-5 connector. Computers recognize USB devices that are class-compliant MIDI devices automatically and require no special drivers to use and are regarded as plug-and-play devices. USB offers significant improvements to carry MIDI data because of the high-speed and bandwidth available which means a single cable can carry more data alongside the MIDI signal.

Teensy 3.2 boardWhy Teensy?

One of the main reasons that Teensy gained so much popularity with the maker community is that it introduced the ability to assign a different USB device type to your Teensy board, MIDI, HID, Joystick, along with regular Serial. This is cool because it allows your Teensy to behave as a class-compliant device which lets it communicate with your computer as that device type without needing any drivers and special software.

So this is really good news for us makers, because as you guessed, there is a MIDI library available for the Arduino IDE which we can use to program our Teensy boards and create awesome MIDI controllers. As mentioned previously, this tutorial is specifically about how to program Teensy boards as USB MIDI controllers, not the MIDI protocol, so we won’t be going into all of the details of the MIDI bytes and what they mean. That’ll be in a separate tutorial under Digital Electronics, so check it out.

The Gear:

To follow this tutorial, all you’ll need is a Teensy board (preferably a 3.x model) and any sensory input of your choice. This could be simple push buttons, potentiometers, encoders, whatever you want. For information on how to connect potentiometers, buttons and other devices up, check out some of our other tutorials which walk through the hardware setup for those.

The Code:

Here is a simple program which utilises the combined Serial + MIDI profile of the Teensy so that we can print some data back. All we’re doing is reading the value of a potentiometer, doing some smoothing, and then updating that data as a continuous controller message via the USB connection. We’re also listening for any incoming continuous controller messages (CC message list available here), and printing them to the serial monitor.

int potPin = A5;

const int numReadings = 20;

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
int lastAverage;

void setup()
{
  pinMode(potPin, INPUT);
  usbMIDI.setHandleControlChange(OnControlChange);
  Serial.begin(9600);
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }
}

void loop()
{
  usbMIDI.read();
  //if there is a change, send and print it as a CC message
  if(average != lastAverage)
  {
    usbMIDI.sendControlChange(7, average, 16);
    Serial.print("Sent Volume: ");
    Serial.println(average);
  }
  lastAverage = average;
  delay(1);
}

void smoothing()
{
  total = total - readings[readIndex];
  readings[readIndex] = analogRead(potPin);
  total = total + readings[readIndex];
  readIndex = readIndex + 1;

  if (readIndex >= numReadings) {
    readIndex = 0;
  }
  average = total / numReadings / 8;
}

void OnControlChange(byte channel, byte control, byte value)
{
  Serial.println("Channel: ");
  Serial.print(channel);
  Serial.println("Control: ");
  Serial.print(control);
  Serial.println("Value: ");
  Serial.print(value);
}

The code is fairly basic, but that’s the idea. It shows how easy it is to create a USB MIDI device using Teensy. For more info about the built in USB MIDI library functionality for Teensy, check out the PJRC page, and let us know what awesome projects you plan on building!

If you’re a musician or have had anything to do with the entertainment industry, you may have heard of the term MIDI be...

Have a question? Ask the Author of this guide today!