Paint a MIDI Controller with Teensy

This tutorial is based on a classroom activity originally designed by Matt Jackson, used with his permission.

Teensy is an excellent platform for designing touchable controllers as you can create single wire capacitive touch sensors with minimal effort. Combining this with the fact that Teensy can be configured out of the box to work as a Class Complaint USB MIDI device with minimal effort means that you can start experimenting with exotic interfaces for music making in a matter of hours. This tutorial is designed to give you an idea of just one way you might go about doing that.

Click here for an extended tutorial on adding MIDI CC controls to this project

Contents

  1. Material Check List
  2. Basic Setup and Touch Test
  3. Add MIDI commands to your patch
  4. Paint a MIDI Controller
  5. Have Fun!

This tutorial assumes a basic knowledge of the Arduino IDE, setup and programming of Teensy, and basic knowledge of components. If you haven’t done so already, please download the latest compatible version of the Arduino IDE and Teensy loader (at the time of writing, 1.6.11 is the latest compatible version). Should you need to, follow the getting started tutorials on the PJRC site before attempting this tutorial.

1. Material Check List

Materials required for this project are:

  • A Teensy 3.0 or higher with pins soldered and Micro USB cable
  • A small breadboard
  • 22pf capacitors
  • Hookup wires and Crocodile Clip Wires
  • Paper or card to paint on, or a thin non-conductive material
  • Conductive paint such as “Bare Conductive” tubes or pots
  • A paint brush
  • Your personal computer, equiped with the Arduino IDE, Teensy libraries and music software with some kind of soft synth that can respond to MIDI.

2. Basic Setup and Touch Test

Once you are armed with the Arduino IDE and Teensy loader, lets begin by just getting a reading from the capacitive touch sensors on the Teensy. Try building the following example on breadboard:

teensy-touch-test_bb

The capacitors are 22pf, but they aren’t totally necessary, just ignore them if you don’t have them. Check your connections before moving on.

Now plug in the Teensy board to your computer and open up the Arduino IDE. We will use the built in Serial prompt to check if we can get a reading by touching the ends of the aerial wires. Enter the following code into Arduino:

// initialise pins 

uint8_t touchPin[2] = {19, 18}; // make a list of the pins with aerials

// create stored values

int ntouch = 2; // used in for loop criteria, increase to use more touch pins
int touchValue = 0; // stored value for touch readings

void setup() {
  Serial.begin(38400); // enable serial
  delay(200);
}

void loop() {

  for(uint8_t i=0; i < ntouch; i++) {
    // for loop will scan each of the touch pins defined at the top before 
      // moving on, a new stored value "i" is created here and used below
        // to recall values from our list(s) at the top

  touchValue = touchRead(touchPin[i]); // touchValue is set by reading a pin
    // touchRead is part of the Teensy library

  Serial.print("touchPin: ");
  Serial.print(touchPin[i]);
  Serial.print(" ");
  Serial.print("Value: ");
  Serial.println(touchValue);

  // this will print out the value of each pin to the Serial Monitor
    // the Serial Monitor can be found in the Tools menu
      // set the baud rate to 38400

  delay(100); // for the sake of readability, this pauses each loop for 100ms

  }
}

You can download the code here if you don’t want to type it out or copy it over.

Hit the Verify button in the top left of the Arduino window, and the software will check your code for any errors. If you typed out the code yourself, you will need to save your patch first. The prompt should look something like this:

aerialtestverify-copy

Before you upload it to the Teensy board, make sure that in Tools > USB Type, “Serial” is selected. You should also make sure that Arduino knows to expect a serial prompt from the correct port, so go into Tools > Port and you should see a usb option related to your Teensy board.

Once you are satisfied that everything is working, hit the Upload button in the top left corner of the Arduino IDE. Wait for the upload to complete, it sometimes pauses briefly. The code will be written to the Teensy, but the Teensy may not automatically restart and you will get a warning message in the Arduino window telling you so. Simply press the button on the Teensy board and the new program will be executed.

RestartError copy.png

Now open the Serial Monitor found under Tools in Arduino, and set the baud rate (bottom right) to 38400. If everything has gone to plan, you should see a stream of numbers that looks something like this:

serial-monitor-copy

If you do, great! You should notice that when you touch the end of one of your Aerial wires, the corresponding value will change in the Serial Monitor. If you aren’t getting the expected results, work though each step in this section again to troubleshoot.

3. Add MIDI commands to your patch

Now we are going to tell the Teensy to be sensitive to a change in capacitance, and respond by triggering a fixed MIDI note. No need to modify the circuit just yet, enter the following code into the Arduino IDE, but don’t upload it to the Teensy just yet:

// initialise pins 

uint8_t touchPin[2] = {19, 18};

// create stored values

int ntouch = 2;
boolean touchState[2] = {false, false};
int touchValue = 0;
uint8_t midiNotes[4] = {60, 72};


void setup() {
  Serial.begin(38400);
  delay(200);

}

void loop() {

  for(uint8_t i=0; i < ntouch; i++) {   touchValue = touchRead(touchPin[i]);   Serial.print("touchPin: ");   Serial.print(touchPin[i]);   Serial.print(" ");   Serial.print("Value: ");   Serial.println(touchValue);   if(touchValue > 2400 && !touchState[i]) {
    usbMIDI.sendNoteOn(midiNotes[i], 99, 1);
    touchState[i] = 1;
  }
  else if(touchValue < 2400 && touchState[i]) {
    usbMIDI.sendNoteOff(midiNotes[i], 0, 1);
    touchState[i] = 0;
  }
  }

  while (usbMIDI.read()) {
    
  }

}

You can download the code here if you don’t want to type it out or copy it over.

We haven’t changed things too much, but a couple of new lines have been added. There are two lines you should take note of towards the end of the program that make up the “if” argument. In C and some other languages, a line containing “if” makes the program check the argument criteria between the brackets (), and if the argument passes then the program will execute the next couple of lines, otherwise it will bypass them.

“touchValue” is a stored value in our program for the capacitance level and “touchState” is a on/off value that is used to set if a wire is already being touched. So the argument is like this: “if the capacitance is greater than 2400 and a wire is not being touched, then do this:”.

The reason I am pointing this out to you is that your capacitance value may be different to my capacitance value – capacitance levels vary depending on the length of wires and other factors in the circuit, so it may be necessary to add some calibration to your program. Go back to your Serial Monitor and check the difference in values between an untouched wire and a touched wire – make a note of the range. In the new program, we are using “2400” in the argument criteria, this was because for me, an untouched wire gave a reading of around 2200, and a touched wire gave a reading of 6000. Go into your program and replace “2400” in the two lines with a threshold that is functional for your circuit – add about 200 to the lowest value.

Once you have made the adjustment, go into Tools and change “USB Type:” to “Serial + MIDI”, then click the Verify button and if Arduino doesn’t report any errors, go ahead and upload the new program to the Teensy board.

When you set the USB Type this way and upload your code, the Teensy will automatically become a Class Complaint USB MIDI device, meaning that when you open music software that is MIDI compatible, it will be able to automatically detect the Teensy as a MIDI ready device! I used Ableton Live and soft synth Aalto to test my patch, but you can work with anything you want. Go into your software settings, and make sure the Teensy is selected as a MIDI input:

touchmidi-tutorial

Now load a soft synth into your software, arm the channel to receive MIDI on Channel 1 and try touching the two wires, if everything checks out you should here some sounds! If you don’t, check you have your music software set up properly, and then check over this section of the tutorial – in particular, make sure the detection threshold is set up correctly for the touch sensing, I included a serial prompt in this program, so you can still monitor the capacitance value in the Serial Monitor. If everything is working you can move on:

4. Painting a MIDI Controller

Here’s a picture from one of my students:

img_2502

The Teensy 3.2 has 9 pins that work as capacitive touch sensors. This means we could have up to 9 MIDI notes by making some simple adjustments to our MIDI patch, the diagram below shows the function(s) of each pin on the Teensy 3.2:

teensy32_front_pinout

Let’s stick with 7 pins as this makes a nice musical scale across an octave. We will need to adapt our circuit first, so unplug the USB lead from the Teensy before you continue.

As you can see from the diagram, we can use the top pins 23, 22, 19, 18, 17, 16 and 15 as Touch pins, add wires to these pins on your breadboard now:

teensy-touch-test-expanded_bb

I’ve just shown 3 wires attached to pins 17, 16 and 15 to save confusion, but you want to duplicate the idea for the seven pins mentioned. Once you have done that and you have checked your wiring, enter this code into the Arduino IDE:

// initialise pins 

uint8_t touchPin[7] = {23, 22, 19, 18, 17, 16, 15};

// create stored values

int ntouch = 2;
boolean touchState[7] = {false, false, false, false, false, false, false};
int touchValue = 0;
uint8_t midiNotes[7] = {60, 62, 64, 65, 67, 69, 71}; // C oct5 major scale


void setup() {
  Serial.begin(38400);
  delay(200);

}

void loop() {

  for(uint8_t i=0; i < ntouch; i++) {   touchValue = touchRead(touchPin[i]);   Serial.print("touchPin: ");   Serial.print(touchPin[i]);   Serial.print(" ");   Serial.print("Value: ");   Serial.println(touchValue);   if(touchValue > 2400 && !touchState[i]) {
    usbMIDI.sendNoteOn(midiNotes[i], 99, 1);
    touchState[i] = 1;
  }
  else if(touchValue < 2400 && touchState[i]) {
    usbMIDI.sendNoteOff(midiNotes[i], 0, 1);
    touchState[i] = 0;
  }
  }

  while (usbMIDI.read()) {
    
  }

}

You can download the code here if you don’t want to type it out or copy it over.

The only things we have changed are the criteria that tell the program how many Touch pins we are using, which touch pins and which corresponding notes to play. You can try uploading this firmware now, and touch the wires to check you get all 7 notes. You should hear the 5th octave C major scale if everything checks out.

Now lets make a painting!

What you technically need to do for this to work is to paint a single line on your surface for each Touch pin, so you need seven lines that don’t touch each other. So long as you follow that as a rule you can paint what ever you like – each of the seven lines should reach the edge of the surface at some point.

Some tips on using conductive paint – it’s not the most appealing colour, and it’s a lot thicker than standard paint and it takes at least an hour to become touch dry. Don’t expect your first attempt to come out perfect, just paint something as a test. In my test, I squirted a blob of paint on a corner of the page from my tube of “Bare Circuit” brand, then I used a small paint brush to distribute it. You can lay the paint relatively thin, but aim for any lines to be solid in colour, any breaks will most likely not conduct.

Here is my first picture with some weird plant like images to touch:

There is a nice method of thining conductive paint to make it go further in this article and it’s well worth looking over the Bare Circuit site for some further ideas.

Once you have painted a design on paper or other surface, put it somewhere secure to dry. Once it has dried, you can hook it up to your circuit, take a crocodile clip for each Touch pin and clip one end to the stripped end of an aerial wire to a point where one of your painted lines meets the edge of your surface.

Now plug your Teensy board back in and open up your MIDI compatible software and soft synth. Make sure Teensy is activated as a USB MIDI device in your software and try touching some points in your painting – you should hear notes play from the C major scale!

If you don’t hear anything, check that you don’t need to adjust the touch detection threshold in your code, remember that by connecting to points on your picture, you are effectively making really long wires, so the capacitance levels will be different. If you find that some notes activate whilst others don’t, check that the crocodile clips are definitely secure and making a good electrical connection.

5. Have Fun!

Now that we have the hardware working you could think about making a more interesting picture – try making something where your painted lines or objects perhaps come very close to each others at some points, and are further away at others. Make something that is interesting to interact with, perhaps make some kind of maze where it is hard to tell which end is connected to which start. Next you should go to your soft synth and make an expressive patch that reflects your painting, when you touch it does sound happen sharply and instantly or does it creep in eerily? You could thing about using MIDI filtering like arpeggiators or chord triggers as well. Now it’s time to use the tools to express yourself 😉

Some more pictures from my students:

wp-1475591052669

img_1332

Advertisements