Capacitive Sensors Interfaced to Arduino

Posted by Jess Brouse on April 29th, 2009

capsense

Capacitive touch sensors are used extensively in consumer electronic devices like iphones, laptop touchpads and buttons, but they can also be used as localized proximity sensors, or turning non-conductive materials like glass into physical interfaces for all kinds of electronics projects. Here are a couple of sensors I’ve been experimenting with lately:

::QT301 (see example) outputs a PWM signal based on capacitive touch/proximity sensing.

QT113 for basic touch sensing applications (acts like an on/off switch). Here’s Tom Igoe’s arduino/QT113 tutorial

::Capacitive Touch Sensor Breakout Board from SparkFun electronics which is based on the AD7746 (see datasheet here for more technical details).

The AD7746 uses I2C (two wire) serial to send and receive information with microcontrollers like the arduino. Since there is little documentation on using this device that is easy to understand I figured I’d donate some sample arduino code (in the name of science!). To communicate over I2C the arduino needs to access the Wire library. The Wire library uses analog pin 4 for sending and receiving data (SDA), and analog pin 5 as the clock (SCL). These pins have internal pull-up resistors on atmega168 and atmega328 (Diecimila, and Duemilanove) so you may ignore these resistors in the datasheet diagrams. If you are using a Boarduino which has no 3.3v power output, you’ll need to use a voltage regulator like the L1085-33 to bump 5v down to the 3.3v the sensor wants to see. Here’s the code- the setup function calibrates the sensor, and the loop function keeps checking its value and spitting it out via Serial.

#include <Wire.h>
 
#define SLAVEWRT 0x48 // address of device during write cycle
#define SLAVERD  0x48 // address of device during read cycle
 
int mySensor = 0; // where capacitive sensor data is kept
 
void setup()
{
 
  Wire.begin(); // sets up i2c for operation
  Serial.begin(9600); // set up baud rate for serial
 
  Wire.beginTransmission(SLAVEWRT); // start i2c cycle
  Wire.send(0xBF); // reset the device
  Wire.endTransmission(); // ends i2c cycle
 
  Wire.beginTransmission(SLAVEWRT); // begin write cycle
  Wire.send(0x0A); // point to config register
  Wire.send(0x01 | (7 << 3)); // calib. mode, slow sample
  Wire.endTransmission(); // ends cycle
 
  Wire.beginTransmission(SLAVEWRT); // begin write cycle
  Wire.send(0x07); // cap setup reg
  Wire.send(0x80); // cap enabled
  Wire.endTransmission(); // ends cycle
 
  Wire.beginTransmission(SLAVEWRT); // begin write cycle
  Wire.send(0x09); //  EXC register
  Wire.send(0x08); // EXC source A
  Wire.endTransmission(); // ends cycle
 
  Wire.beginTransmission(SLAVEWRT); // begin write cycle
  Wire.send(0x0B); // CAPDAC A reg
  Wire.send(0x00 | 39); // capdac a is on, offset about 1.2pF
  Wire.endTransmission(); // ends cycle
 
  Wire.beginTransmission(SLAVEWRT); // begin write cycle
  Wire.send(0x0A); // configuration register
  Wire.send(0x01 | (7 << 3)); // continuous mode
  Wire.endTransmission(); // ends cycle
 
}
 
void loop() // main program begins
{
 
    Wire.beginTransmission(SLAVERD); // begin read cycle
    Wire.send(0x00); //pointer to first cap data register
    Wire.endTransmission(); // end cycle
 
    Wire.requestFrom(SLAVERD,4); // reads 4 bytes
 
    byte data[2];
    int i = 0;
      while(Wire.available())
     {
	char c = Wire.receive();
        data[i] = c;
        i++;
     }
 
   mySensor = -((data[0]<<16)+(data[1]<<8)+data[2]) / 12;
   Serial.println(mySensor);
 
  delay(50);
}
Share:
  • Digg
  • Technorati
  • del.icio.us
  • Facebook
  • Google Bookmarks

Tags: , , , , ,

6 Responses to “Capacitive Sensors Interfaced to Arduino”

  1. steve blair Says:

    Right on! I’ve been looking at the QT113 for turning backlit acrylic panels into touch sensitive buttons. While searching for more info though, I found this page http://tiny.cc/BdYRa which suggests using the QT100A as a newer replacement for the QT113. So, I’ve ordered some and now I just have to wait anxiously for them to come in the mail before I can start playing with them.

  2. Jess Brouse Says:

    Cool, let me know how it goes. Have fun.

  3. Treizeur Says:

    Damn ! I have problems to make it work properly (AD7746 and Arduino Duemilanove)… What kind of value does it returns ? I have a value of approximately 420, which goes up near 500 when I put a finger so close to the sensor. If I touch it the value is 0. Is it normal values ?
    There are a lot of things that I don’t really understand (for example, if I change parts of the code nothing happens !?)…
    If you have time to spend with me it would be great help ! (I understand if not, however ! )

  4. Daniel Says:

    Lovely well explained code Jess, I thank you kindly and will credit ifi use.
    Having a few problems getting Channel 2 of the sensor activated and set up. Any advice at all!!! have looked at the data sheet and see that what I need to do it is just the hex that I’m stuck with!!!!!
    Thanks again
    Daniel

  5. Jess Brouse Says:

    I haven’t used two channels, can’t help you there sorry.

    Treizeur:
    Expect numbers to vary greatly depending on positioning, and if it is sensing through a material like glass, plastic, air etc. Getting sensitivity right is a chronic issue with capacitive sensors as whenever the physical environment they’re in changes, they produce different values. So basically get a sense of the range of numbers in your situation and use a bit of math to make those numbers meaningful (say 0-255 if you want to control a PWM pin with it)

  6. Treizeur Says:

    Thanks your answer helps me ! In fact I have no idea how capacitance works, I’m trying to build something that detects pieces of adhesives ribbon onto textile ribbons. I’ve seen existing devices that uses this technology, I hope the AD7746 can accomplish that. I will try to build a kind of fork as I’ve seen to let the ribbon pass through, perhaps the values will be less messy.
    Thanks again.

Leave a Reply

You must be logged in to post a comment.