Electronics
Arduino Capacitive Buttons
Sometimes the magic isn’t in complex components, but in how cleverly you use the basics. Did you know you can create capacitive touch buttons using nothing more than a resistor , a bit of metal , and an Arduino ?
Sometimes the magic isn’t in complex components, but in how cleverly you use the basics. Did you know you can create capacitive touch buttons using nothing more than a resistor, a bit of metal, and an Arduino? No fancy touch modules, no exotic chips. And best of all: you can even activate them through thin plastic or paper. Let me show you how it works.
The idea behind capacitive touch
Using the capacitive sensor library for Arduino, a digital pin sends a 5V pulse through a large resistor (typically around 10 MΩ) to a metal plate. That plate behaves like a small capacitor. On the other side, a second pin measures how long it takes for the voltage to rise high enough to be read as a “HIGH”. Under normal conditions, this happens extremely fast, just a fraction of a second.
But the moment you touch the metal plate, something interesting happens.
You become part of the circuit
Your body has its own capacitance. When you touch the plate, you add extra capacitance to the system. As a result, the plate takes just a little longer to charge up. That extra delay is exactly what the Arduino detects. If the voltage rise takes longer than expected, the code concludes: someone is touching this. At that point, you can trigger whatever action you want.
In my case: toggling an LED on and off with each touch.
Hardware interpretation
Capacitive sensor
- Send pin:
D5 - Receive pin:
D4
LED
- LED anode → D2 via resistor (as shown)
- LED cathode → GND
Required library
Install this library in Arduino IDE:
Sketch → Include Library → Manage Libraries
Search: CapacitiveSensor by Paul Badger
Arduino Code
View the full source code
/**
Copyright 2026 Achim Pieters | StudioPieters®
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
for more information visit https://www.studiopieters.nl
**/
#include <CapacitiveSensor.h>
// CapacitiveSensor(sendPin, receivePin)
CapacitiveSensor capSensor = CapacitiveSensor(5, 4);
// LED pin
const int ledPin = 2;
// Adjust this after reading Serial Monitor
long touchThreshold = 1000;
// State variables
bool ledState = false;
bool touchActive = false;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
// Disable auto calibration for consistent readings
capSensor.set_CS_AutocaL_Millis(0xFFFFFFFF);
Serial.println("Capacitive touch toggle ready");
}
void loop() {
long sensorValue = capSensor.capacitiveSensor(30);
Serial.print("Cap value: ");
Serial.println(sensorValue);
// Touch detected
if (sensorValue > touchThreshold && !touchActive) {
ledState = !ledState; // TOGGLE LED
digitalWrite(ledPin, ledState);
touchActive = true; // Lock until released
}
// Touch released
if (sensorValue < touchThreshold * 0.6) {
touchActive = false;
}
delay(10);
}
Calibration (Important)
- Upload code
- Open Serial Monitor (9600 baud)
- Note values:
- No touch → ~50–300
- Touch → ~1500–8000
- Set:
long touchThreshold = 1200; // exampleThe problem: false touches
There was one downside. Touching the wires themselves could sometimes be detected as a touch, even through the silicone insulation. Not ideal. Time for a fix.
The solution: shielding with an old audio cable
By stripping an old audio cable, I got exactly what I needed: a central conductor and a shielding braid.
- The core wire connects to the sensor
- The shielding is connected to GND
This setup ensures that touching the wires no longer affects the measurement. Only the sensor responds, exactly as intended.
Multiple buttons, hidden behind plastic
Using the same principle, I built several capacitive buttons. Instead of flat metal plates, I used copper rings, made from leftover household wiring. Surprisingly effective as sensor surfaces. I mounted them behind a thin plastic panel, with an LED strip placed behind them. From the outside, you don’t see any buttons at all, but touch the right spot, and everything lights up.
As long as you don’t touch the voltage directly, the system works beautifully.
Simple, clever, and surprisingly powerful
What makes projects like this so satisfying is how little you need to create something that feels almost magical. No visible buttons, no mechanical wear, just a subtle touch and an Arduino that understands what you mean.
All with a single resistor, a piece of metal, and a bit of curiosity.