Touch Sensing

Since the mbed platform doesn't come with any buttons or sensors, it is difficult to create meaningful examples or experiments that use human input. Adding a physical button would be easy to do, but we wondered if we could do more with less. This page describes how one would use a small capacitor in conjunction with an ADC (AnalogIn) and a GPIO (DigitalIn) to create a touch sensitive button. The idea was adapted from a Microchip Appnote - Capacitive touch using only an ADC.

You need - a jumper cable and a small value capacitor (100pF works fine). Connect the jumper cable across pins P19 and P20 of the mbed. Connect the capacitor between P18 and P19 of the mbed as shown.

Touch Capacitor Connections

 

Principle: the touch sensitive "button" works by charging up the capacitor to the supply voltage and then testing the voltage using an ADC pin. To trigger the button, one must touch both leads of the capacitor. The pseudo-code below explains the process.

  1. Assign P20 as an AnalogIn, P19 as a DigitalIn and P18 as a DigitalOut (for conveniently located ground)
  2. Pull up P19 to charge capacitor to 3.3V
  3. Float P19 to retain charge on capacitor
  4. Immediately sense voltage on P20.
  5. If the user has touched both leads, the capacitor would have discharged through skin resistance to ground.
  6. If not, the charge on the capacitor will remain pretty much the same.

 

Breadboard picture

 

TouchSense

 

Other thoughts:

The original aim of this exercise was to perform touch sensing without any external capacitor. As the Microchip AppNote mentions, you should be able to store and share charge on the  sample-and-hold capacitor internal to the ADC. The datasheet mentions that the maximum capacitance on the ADC inputs is 15pF. However, the ADC pins are all multiplexed with digital functionality as well. Does selecting the ADC functionality through ADxCR turn off the digital part and expose the sample and hold capacitor ? Or is the sample and hold capacitor only exposed when conversion is started ?

 


3 comments

24 Oct 2010 . Edited: 24 Oct 2010

We can reuse the precharging port as analog input, by allocating and deallocating c++ classes dynamically.

25 Oct 2010

user Tianji Wu wrote:

We can reuse the precharging port as analog input, by allocating and deallocating c++ classes dynamically.

I haven't tried it, but it seems possible. Does it work reliably ? If so, could you publish/post the code here.

Thanks,

Zainul.

26 Oct 2010

user Zainul Charbiwala wrote:

 

user Tianji Wu wrote:

We can reuse the precharging port as analog input, by allocating and deallocating c++ classes dynamically.

I haven't tried it, but it seems possible. Does it work reliably ? If so, could you publish/post the code here.

Thanks,

Zainul.

DigitalInOut * precharge;
AnalogIn * sense;
precharge = new DigitalInOut(p19);
precharge->output();
(*precharge) = 1;
precharge->input();
precharge->mode(PullNone);
delete precharge;
wait_ms(10);
sense = new AnalogIn(p19);
float value = *sense;
delete sense;

It is reliable. However, I would suggest to put a 10M or some kind of large resistor between p19 and ground. Otherwise, the pin is completely floating when sampling. If people touch only this pin but not the other ground pin, the sampled signal is a mass.

You need to log in to post a comment