Introduction: Capacitive Switch for Arduino

This is a simple way to make and use capacitive switches with an Arduino or similar device such as a Raspberry Pi. These switches are touch sensitive, can be any shape or size, and can be mounted on any non-metallic base. This makes them perfect for the project I am working on which is a door handle that can detect a human hand. The Arduino code also has built-in debouncing which works pretty well, although I haven't tested this on any interrupt pins.

The code needed to detect a touch is very simple and could easily be ported to a small 8 pin PIC chip if your Arduino resources are getting scarce. This will reduce the number of digital input pins needed from 3 to 1.

There is, of course, a capacitive sensing page on the Arduino Playground, which uses a slightly different circuit. It can be found here for comparison.

P.S. This is my first instructable so any feedback is welcome.

Step 1: Capacitive Switch Principles

The principle of measuring a capacitor with an Arduino is very well explained here, so I won't go into too much detail (and possibly expose my ignorance). Basically, we turn an output pin on, then measure the amount of time it takes for an input pin to reach a certain voltage. The circuit has a resistor and a capacitor both of which will affect this time - the higher the resistance and capacitance are, the longer it will take for the input to reach the pre-set value.

In my circuit, however, the capacitor is you (or whoever is touching the switch). If you have a multimeter that can measure capacitance try putting two plain wires into the capacitor sockets. You will see that, when you touch both wires the meter will register a decent amount of capacitance. In my case about 60 nano Farads.

I have simplified things a bit as we do not need to know an exact value of the capacitance, we just need to be able to recognise the difference in charge time between a switch that is being touched and a switch that is not. So, I have used a digital input pin to measure the voltage and just counted the number of times a simple loop is executed instead of measuring the time.

Step 2: The Switch

The switch is just something metallic. It could even be a bit of bare wire on the breadboard. For my application I need a switch that will detect a persons hand without them having to press any buttons, so I have used a thin strip of steel shim about 0.05mm thick. The thin gauge of the material makes it very easy to cut with either scissors or a craft knife. To test the switch I glued it onto a thin sheet of plastic (a cut down credit card), then soldered a single-core wire to it for insertion into the breadboard.

I tried, at first, to use some self-adhesive aluminium foil, which would have been even easier to fashion into a useful shape, but I couldn't solder it to a lead. More experimentation needed.

You really can use anything (within reason) as a switch and I will be looking out for interesting ways to make this more versatile.

Step 3: The Circuit and Breadboard

You will need the following:

  • 1 1MΩ resistor.
  • 1 220Ω resistor.
  • A transistor of some sort. I used a BC547 NPN.
  • A breadboard and wires.
  • An Arduino of some sort.

I have also added an LED and a 220Ω resistor to test the switch. The LED is wired to a digital output pin on the Arduino, so it does not affect the circuit diagram.

Step 4: Arduino Code and Testing

Attached is the code for an Arduino (in .ino and .txt format). I have tested this with an Uno and it works pretty well. I have also written a library which uses direct port manipulation for speed.

The basic principle of the code is this:

  1. Turn the charge pin on - this will start to charge the input pin.
  2. Count how many empty loops the Arduino does until the input pin is high.
  3. Turn the charge pin off.
  4. Turn the discharge pin on - this will discharge the circuit through the 220Ω resistor.
  5. Turn the discharge pin off.

I have added some logic to debounce the switch. Basically it waits until the switch has been off for 100ms until it registers a switch. This seems to work pretty well.

You may need to tweak the value of the LOOP_LIMIT in this code. A faster processor or more efficient code (using direct port manipulation perhaps) will probably need a higher value.