Skip to content
My Account

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 ?

5 min read

Arduino Capacitive Buttons
No ratings yet, be the first.

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.

Diagram of a capacitive touch sensor: a resistor and metal plate acting as a small capacitor

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.

Diagram showing the extra charging delay the Arduino detects when the plate is touched

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)

  1. Upload code
  2. Open Serial Monitor (9600 baud)
  3. Note values:
    • No touch → ~50–300
    • Touch → ~1500–8000
  4. Set:
long touchThreshold = 1200; // example

The 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.

Wiring diagram using shielded cable so only the sensor plate responds to touch, not the wire

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.

Advertisement
All projects