Bare Conductive Beginner Article 8

Building a Touch Piano

Full project — a 12-note painted or copper-tape keyboard that outputs MIDI notes to any software instrument.

⏱ 30 min read project piano MIDI keyboard copper tape

The project

A 12-note touch piano, one octave (C4–B4), using all 12 electrodes. Touch a key → MIDI note on. Release → note off. Connect to GarageBand, Ableton, or any DAW and play a real software instrument.

What you need

  • Touch Board
  • A4 card (200gsm or heavier)
  • Copper tape, 6mm width (or Electric Paint)
  • Craft knife or scissors
  • Ruler + pencil
  • Micro-USB cable (to computer)
  • Headphones or speakers (DAW output)
  • Arduino IDE with MIDIUSB library installed

Step 1: Design the keyboard

A standard piano octave has 7 white keys and 5 black keys. On card, we’ll simplify to a single row of 12 keys:

┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ C │C# │ D │D# │ E │ F │F# │ G │G# │ A │A# │ B │
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │10 │11 │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
     (numbers = electrode E0–E11)

Draw 12 rectangles on card: each 3cm wide × 8cm tall, with a 2mm gap between keys. Add narrow traces running down to a connection strip at the bottom edge.

Step 2: Apply copper tape

Cut 12 rectangles of copper tape to fill each key area. Press firmly with a burnishing tool or fingernail. Then cut 12 narrow strips (3mm wide) as connecting traces from each key to the bottom edge.

At the bottom edge, add 12 small connection pads (1cm × 0.5cm). These are where you’ll clip crocodile cables.

Alternatively: Use Electric Paint to fill the key shapes and draw the traces in one continuous operation.

Step 3: Upload the MIDI sketch

#include <MPR121.h>
#include <Wire.h>
#include <MIDIUSB.h>

// Chromatic scale: C4 through B4
const byte NOTES[12] = { 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71 };
const byte CHANNEL   = 0;    // MIDI channel 1 (0-indexed)
const byte VELOCITY  = 100;

void noteOn(byte ch, byte note, byte vel) {
  MidiUSB.sendMIDI({ 0x09, byte(0x90 | ch), note, vel });
  MidiUSB.flush();
}

void noteOff(byte ch, byte note) {
  MidiUSB.sendMIDI({ 0x08, byte(0x80 | ch), note, 0 });
  MidiUSB.flush();
}

void setup() {
  Serial.begin(57600);
  if (!MPR121.begin(0x5C)) { Serial.println("MPR121 failed"); while(1); }
  MPR121.setInterruptPin(4);
  MPR121.setTouchThreshold(40);
  MPR121.setReleaseThreshold(20);
}

void loop() {
  if (MPR121.touchStatusChanged()) {
    MPR121.updateTouchData();
    for (int i = 0; i < 12; i++) {
      if (MPR121.isNewTouch(i))   noteOn(CHANNEL,  NOTES[i], VELOCITY);
      if (MPR121.isNewRelease(i)) noteOff(CHANNEL, NOTES[i]);
    }
  }
}

Step 4: Connect the keyboard

Connect 12 crocodile cables: Touch Board E0 ↔ C key pad, E1 ↔ C# pad, and so on through E11 ↔ B key pad.

The order matters — E0 must go to the key that should play C4, etc. If a key plays the wrong note, swap the cables.

Step 5: Connect to a DAW

GarageBand (macOS):

  1. Plug the Touch Board into your Mac
  2. Open GarageBand → New Project
  3. Add a Software Instrument track (Classic Electric Piano is a good start)
  4. In the track header, click the MIDI input icon → select Arduino Leonardo
  5. Touch keys — you should hear notes

Ableton Live:

  1. Preferences → MIDI → Enable “Arduino Leonardo” for both Track and Remote
  2. Create a MIDI track, set input to “Arduino Leonardo”
  3. Add an instrument (Simpler, Wavetable, etc.)

Improvements and variations

Velocity-sensitive keys: Read the MPR121’s filtered data — a faster capacitance change approximates harder touches:

// Rough velocity estimation from how fast the filtered value dropped
int vel = map(abs(MPR121.getFilteredData(i) - MPR121.getBaselineData(i)), 10, 100, 30, 127);
vel = constrain(vel, 30, 127);
noteOn(CHANNEL, NOTES[i], vel);

Sustain pedal: Dedicate one electrode as a sustain control. When held, notes sustain (don’t send note-off until both the key and the sustain electrode are released).

Octave shifting: Two electrodes shift the octave up and down:

int octaveOffset = 0;  // in semitones: -24, -12, 0, +12, +24

// Electrode 10 = octave down, electrode 11 = octave up
if (MPR121.isNewTouch(10)) octaveOffset = max(octaveOffset - 12, -24);
if (MPR121.isNewTouch(11)) octaveOffset = min(octaveOffset + 12, 24);

Key takeaways

  • All 12 electrodes map to one chromatic octave (C4–B4, MIDI 60–71)
  • Copper tape keys with narrow connecting traces is the most reliable physical design
  • The MIDIUSB library makes the Touch Board appear as a MIDI device in any DAW
  • Always send noteOff on release — notes left “stuck on” are audible and annoying
  • Velocity estimation, sustain, and octave shifting can be added with a few extra lines of code