Arduino Capacitive Sensor: How to make Touch Sensing inputs with No
External Components!... Whaaaatttt?... How is this Arcane Magic
performed? Tell me the incantation for ultimate 'Touch Sensing' Power.
Arduino Capacitive Sensor: Here you can find out how to use a single pin and no external hardware to create a button that operates through wood, plastic or glass.
For some designs you need a push button that is hidden and this is
the ideal method to do it - capacitive touch sensing. The actual
technique is really measuring capacitance by measuring the charging time
of the external capacitance.
Standard Arduino Capacitive Sensor Method
The usual method for detecting a capacitive touch input is to use two
pins with a high value resistor between them. In this setup the
capacitance at the sensor pin is measured by manipulating two pins. The CapacitiveSensor library is used for this (two-pin) method.
One pin is the controller.
One pin is the sensor.
When the controller pin is set high the capacitance at the sensor is
charged through the resistor. When the input voltage at the sensor
reaches the input high threshold voltage (Vih) it indicates a valid
input (logic level high).
The total capacitance at the sensor and the resistance from capacitor to input determines the rise time
(charging rate) and when you add more capacitance, by
placing your finger near the sensor, capacitance increases (slowing the
charging rate). This is because capacitances in parallel add together.
Measuring the rise time allows you to detect the presence of a finger!
Note: You can use the same control pin for multiple capacitive sensors when you use the CapacitiveSensor library.
The CapacitiveSensor library documentation talks about changing the value of the resistance as follows:
1 MOhm absolute touch
10 MOhm 4-6 inch detection
40 MOhm 12-24 inch detection
You can choose these parameters based on your design. Using the
single pin ADC method below you can adjust the sensitivity by changing
the adc threshold measured.
Tip: You can even use just a length of wire as the detector!
ADC Arduino Capacitive Sensor
The advantage of this ADC Arduino capacitive sensor method is that it only needs a single analogue pin per input.
So this method is most appropriate for pin constrained designs such
as an ATtiny85 (8 pins - 6 useable) whereas the CapacitiveSensor library
is useful if you have many inputs because you have greater control over
the sensing ability when selecting external components.
There are three elements required by the method:
A sample and hold capacitor with a known value (14pF).
A controllable pull-up.
The ability to ground the ADC sample and hold capacitor.
How the ADC Capacitive Sensor Works
Arduino ADC and pin Block diagram
If you draw out the above elements as a single diagram then you get:
Attach a small copper plate to an analogue input pin (with series
resistor for ESD protection -not shown), if you just want to see what
happens just use a small length of wire e.g. 10cm - the plate increases
the capacitance and allows a finger to have a bigger effect. When an
object (or finger) is
brought near the plate its capacitance increases.
The idea is to compare the external capacitance to the internal
sample and hold capacitance - if they are similar then the ADC will read
2.5V and become lower as C increases.
Charge External and ground internal cap
To do that the external capacitor is charged to 5V while the internal capacitor is discharged to ground:
Remove charge and connect pin to ADC
Now disconnect the pullup and connect the capacitors then charge
distributes according to the relative capacitance values with the
ultimate capacitance determined by adding capacitors in parallel.
Now Make an ADC reading to detect the capacitance change.
Library for the Capacitive Touch Sensor : ADCTouch
This source code for the capacitive touch sensor is from the ADCTouch library showing the core operational code.
Later code has been updated to accommodate ATTiny devices, as the
register values used different, so you should use the latest version but
the code below is for the Arduino Uno and is easier to read (from github
ADCTouch.cpp - Library for Capacittive touch sensors using only one ADC PIN
Created by martin2250, April 23, 2014.
Released into the public domain.
while(!(ADCSRA&(1<<ADIF)));//wait for conversion to finish
ADCSRA|=(1<<ADIF);//reset the flag
The latest code has a few more comments but the basic operation is this:
Set the input pull-up active to charge the external capacitor.
Set the Mux to select ground as input to discharge the S&H capacitor.
Perform a conversion (not sure this is strictly necessary).
Release the pull-up - set inactive.
Perform an ADC read
Repeat from step 1 a few times: 'samples' times, then divide the
result by the number of 'samples' taken to get the average value.
Example Test code
Using hardware: Arduino Uno.
The following code for the Arduino capacitive sensor is an example
that shows reading of two capacitive touch sensor inputs attached to
analogue input pins A0 and A1. Note that with the standard sensing
method you would need three pins to do this plus two resistors and
possibly two more capacitors.
All you need here is a wire and a copper pad (I used a piezo disc
using only the wire connected to the copper pad). All you do is place
these connections in A0 and A1 pins on an Arduino Uno.
The copper disc was attached to A0 while the wire was attached to A1. You can see the output results below the sketch.
intref0,ref1;//reference values to remove offset
// No pins to setup, pins can still be used regularly, although it will affect readings
ref0=ADCTouch.read(A0,500);//create reference values to
ref1=ADCTouch.read(A1,500);//account for the capacitance of the pad
intvalue0=ADCTouch.read(A0);//no second parameter
intvalue1=ADCTouch.read(A1);// --> 100 samples
Serial.print(value0>40);//send (boolean) pressed or not pressed
Serial.print("\t");//use if(value > threshold) to get the state of a button
Serial.print(value0);//send actual readingc