Wednesday, 29 June 2011

Multiple touch sensitive inputs

In a previous post we talked about how to use a darlington transistor to create a touch sensitive switch.

For a device with multiple touch-sensitive inputs, it seems obvious that we repeat the single input for each pin we want to use as a touch sensor:

However, for each input our component count increases.
In the example above, we're using PORTB on the microcontroller, which has a built-in pull-up resistor on each input pin. If we need to use a different port, or want to use more than 8 inputs, we're going to have to add a pull-up resistor on each input pin. Also required - though not shown on the diagram above for the sake of simplicity - is a 1M pull-down resistor on the base pin of each darlington transistor.
So for each additional input, we're introducing three extra components.

It's worth noting, at this point, that for each touch sensitive input, we need two pads per input: one pad connected to the base pin on a transistor, and one pad connected to the 5V supply (the user touches and effectively creates a bridge between the 5V supply and the base input pin).

However, we can simplify our design massively by swapping the pads around:
instead of a fixed 5V supply and multiple darlington transistors, we can use a single transistor and multiple, variable 5V supplies. How to do this?
We turn each potential input pin to an OUTPUT and use this output to drive what would otherwise be a fixed 5V supply on the first pad. So each pair of pads that make up a touch-sensitive switch consist of an output pin (from the microcontroller) and a pin connected to the base of the darlington transistor.

a simple PIC/usb device with 16 touch sensitive inputs

Every touch contact would consist of a pair of pins/pads - one going to each of the numbered pads (PAD1, PAD2 etc) and the other a common input (COM_INPUT) so there would be a total of 16 COM_INPUT pads all tied together.

The pseudo-code would go something like this:
  • turn off all outputs
  • turn on output RA2 (PAD1)
  • has RA0 gone low? (yes=finger present across PAD1 + COM_INPUT)
  • turn off output RA2
  • allow time for input to return high
  • turn on output RA3 (PAD2)
  • has RA0 gone low? (yes=finger present across PAD2 + COM_INPUT)
  • turn off output RA2
  • allow time for input to return high
  • etc.

It depends on the type of darlington transistor you use (different transistors have different response/switching times) and the size of the pull-down resistor on the base pin, but in practice, with a 1M pull-down resistor, we found that 0.5ms (500us) worked well. Using this approach, we were able to poll all pins in under 10ms (0.5*16 = 8ms). At 100 times per second, this was more than responsive enough for our needs!