CapacitiveSensor: touch sensing with foil and a resistor
CapacitiveSensor, by Paul Badger, turns any piece of metal (foil, a coin, a fruit, a wire under paper) into a touch sensor with no sensor chip at all. You connect a high-value resistor between two pins, a send pin and a receive pin, and the metal to the receive pin.
Built in on Mokxi: #include <CapacitiveSensor.h> and it builds, with nothing to install. Free, and no account needed.
What CapacitiveSensor does
The library flips the send pin and counts how long the receive pin takes to follow through the resistor. A finger near the metal adds capacitance, so the count gets bigger. The value it returns is not in any unit: it is a count that you compare against a threshold you pick by watching the numbers on Serial.
The resistor sets sensitivity. Around 1 M惟 responds to an actual touch, 10 M惟 starts to sense a hand an inch or two away, and larger values sense from further but read more slowly and pick up more noise. A small capacitor (about 100 pF) from the receive pin to ground steadies the readings.
| Library Manager name | CapacitiveSensor |
|---|---|
| Author | Paul Badger, Paul Stoffregen |
| Include | #include <CapacitiveSensor.h> |
| Boards | every board Mokxi compiles for but ATtiny85 |
| In the simulator | Simulated: it runs against the part the way it does on the bench. |
| Parts it drives | Touch foil, Resistor |
Install it
It builds on every board Mokxi compiles for but ATtiny85.
In Mokxi it is built in: #include <CapacitiveSensor.h> and the sketch compiles, with no download, no zip and no Library Manager.
On a real board, install "CapacitiveSensor" by Paul Badger, Paul Stoffregen from the Arduino IDE鈥檚 Library Manager (Sketch, Include Library, Manage Libraries), or add CapacitiveSensor to lib_deps in PlatformIO. Mokxi follows the calls of release 0.5.1, so a sketch written here builds there too.
What to know in the simulator: The count is what the simulated RC gives: put a touch foil on the receive pin and hold it. A hand coming near before it touches is not simulated.
ESP32-C3 路 Arduino Uno 路 Arduino Nano 路 Arduino Mega 2560 路 Arduino Leonardo 路 SparkFun Pro Micro 路 Arduino Micro 路 ESP32-C6 路 Raspberry Pi Pico 路 Raspberry Pi Pico W 路 Seeed XIAO SAMD21 路 STM32 路 STM32 Nucleo-F411RE 路 STM32 Blue Pill 路 micro:bit V2 路 Arduino Uno R4 路 ESP32 DevKit 路 ESP32-S3-DevKitC-1 路 ESP8266 NodeMCU 路 Arduino Pro Mini 3.3 V 路 Seeed XIAO ESP32-C3 路 ESP32-C3 SuperMini 路 Seeed XIAO ESP32-C6 路 ESP32-DevKitC V4 路 LOLIN32 Lite 路 Wemos D1 R32 路 Cheap Yellow Display 路 TTGO T-Display 路 Seeed XIAO ESP32-S3 路 Arduino Nano ESP32 路 Arduino Nano RP2040 Connect 路 Seeed XIAO RP2040 路 Waveshare RP2040-Zero 路 Arduino Uno R4 WiFi
The calls you will use
In the order a sketch meets them.
CapacitiveSensor pad = CapacitiveSensor(4, 2)
Send pin 4, receive pin 2, with the resistor between them and the foil on pin 2.
long total = pad.capacitiveSensor(30)
Takes 30 samples and returns their total count, minus a baseline the library tracks. More samples give steadier but slower readings. It returns -2 when the receive pin never followed in time.
long total = pad.capacitiveSensor(30);
Serial.println(total);
digitalWrite(LED_BUILTIN, total > 500 ? HIGH : LOW);pad.capacitiveSensorRaw(30)
The same measurement without the baseline subtracted, for calibrating your threshold.
pad.set_CS_AutocaL_Millis(0xFFFFFFFF)
Turns off the automatic recalibration (every 20 seconds by default), which otherwise can absorb a finger held still on the pad.
pad.set_CS_Timeout_Millis(2000)
How long one reading may take before giving up with -2.
Example: A touch pad on two pins
On the Arduino Uno R3. It runs in the browser exactly as printed.
#include <CapacitiveSensor.h>
// A 1 megohm resistor between pin 4 (send) and pin 2 (receive). On the bench
// the receive pin also goes to a piece of foil; a finger is not simulated, so
// the count here stays at its floor.
CapacitiveSensor cs_4_2 = CapacitiveSensor(4, 2);
void setup() {
Serial.begin(9600);
}
void loop() {
long start = millis();
long total = cs_4_2.capacitiveSensor(30);
Serial.print("took ");
Serial.print(millis() - start);
Serial.print(" ms, count ");
Serial.println(total);
delay(200);
}Wiring
- Arduino Uno R3 4 to Resistor 1
- Arduino Uno R3 2 to Resistor 2
Common errors and how to fix them
capacitiveSensor() returns -2 every time
The receive pin never changed before the timeout. The resistor is missing, in the wrong pins, or far too large; check it sits between the send and receive pins named in the constructor.
Readings jump around even with nothing touching
Battery-powered boards have no ground reference. Connect the board鈥檚 ground to something large or to earth, raise the sample count, and add about 100 pF from the receive pin to ground.
A held finger stops being detected after a while
Automatic recalibration is treating the touch as the new baseline. Disable it with set_CS_AutocaL_Millis(0xFFFFFFFF), or use capacitiveSensorRaw() with your own baseline.
Projects that use CapacitiveSensor
Built-in projects that include it. Each page has the full sketch and opens in the editor, already wired.
Keep going
Parts
Try CapacitiveSensor without installing anything
Open the example, change the sketch, and keep your version in a free account.