Purchase orders are available for educators - find out how × [hide]

empowering creative people

Capacitive Touch with Makey Makey

Source: core-electronics.com.au

The Makey Makey introduces the concept of using everday objects like fruit, lead pencil drawings, play dough etc. to interact with your computer via USB. The Makey Makey acts like a HID device over USB, which means that it behaves just like a keyboard or mouse, without any drivers or special software required; you plug it in and it just works. The standard firmware that the Makey Makey ships with allows you to use all the pins and pads as inputs using ‘Resistive Touch’. If you haven’t read our article on the Makey Makey’s standard resistive touch, check it out here.

What is Capacitive Touch

The draw back to using the built in resistive touch is that for most projects, the goal is to trigger a pin by touching it, this is the most intuitive way to interact with the Makey Makey, however in order to do this, you have to make sure you’re touching a lead connected to the ground pads at the same time in order to complete the circuit. What if you could re-program the Makey Makey to use each pin as a ‘Capacitive Touch’ pin? This allows us to trigger a pin just by touching it, and our body’s natural capacitance does the rest. For info on how capacitive touch works, check out this example at Arduino.cc.

To do this, we need to reprogram the Makey Makey, which we can easily do using the Arduino IDE. If you aren’t familiar with using Arduino, I suggest going to our tutorials section and reading some of the tutorials there, as we’ll be focusing just on the code we need to upload.

Configuring Arduino For Makey Makey

To get our Makey Makey working with Arduino, there’s a couple of things you’ll need to do first. This article over at SparkFun looks at downloading the Makey Makey libraries to get it to communicate with Arduino IDE.

The Code

Once you’ve got your Makey Makey showing up in boards inside Arduino as shown in the link above, it’s time to look at the code we’ll be using. The code comes from Eric Rosenbaum’s Github page, and we’ve found to work flawlessly with Makey Makey. We’ve made a couple of slight modifications to the key mapping, however you can modify that however you want. We’ve also adjusted the sensitivity threshold for the keystrokes as some of the lines were slightly over sensitive during testing when connected to items such as fruit or vegetables. This adjustment ensures smooth operation with most materials. Copy the code into your Arduino IDE, and upload it to your board.

#define NUM_INPUTS 18
// keys
// edit this array to change the keys pressed
int keys[NUM_INPUTS] = {
'a','s','d','f','g','m', // top of makey makey board (up, down, left, right, space, click)
'h','w','e','r','t', 'y', // left side of female header
'z','x','c','v','b','n' // right side of female header
};
// cap sense threshold for each pin
// this number is proportional to the capacitance on the pin that will count as a press
// it is units of a very small unit of time, in iterations through an unrolled loop
// higher values make it less sensitive (i.e. require larger capacitance)
int capThresholds[NUM_INPUTS] = {
2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2,
};
int pinNumbers[NUM_INPUTS] = {
12, 8, 13, 15, 7, 6,
5, 4, 3, 2, 1, 0,
23, 22, 21, 20, 19, 18
};
const int outputPin = 14; // pin D14, leftmost pin on the output header
boolean pressed[NUM_INPUTS];
void setup(){
Keyboard.begin();
for (int i=0; i<NUM_INPUTS; i++) {
pressed[i] = false;
}
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW);
}
void loop() {
for (int i=0; i<NUM_INPUTS; i++) { // for each pin
if (readCapacitivePin(pinNumbers[i])>capThresholds[i]){ // if we detect a touch on the pin
if (!pressed[i]) { // and if we're not already pressed
Keyboard.press(keys[i]); // send the key press
pressed[i] = true; // remember it was pressed
}
}
else { // if we don't a detect touch on the pin
if (pressed[i]) { // if this key was pressed before
Keyboard.release(keys[i]); // send the key release
pressed[i] = false; // remember we are not pressed
}
}
}
// OUTPUT
// output pin D14 goes high while any input is pressed
boolean anythingIsPressed = false;
for (int i=0; i<NUM_INPUTS; i++) {
if (pressed[i]) {
anythingIsPressed = true;
}
}
if (anythingIsPressed) {
digitalWrite(outputPin, HIGH);
}
else {
digitalWrite(outputPin, LOW);
}
}
// CapacitiveSensor tutorial from http://www.arduino.cc/playground/Code/CapacitiveSensor
// readCapacitivePin
// Input: Arduino pin number
// Output: A number, from 0 to 17 expressing
// how much capacitance is on the pin
// When you touch the pin, or whatever you have
// attached to it, the number will get higher
uint8_t readCapacitivePin(int pinToMeasure) {
// Variables used to translate from Arduino to AVR pin naming
volatile uint8_t* port;
volatile uint8_t* ddr;
volatile uint8_t* pin;
// Here we translate the input pin number from
// Arduino pin number to the AVR PORT, PIN, DDR,
// and which bit of those registers we care about.
byte bitmask;
port = portOutputRegister(digitalPinToPort(pinToMeasure));
ddr = portModeRegister(digitalPinToPort(pinToMeasure));
bitmask = digitalPinToBitMask(pinToMeasure);
pin = portInputRegister(digitalPinToPort(pinToMeasure));
// Discharge the pin first by setting it low and output
*port &= ~(bitmask);
*ddr |= bitmask;
delay(1);
// Make the pin an input with the internal pull-up on
*ddr &= ~(bitmask);
*port |= bitmask;
// Now see how long the pin to get pulled up. This manual unrolling of the loop
// decreases the number of hardware cycles between each read of the pin,
// thus increasing sensitivity.
uint8_t cycles = 17;
if (*pin & bitmask) {
cycles = 0;
}
else if (*pin & bitmask) {
cycles = 1;
}
else if (*pin & bitmask) {
cycles = 2;
}
else if (*pin & bitmask) {
cycles = 3;
}
else if (*pin & bitmask) {
cycles = 4;
}
else if (*pin & bitmask) {
cycles = 5;
}
else if (*pin & bitmask) {
cycles = 6;
}
else if (*pin & bitmask) {
cycles = 7;
}
else if (*pin & bitmask) {
cycles = 8;
}
else if (*pin & bitmask) {
cycles = 9;
}
else if (*pin & bitmask) {
cycles = 10;
}
else if (*pin & bitmask) {
cycles = 11;
}
else if (*pin & bitmask) {
cycles = 12;
}
else if (*pin & bitmask) {
cycles = 13;
}
else if (*pin & bitmask) {
cycles = 14;
}
else if (*pin & bitmask) {
cycles = 15;
}
else if (*pin & bitmask) {
cycles = 16;
}
// Discharge the pin again by setting it low and output
// It's important to leave the pins low if you want to
// be able to touch more than 1 sensor at a time - if
// the sensor is left pulled high, when you touch
// two sensors, your body will transfer the charge between
// sensors.
*port &= ~(bitmask);
*ddr |= bitmask;
return cycles;
}

Something that you may find, depending on how you’re folder structure is setup, is that you’ll need to copy the mouse.h and settings.h files into the Makey Makey folder in your Arduino sketches folder. If you’re getting compilation errors, try adding these in, we’ve attached them at the bottom of this tutorial for convenience. To adjust which keystrokes the inputs trigger, and the sensitivity, check out this section of the code:

Arduino Makey Makey code screenshot

Try it out, and see how amazing capacitive touch can be. Both resistive and capacitive touch have their place in projects, but for many applications, capacitive touch works in a much more intuitive, hand on way.

For great project ideas, and kit resources, check out our other Makey Makey tutorials.

Attachment: mouse-settings-h-files.zip

The Makey Makey introduces the concept of using everday objects like fruit, lead pencil drawings, play dough etc. to interact...