Touch Sensing on the Spark Core

The Arduino CapacitiveSensor library by Paul Stoffregen/Paul Badger provides a nice way to add touch sensing to projects. Unfortunately, there doesn’t seem to be a port to the Spark Core platform. This fact and the desire to better understand how the original library worked, lead to some effort to develop touch sensing on the Spark Core.

The capacitive sensing technique sends a LOW to HIGH transition from pin D3 through a large value resistor (~10Mohm) to sensing pin D2, as shown in the schematic below. A 1kohm series resistor was put in series with D2 and the connection to the 10Mohm resistor to increase protection against ESD. Stray or intentional capacitance (10pF shown in the schematic) forms an RC low-pass that slows down the rising edge of the transition. This causes a time delay for the signal at D2 to reach the voltage threshold to be detected as a HIGH, as shown in the timing diagram.

SparkCore_touch_sense_schem

SparkCore_touch_sense_bb

When the node connecting the resistors is touched, additional capacitive loading is introduced which further delays the arrival of the pulse. By comparing the arrival time against the baseline (untouched) arrival time, touching of the node can be detected. A baseline calibration is maintained by an exponential moving average of readings below the threshold of excessive delay (< 1.25 * Tbaseline). This accommodates slow drifts due to temperature or humidity changes.

TimingDiagram

Because capacitance will hold charge (and the impedance is high), it needs to be discharged prior to each reading of arrival time. This is accomplished by setting pin D2 to an output in a LOW state and then setting it back to a high impedance input. The code takes 32 readings and averages them to help filter noise. The Spark micros() function is used, along with attaching an interrupt to the sensing pin D2 to note when the threshold voltage was achieved. Micros() will periodically roll-over due to long data type limits, so these (infrequent) data points are ignored in the average calculation.

In further post-processing, the readings are debounced like a mechanical switch, in a function that reports ‘Touch Events’: tEVENT_NONE, tEVENT_TOUCH, tEVENT_RELEASE.

The Loop() then periodically polls for Touch Events (every POLL_TIME milliseconds). The Spark Core on-board LED D7 is lit when a tEVENT_TOUCH occurs and turned off when a tEVENT_RELEASE is sensed.

Code

The code is available at on Tangibit Studio’s Github repository.

Going Further

The Arduino version uses a pseudo-differential sensing technique to help reduce noise: readings are taken for both a LOW to HIGH and HIGH to LOW transition and then averaged. This could be incorporated.

Additional, this technique can get encapsulated in a library.

Have fun!

-JVS

Facebooktwittergoogle_plusredditpinterestlinkedinmail