Background
Until recently, I had used an Arduino to output readings from potentiometers over serial USB, convert it to MIDI in Pure Data and then send it to Ableton Live. This convoluted setup has one clear drawback: you always have to have PD running to convert the serial to MIDI. I wanted something that wouldn’t rely on any other software; not least because it becomes increasingly difficult to configure MIDI settings in PD once you’ve had some Dutch courage prior to your set.
In order to simplify things, I set out to make a class compliant HID midi controller. A simple, and cheap, way I found was to use the Teensy microcontroller. What’s even better is that you can also you use the Arduino IDE to build and upload sketches using the Teensyduino add-on.
The Teensy USB Development Board is a complete USB-based microcontoller development system. Only a standard Mini-B USB cable (sold separately) is needed to connect to a PC or Macintosh.
I recently got a Teensy microcontroller as part of a Build Brighton group buy. It can be purchased directly from the manufacturer but those living in Europe might find it cheaper to purchase from Floris.
Hardware
Connecting potentiometers to the Teensy is fairly easy and they have a great tutorial on their website. Simply connect your potentiometers to +5v, ground and to the Teensy’s analog inputs (A0, A1, A2, A3, A4 & A5).
Software
Use the tutorial here to get up to speed with how to use the Teensy. It provides details on how to upload sketches, install the Teensyduino add-on etc. Now, back to business, make sure you’ve selected MIDI from Tools > USB. This will allow your device to be recognised as an HID device, without requiring any other drivers. Neat, huh? Now, upload the sketch below.
// Teensy Midi Controller // Philip Cunningham // http://philipcunningham.org // Smoothing hacked from // http://www.arduino.cc/en/Tutorial/Smoothing // Smoothing amount const int numReadings = 30; // Set the readings from the analog input to 0 int readings[numReadings] = {0,0,0,0,0}; // The number of pots int pots = 6; // The index of the current reading int index = 0; // Running total int total = 0; // Pin total int pintotal[6] = {0,0,0,0,0}; // Pin average int average[6] = {0,0,0,0,0}; // Set midi channel to send to 1 int channel = 1; // Set the last readings to 0 int lastreading[6] = {0,0,0,0,0}; void setup() { // Standard midi rate Serial.begin(31250); } void loop() { // Get reading for all potentiometers for (int i = 0; i < pots; i++ ) { // Set index to zero index = 0; // Loop to create average reading for (int j = 0; j < numReadings; j++ ){ // Subtract the last reading total = total - readings[index]; // Read from the sensor readings[index] = analogRead(i); // Add the reading to the total total = total + readings[index]; // Advance to the next position in the array index = index++; pintotal[i] = total; } // Calculate the average // Divide by 8 to make between 0-127 average[i] = (pintotal[i]/numReadings)/8; // If reading is different from the previous if (lastreading[i] != average[i]){ // Send midi data usbMIDI.sendControlChange(i, average[i], channel); } // Set last array value to current value lastreading[i] = average[i]; } // Delay output by 5ms delay(5); }
The sketch above was written for my controller, which has six potentiometers. So, if you’ve got four, three or eight pots, you’ll have to change the code slightly to reflect this. Check the comments in the code, it isn’t really hard to do; unless you’ve got more pots than analog pins. Then things become more complicated. If this sounds like you, try investigating something called multiplexing.
Conclusion
You should now have a class compliant HID MIDI controller that wont require any additional drivers, software, etc. Go forth and twiddle some knobs.