Can I connect capacitive touch sensors to Pin 0 or 1?

Hello All,
In searching for the best touch sensor I was advised to look into a capacitive sensor:
http://arduino.cc/playground/Code/CapacitiveSensor

I was uncertain because in another post I read that it is too sensitive, reacting to proximity.
Well, for me it works marvelously, much better that even momentary push switches.

Problem is that I cannot use Pin 0 or 1, the function returns 0 no matter what (while it returns 1 for pin 2 to 13 when non touched and 4 when touched).

The reference: Arduino Reference - Arduino Reference mentions that You should note, however, that pins 0 & 1 are used for serial communications for programming and debugging the Arduino, so changing these pins should usually be avoided unless needed for serial input or output functions. Be aware that this can interfere with program download or debugging.

I do need them as I have 14 touch sensors to read. I could live with 13 but I would still need port 0 or 1.

Is there a way around this limitation?

Thanks

This is the code I am using:

/* Uses the capacitive pin function
to read capacitance on push buttons
Connected to Pins 0 to 13
Prints the values on the serial monitor.
*/

uint8_t PinStatus;
uint8_t cycles ;
byte i;

void setup ()
{
Serial.begin(57600);
}

void loop ()
{
for (i=0;i<=13;i++) {
PinStatus= readCapacitivePin (i) ;
Serial.print (PinStatus) ;
Serial.print(" ");
}
Serial.println();

}

// 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

//#include "pins_arduino.h" // Arduino pre-1.0 needs this

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;
}

Hi!

If u need to do Serial communication, u cant use pin 0 or pin 1.

But u can use digital pins 2 to 13 (=12 pins) and analog pins 0 to 5 (=6 pins numbered digital pins 14 to 19)... :slight_smile:

Bye

There is no way round this restriction because these pins are connected to the USB to serial chip. Therefore they do not have the high impedance needed to make a touch sensor.

However you can use the analogue pins as digital ones you know.

RIDDICK:
But u can use digital pins 2 to 13 (=12 pins) and analog pins 0 to 5 (=6 pins numbered digital pins 14 to 19)... :slight_smile:

Grumpy_Mike:
However you can use the analogue pins as digital ones you know.

Waitaminute, I know how to read an analog pin and decide that if the result is, say, 600 or higher I consider it a HIGH.
But are you saying that I can simply decide that A0 is digital pin 14 and use the function:

 PinStatus= readCapacitivePin (14) ;

from the code above, like I would do for any digital pin 2-13?

That would solve ALL my problems (or at least those related to this project. There is still the issue of the meaning of life and how to pay rent, but that's another story :slight_smile: )

yup - digitalRead(14) works...
analog pin 0 is also a digital pin...

Thank!

Another quick question:

The refernce says it's better not to use Pin 13 for input with the internal pull up set.
Would the same caveat apply for the capacitve sensor?

code-wise is slighly easier to use 13 as well and put any LED on unused analog pins.

Pin 13 has an led and resistor on it so that spoilers the high impedance input you need.

Got it. Leave 13 for LED :slight_smile:

Thot:

RIDDICK:
But u can use digital pins 2 to 13 (=12 pins) and analog pins 0 to 5 (=6 pins numbered digital pins 14 to 19)... :slight_smile:

Grumpy_Mike:
However you can use the analogue pins as digital ones you know.

Waitaminute, I know how to read an analog pin and decide that if the result is, say, 600 or higher I consider it a HIGH.
But are you saying that I can simply decide that A0 is digital pin 14 and use the function:

 PinStatus= readCapacitivePin (14) ;

from the code above, like I would do for any digital pin 2-13?

That would solve ALL my problems (or at least those related to this project. There is still the issue of the meaning of life and how to pay rent, but that's another story :slight_smile: )

Not only that you can use the names A0, A1 etc and they will work both in analogRead() and digitalRead() - saves having to remember that analog 0 is digital 14. On the Arduino MEGA analog 0 is not digital 14 anyway, so the A0/A1 names are more portable.