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:

  1. A sample and hold capacitor with a known value (14pF).
  2. A controllable pull-up.
  3. 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:


 adc touch block diagram operation capacitive touch using adc

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:

initialise capacitive touch using adc

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.

internal cap connect operation capacitive touch using adc

Now Make an ADC reading to detect the capacitance change.

Arduino Library

Library for the Capacitive Touch Sensor : ADCTouch

Download from :https://github.com/martin2250/ADCTouch and unzip to the libraries folder (usually c:/users//Documents/Arduino/libraries).

Or use the library manager, searching for ADCTouch.

Library installation details are here.

ADCTouch Souce Code

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 2016).

/*
  ADCTouch.cpp - Library for Capacittive touch sensors using only one ADC PIN
  Created by martin2250, April 23, 2014.
  Released into the public domain.
*/
#include "Arduino.h"
#include "ADCTouch.h"

int ADCTouchClass::read(byte ADCChannel, int samples)
{
	long _value = 0;
	for(int _counter = 0; _counter < samples; _counter ++)
	{
		pinMode(ADCChannel, INPUT_PULLUP);

		ADMUX |=   0b11111;
		ADCSRA |= (1<<ADSC); //start conversion
		while(!(ADCSRA & (1<<ADIF))); //wait for conversion to finish
		ADCSRA |= (1<<ADIF); //reset the flag

		pinMode(ADCChannel, INPUT);
		_value += analogRead(ADCChannel);
	}
	return _value / samples;
}

The latest code has a few more comments but the basic operation is this:

  1. Set the input pull-up active to charge the external capacitor.
  2. Set the Mux to select ground as input to discharge the S&H capacitor.
  3. Perform a conversion (not sure this is strictly necessary).
  4. Release the pull-up - set inactive.
  5. Perform an ADC read
  6. 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.

#include <ADCTouch.h>

int ref0, ref1;     //reference values to remove offset

void setup()
{
    // No pins to setup, pins can still be used regularly, although it will affect readings

    Serial.begin(9600);

    ref0 = ADCTouch.read(A0, 500);    //create reference values to
    ref1 = ADCTouch.read(A1, 500);    //account for the capacitance of the pad
}

void loop()
{
    int value0 = ADCTouch.read(A0);   //no second parameter
    int value1 = ADCTouch.read(A1);   //   --> 100 samples

    value0 -= ref0;       //remove offset
    value1 -= ref1;

    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(value1 > 40);
    Serial.print("\t\t");

    Serial.print(value0);             //send actual readingc
    Serial.print("\t");

    Serial.println(value1);
    delay(100);
}

ADCTouchClass ADCTouch;

Example code Results


0	0		1	2
0	0		1	1
0	0		0	2
0	0		1	0
0	0		1	0
0	0		1	1
0	0		1	3
0	0		0	1
0	0		1	0
0	0		1	1
0	0		0	2
0	0		2	1
0	0		5	1
1	0		293	8
1	0		338	8
1	0		382	2
1	0		355	3
0	0		1	0
0	0		1	0
0	0		1	2
0	0		0	2
0	0		1	4
0	0		1	6
0	0		0	10
0	0		1	15
0	1		2	70
0	1		1	78
0	1		2	77
0	1		2	79
0	1		2	84
0	1		2	70
0	0		1	5
0	0		1	2
0	0		1	0


Comments

Have your say about what you just read! Leave me a comment in the box below.

Don’t see the comments box? Log in to your Facebook account, give Facebook consent, then return to this page and refresh it.




Privacy Policy | Contact | About Me

Site Map | Terms of Use