Daily Archive for July 14th, 2012

Capacitive Touch Testing with bcard

While I think a little bit more about why I can’t seem to get V-USB to work with hdctrlr, I’ve gone back to working on my PCB business card, bcard.

The ATTiny10 is basically impossible to do meaningful development on, so I decided to make a breakout version of my business cards that use an Atmega168 instead. That way, I can get data over serial, etc. to develop a decent sketch of a program that I will then implement in assembly on the Attiny. Of course, when I get to that point, I could always disassemble the Atmega program and use that as a template for the Attiny program, but I’m far too much of a masochist to do something like that; I’ll be rewriting it from scratch in order to get as much power savings as physically possible.

Anyways, here’s a quick photo of the capacitive breakout board that I made:

The basic idea of this style of capacitive touch sensing is that there is a parallel RC circuit like this:

First, I set the CTRL pin to be an output so that it can charge up the capacitor (which is the interlocking bars in the image above). Then, I change CTRL to be an input pin, so that it has infinite impedance. This means that the circuit just looks like a resistor and capacitor in parallel, connected to ground. So, the capacitor will discharge through the resistor while the input pin monitors the voltage. We don’t even need CTRL to be an ADC; all it has to do is look for when the input goes from 1 to 0.

So what happens when we put our finger on the pad? Well, this is where it gets fun. When this happens, you’re changing the dielectric constant of the capacitor on the board, increasing the time constant (i.e. increasing the time it takes to discharge). This looks somewhat similar to a design by Michael Ciuffo, a friend of mine, but his sensor is being actuated on the change in resistance when you put your finger on a sensor whereas I’m looking at the change in capacitance. So, with his design, when you put your finger on the pad, the time constant decreases, whereas with mine, the time constant increases.

Screw it, let’s do it in pictures. I like pictures.  (In this example, I model the change in the dielectric constant as an added capacitor).

And how does it look in real life? Well here’s two photos of my scope measuring the CTRL pin for a sensor. The first shows the normal waveform (I charge up the cap with the CTRL pin and wait a while, then let it fall) and the second shows what happens when you put your finger on the sensor.

I based this design on inspiration from this site.

So, how do you get useful information with a microcontroller? It’s really just a few lines of code. Let’s say that you’re using PB0 as your CTRL pin.

[cc lang=”c”]
uint8_t counter = 0; // we’ll count how long it takes the pin to drop back to 0 here

DDRB |= (1<<PB0); // set CTRL to drive a voltage
PORTB |= (1<<PB0); // apply logic 1 to charge the cap
_delay_ms(PIN_ON_DELAY); // charge for a little while (this can be really small)
DDRB &= ~(1<<PB0); // set CTRL to input mode
PORTB &= ~(1<<PB0); // get rid of driving voltage

while ( PINB&(1<<PB0) && counter <= 255 ) {
// each time, we check to see if PB0 has gone back down to logic 0. If it hasn’t, then we increment counter (up until the point where it could overflow)

That’s it! Drive the pins, stop driving them, and see how long it takes for them to change back.

So here’s a video of some live plotting of data I took (see video description for the moment on details).

In this example, I let counter be a 16-bit value instead of just an 8-bit one so that I would have more resolution, but in practice, just using an 8-bit counter is sufficient.

To measure a press versus a not-press, I start by establishing a baseline — basically when the micro first starts up, it takes a bunch of samples (I assume that the user doesn’t start by pressing the pads). It then starts performing readings. If the reading is significantly off baseline, then it registers it as a press. If it’s not significantly off, then it updates the baseline by averaging in the new value. This allows the sensor to react to minor changes in the environment around it.

With respect to bcard, I actually have two sensors (you can see that there are two sensing pins). So, I wrote a short algorithm that looks for a press on the first one and then a press on the second one to indicate that someone swiped their finger over the pads. I should have a full code implementation done fairly soon.

I really have stopped liking my current bcard design so I’m probably going to do a complete redesign and rerouting of it soon. I really want it to look aesthetically pleasing and I’m definitely not there yet. I think I’m going to make the swipey thing vertical instead of horizontal. I may also adjust the placement of the LEDs.