Sensor key demonstrates how the Arduino can sense a touch sensitive key through digital pins 8 to 13. It requires no special hardware, nevertheless a capacitor of 1nF is recommended in line with the pin to decouple 50Hz noises.
Connect a wire or some metallic plate to a digital pin (digital 8-13).

The program measures the capacity (time to charge) of the given port. If untouched getcap returns a low value e.g. "1" when touched it rises to about 5. By adding some comparision with a threshold you can make it a boolean key input.
the pin is toggled to output mode to discharge the port capacity, which would shortcut any chip/transistor which might drive the port high.
Mario Becker, Fraunhofer IGD, 2007 http://www.igd.fhg.de/igd-a4
// sensor key
#define KEYPORT PORTB
#define KEYDDR DDRB
#define KEYPIN PINB
#define KEY0 PB0 // capture input - digital 8
#define KEY1 PB1 // capture input - digital 9
#define KEY2 PB2 // capture input - digital 10
#define KEY3 PB3 // capture input - digital 11
#define KEY4 PB4 // capture input - digital 12
#define KEY5 PB5 // capture input - digital 13
void setup()
{
Serial.begin(9600); // connect to the serial port
}
// returns capacity on one input pin
// pin must be the bitmask for the pin e.g. (1<<PB0)
char getcap(char pin)
{
char i = 0;
KEYDDR &= ~pin; // input
KEYPORT |= pin; // pullup on
for(i = 0; i < 16; i++)
if( (KEYPIN & pin) ) break;
KEYPORT &= ~pin; // low level
KEYDDR |= pin; // discharge
return i;
}
void loop ()
{
char capval[6];
char pinval[6] = {1<<KEY0,1<<KEY1,1<<KEY2,1<<KEY3,1<<KEY4,1<<KEY5};
delay(1000);
for(char i = 0; i < 6; i++)
{
capval[i] = getcap(pinval[i]);
Serial.print("digital ");
Serial.print(i+8, DEC);
Serial.print(": ");
Serial.println(capval[i], DEC);
}
Serial.println("");
}
For some reason using shorthand such as "PB4" doesn't work when compiling for the newer Duemilanoves, so I've rewritten this code to account for this and tested it on my own.
Great work by Mario, thanks for this simple code for such a potentially useful sensor!
/*Capacitative Sensing Code for ATMega328 Arduinos*/
void setup()
{
Serial.begin(9600); // connect to the serial port
}
void loop ()
{
char capval[6];
char pinval[6] = {1<<PINB0,1<<PINB1,1<<PINB2,1<<PINB3,1<<PINB4,1<<PINB5};
delay(1000);
for(char i = 0; i < 6; i++)
{
capval[i] = getcap(pinval[i]);
Serial.print("digital ");
Serial.print(i+8, DEC);
Serial.print(": ");
Serial.println(capval[i], DEC);
}
Serial.println("");
}
// returns capacity on one input pin
// pin must be the bitmask for the pin e.g. (1<<PB0)
char getcap(char pin)
{
char i = 0;
DDRB &= ~pin; // input
PORTB |= pin; // pullup on
for(i = 0; i < 16; i++)
if( (PINB & pin) ) break;
PORTB &= ~pin; // low level
DDRB |= pin; // discharge
return i;
}