Wednesday, October 24, 2012

A Very Simple DIY USB MIDI Controller

The aim of this post is as a starting point for making your own DIY MIDI controller. Although many MIDI controllers can be purchased off the shelf, there may be times when a DIY approach is more economical or more appropriate in terms of specific design and mapping.

This is one of the simplest MIDI controllers that I can think of - it is just a pot (i.e. "knob") that sends USB MIDI continuous controller data on CC#1, channel 1.



Hardware needed:
• 1 x Teensy board with pins
• 1 x USB A to B mini cable
• 1 x 100kΩ B-type potentiometer
• 1 x mini breadboard
• 3 x breadboard jumpers (can use a jumper kit for instance)

Software needed:
Arduino IDE
• A digital audio workstation (DAW) such as Ableton Live

Hardware Setup

This is the pinout of the Teensy 2.0 Board with Pins. For this very basic example, we are only interested in three of these pins - the ones marked Ground, +5 Volts and A0.

Place the Teensy 2.0 Board with Pins into the breadboard, so that one half of the pins are on the left side of the gap in the middle of the breadboard and the other half are on the right, as shown.

Place the pot so that it sits across five rows of the breadboard, as shown.

The pot has three legs in a row. Connect ground to one of the outside legs. It doesn't matter which one. Ground is marked Ground on the above wiring pinout diagram and marked GND on the physical board. 

Connect the other outside leg of the pot to five volts (marked +5 Volts on the above wiring pinout diagram and marked VCC on the physical board).

Finally, connect the middle or inner leg of the pot to analog input zero (marked pin 21 A0 on the above wiring pinout diagram and marked F0 on the physical board)

Software Programing
Install the Arduino IDE software as instructed on the Arduino website. Install the Teensyduino component software as instructed on the Teensyduino website.

 Open the Arduino software. Create a blank Arduino sketch by going to File > New.

Save your Arduino sketch and give it an appropriate name. In this example, it is called "Simple_DIY_Controller". 

Type the following code:

void setup() {

void loop() {
   usbMIDI.sendControlChange(1, analogRead(0) / 8, 1);

Save your sketch.

void setup() { } is an area of the code where we might set something up like inputs or outputs or software serial connections. Our USB and MIDI functionality on the Teensy board does not need to set up, so there is no code that belongs here.

void loop() { } is our main program loop. In our void loop() { } we have two lines of code:

usbMIDI.sendControlChange( )
delay( )

usbMIDI.sendControlChange( ) is the first line of code and sends the MIDI Continuous Controller message via USB. It takes three arguments, separated by commas - in the above example given as:

(1, analogRead(0) / 8, 1)

The first argument is the controller number, which is 1 (i.e. modulation). This can be a value between 0 and 127.

The second argument is the actual controller value, which is the data as read from the pot. The second argument in the above example is analogRead(0) / 8. The function analogRead(0) reads the analog input pin 0 (the middle leg of the pot) and gives a value between 0 and 1023 depending on the current position of the pot.

However, the range of a MIDI continuous controller is from 0 to 127. We can divide the value given by analogRead(0) by 8 to get a useable range from 0 to 127.

The third argument is the MIDI channel number, which is given in the above example as 1. This can be a value between 1 and 16.

For more information regardingArduino functions see the Arduino reference. For more information regarding using Teensy with MIDI functions, see the Teensy MIDI reference.

The second line of code is delay(5). This is simply five milliseconds of delay time before our code repeats and our pot is read again and sent as a MIDI continuous controller via USB.

Next, go to Tools > Board and choose Teensy 2.0. This selects the Teensy board.

Also, go to Tools > USB Type and choose MIDI.This sets the Teensy board into MIDI mode. Now, go to File > Upload Sketch and wait for the Arduino software to upload your code to the Teensy board. The Teensy loader will launch in the background.

If your Teensy board does not respond or if the code does not upload correctly, you may need to press the tiny black button that is physically on the Teensy board.

Software Setup and Using the Controller
Now it's time to set up your DAW. This example will be for Ableton Live, but in general it should work with other software packages. Go to the preferences and choose the MIDI Sync tab. The Teensy USB device should appear. It may be called "TeensyUSB", but in my case it is called "Seb's MIDI Device".

Make sure that the Track and Remote columns are set to On for the Input section of the device. 

Press command M to enter MIDI Map mode. Select parameters that should be controlled via the pot and turn the pot. You should see a mapping that links CC #1, channel 1 to the chosen parameter(s) Exit mapping mode by pressing command . Turn the pot and see the parameter move!

Wasn't that easy? Of course, the above can be extended to create a vast range of MIDI controllers. 
Hopefully this is a useful starting point, though.


Michael said...

Very nice writeup.

In fact, I'm not sure where you find all the time and patience for all of your useful posts. I recently built a MIDI stomp pedal board with Teensyduino and announced it on the forum for an app I like to use

Of course, having done that, now I have also volunteered myself to write up a nice to-do doc like you've just done here.


Anonymous said...

Hi, I saw the small Project and I was hit by the facility of the controller and for this reason I bought a teensy!
It is fantastic, but I have a problem, when I try to learn to the potentiometer the controller on the software it auto learn the command without touch the real pot. Do you have the same problem?! thanks a lot!

griv said...

Awesome post. Really easy to follow. :)

How did you rename your Teensy to be something other than Teensy USB?

griv said...

I had the same problem. In fact it's worse when you attach multiple pots as they are all sending all the time.

I copied some code from here:

It temporarily stores the value of each pot and then only send MidiCC when the value changes above a threshold.
It's working well, and it a;so means you don't need the delay() because it only sends when it detects a change in the pot value.

Anonymous said...

Thank you so much for this tutorial! I've been looking everywhere for a straight forward intro like this!