Paint a MIDI Controller 2: More Controls

This page is an extension of the Paint a MIDI Controller Tutorial, here we will look at adding some further controls with the breadboard which can be used to extend the range of sounds, activate effects or whatever else. Now we are going to look at setting up some MIDI CC controls (Control Change) on the Teensy. Ableton Live is great software to work with alongside this project as you can quickly assign MIDI CC to almost anything. You can download a limited demo version of Ableton Live if you do not have the software, it will be sufficient for this tutorial.


  1. Materials
  2. Adding things to the Breadboard
  3. The New Code
  4. Testing it out
  5. Further Ideas

1. Materials

  • You should have your painting and connections still, look here this will not prevent you trying this tutorial though.
  • A Breadboard
  • A Teensy 3.2 + USB data lead
  • Hookup wires
  • A Potentiometer
  • A push button
  • Arduino IDE + Teensy Tools/Library on your computer
  • Ableton Live (Optional)

Again, this tutorial will assume a basic familiarity with programming an Arduino or Teensy, if you haven’t done it already please follow the instructions on the Arduino and Teensy websites for installing the software and uploading new code to the hardware.

2. Adding things to the Breadboard

Before you power on the Teensy, you should add the new components to the breadboard and wire them in to a circuit. We are going to add a potentiometer and a push button. We can think of a potentiometer as an analogue component and the push button as digital – this is because the potentiometer will give us a variable value, we can say between 0% and 100% whereas the push button will only have a state of 0 or 1 (on or off). As such, the potentiometer needs to be attached to an analogue pin on the Teensy, as these pins link to an internal ADC (analogue to digital converter) in order to get a variable reading. The Teensy also has a bunch of pins ready for digital signals – signals that will only ever be on or off. These are perfect for connecting LEDs and buttons.

Take a look at the diagram below:


If you haven’t already done so, you should begin by connecting the power and ground pins of the Teensy to the outer rows of your breadboard. The outer two rows on the breadboard run right across, so they are ideal for setting up a power bus. Note that on some longer breadboards, the rows have a break in the middle so you will need to make a wire jumper there if you want to extend your signal across the full length of the board. The two rows at either side of the board do not join together at any point, so you can use one row for a +V and the other for Ground. On the Teensy, +Vout (3.3V) is found three pins in from the top left (if oriented as in the picture) and Ground/GND is found on the bottom right pin. I will normally wire a power bus from the top rows to the bottom so I can access it easily, if you do this, be careful that you don’t accidentally short circuit the +3.3V to GND as this may break your Teensy – check your wiring carefully before you move on.

The button is nice and easy to connect as the Teensy has internal “pullup” resistors, this means if nothing is connected the digital pin will have a “high” state or “1”. We can flip the state of the pin by making a connection to GND, as a button is essentially just two bits of metal that make contact when pressed it is perfect for this job. To connect the button, take one wire from D3 (pin 3) on the Teensy to one leg of the button, and connect the opposite leg to ground. – A quick note, these pushbuttons have 4 legs, but really just have two pieces of metal inside, the switch mechanism goes across the narrower of the gaps between the four legs. If you try making a switch out of the wider gap, you will just get a short circuit.

The potentiometer works by creating a “potential difference” between the 3.3V rail and GND, connect the outer legs of the potentiometer to +3.3V and GND and the middle leg to A0 (pin 14) on the Teensy. A0 will measure the potential difference when we instruct it to and get an analogue reading that we can use. Note that if you wire the potentiometer outer legs the opposite way to diagram as above (left going to +3.3V and right going to GND) the reading will go the opposite way to what you might expect!

Once you have completed constructing the circuit shown, check over your connections and if you are happy, move on to the next step.

3. The New Code

Now you can plug in the Teensy and open up the Arduino IDE, below is the new code which includes everything from the previous tutorial, with the addition of new lines to instruct the Teensy to read from the pot and button. Copy the code into the Arduino IDE or download it here:

// Here is an extended version of the 7 note TouchMIDI patch.
// In this version we add two buttons and a potentiometer
// Now we can play with some MIDI CCs as well
// TouchPins used are 23, 22, 19, 18, 17, 16 and 15
// Pushbutton attached to pin 3 pulls to ground
// Potentiometer is read on pin A0

// label / initiate pins 

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

// create stored values

uint8_t ntouch = 7;
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
uint8_t button1state = 0;
int ccPot1 = 0;
int previousPot1 = -1;
elapsedMillis msec = 0;

void setup() {
  pinMode(3, INPUT_PULLUP);

void loop() {

  // Scan the Capacitive Touch pins

  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;   }   }   // Below is some code for adding a pot and button as MIDI CCs   if(msec >= 20) {
    msec = 0;

    ccPot1 = analogRead(A0); // check the position of the pot
    ccPot1 = map(ccPot1, 0, 1024, 0, 127); // scale the value to the MIDI range
    if(ccPot1 != previousPot1) {
      usbMIDI.sendControlChange(20, ccPot1, 1);
    //  Serial.print("cc20: ");
    //  Serial.println(ccPot1);
      previousPot1 = ccPot1;
  // CC20 is by standard a free slot but you can change it to anything you want
  // You can copy the above block of code to add more analogue inputs


  if (digitalRead(3) == LOW && !button1state == 0) {
    usbMIDI.sendControlChange(21, 127, 1);
    button1state = 1;
  else if(digitalRead(3) == HIGH && button1state == 1) {
    usbMIDI.sendControlChange(21, 0, 1);
    button1state = 0;
  // CC21 is by standard a free slot but you can change it to anything you want
  // You can copy the above block of code to add more analogue inputs

  // Serial.println(button1state);

  // Below just makes the Teensy ignore incoming MIDI messages

  while ( {



The new additions are mainly towards the end of the code, but take note that there are some new stored variables as well. You can add some more pots and buttons should you want until you have exhausted the analogue and digital pins on the Teensy. Just make sure each new control has a unique identity e.g ccPotand a unique CC number. Lets briefly unpack this a little further:

The pot we added has 3 stored values that are unique to it, “ccPot1” was created to store the number from the analogue reading, “previousPot1” is there to prevent a constant flood of MIDI messages i.e only send a new MIDI CC message if ccPot1 changes value. Notice the actual MIDI CC send message contains the CC address:

usbMIDI.sendControlChange(20, ccPot1, 1);

this translates to sendCC(address, value, channel). If you want to add more analogue controls, they will need unique stored values to call and you will probably want them to have a unique CC address as well.

One final note here, I have “commented out” several of the Serial.Print commands in the code by placing // in front of them – this tells the Arduino IDE to ignore what comes afterwards on that line of code. If you need to debug controls in the code, you can delete the // so they will start sending messages to the Serial Monitor.

4. Testing it Out

You can test that your new MIDI CC controls are working in your MIDI software of choice, but I would recommend that you try them out in Ableton Live because Live has a quick setup feature that allows you to assign MIDI CC to virtually anything in the software in seconds.

Load up Ableton Live and your favourite VST or equivalent synth. Go into Live > Preferences and choose the MIDI Sync tab. You should see your Teensy board listed at the bottom of the pop up window. Make sure for “Input”, Track and Remote are set to “On”.


First test that your touch sensors are functioning as intended, go back to the Arduino IDE and calibrate them if you need to.

On a MIDI channel, load a synth – this could be a stock Ableton synth if you have one, or a VST. I like to use Madrona Labs Aalto (you can get a free demo here).

(follow this step if you used a VST) In Ableton on the MIDI channel you added your VST to, look at the utility box click on the arrow next to the power button – this will reveal the “Configure” option:


When you click on “Configure”, the GUI for your softsynth should pop up – now when you click any control it will be added as a parameter in your utility box – try clicking something like filter cut-off if you have it, you should see something like this:


Now, look to the top right hand corner of the main view in Live and locate the “MIDI” button – this will put the software into MIDI Assign mode:


Notice that much of the interface has changed to a shaded colour – anything shaded indicates something that you can assign a MIDI CC to. Click on the new control for Filter Cutoff in the utility box (or any other control on your synth) and then turn the potentiometer on your breadboard – you should see Live respond to show that it has recognised a new CC!

Turn MIDI assign mode off and try playing some sounds with the touch controls whilst turning the potentiometer, you should hear the filter sweep!

Go back into MIDI assign mode, and notice in the box on the left of the screen the new MIDI CC link has appeared. You can set maximum and minimum values here which you might find useful.

Let’s try something slightly different for our button:

Go into the MIDI Effects tab in Live and add a “Chord” filter to the same MIDI channel as your synth, it needs to be to the left of the synth in the device chain.


Go into MIDI assign mode and click on the Power button for the Chord filter, then press the button on your breadboard:


Now exit MIDI assign mode – now, when you push the button, Chord mode will become active, and when you depress it will become deactive – pretty neat right?

Take some time now to experiment with your new controls in Live.

5. Further Ideas

Perhaps you would prefer to have your push button latch on when pressed, and then off on the next press as opposed to being momentary. You can achieve this with some code like this:

if (digitalRead(3) == LOW && button1state == 0) {
    usbMIDI.sendControlChange(21, 127, 1);
    button1state = 1;
  else if(digitalRead(3) == HIGH && button1state == 1) {
    button1state = 2;
  else if(digitalRead(3) == LOW && button1state == 2) {
    usbMIDI.sendControlChange(21, 0, 1);
    button1state = 3;
  else if(digitalRead(3) == HIGH && button1state == 3)
    button1state = 0;

A little clunky looking, but what this effectively does is use “button1state” as a flag that blocks certain things happening – like the button chaotically flipping on and off if it is held down. Press the button once and the “On” CC message is sent, release the button and button1state changes so that the same CC message cannot be sent again. Next time the button is pressed, the “Off” CC message will be sent, then when the button is depressed the sequence is reset.

You should now have a think about the tools you have experimented with in the last two tutorials and consider what you might like to do with them in your own work – maybe you would like to run a workshop yourself and have your audience paint the controller, maybe you would like to use this project as part of a live music performance with your band – or maybe you would like to make an interactive painting as part of an installation, there are many possibilities.

Once dry, the conductive paint should work the same way even if partially covered up. You could think about making a more elaborate painting where you start with a layer of conductive paint, and then paint over it with a variety of colours just leaving some conductive points exposed – you may have also noticed that the capacitive sensing would still give a small reading even through an insulator – so there is potential with some fine tweaking to get the same reactions without having to directly touch a conductive surface.

Pots and buttons are great – but there are many other sensors out there that detect temperature, light levels, motion and more – and as mentioned somewhere above, a button is effectively just two bits of metal that can make contact – consider making your own buttons out of bare conductive material. One of the great strengths of a platform like Teensy is that you can use it as a hub or brain that can translate a reading from a given sensor into data that is directly useable for something else (in our case, MIDI) – now is a great opportunity to do some research on the different types of sensors that are out there, and go on to make the most exotic MIDI controller ever!

I hope you have enjoyed these tutorials on Painting MIDI – if you have any questions, comments or issues, please use the comments section on this page to keep the discussion open.