ESP32 Basics: Capacitive Touch Pins

ESP32 is a great development board for creating smart IoT projects and adding touch functionality will make them even smarter.

ESP32 offers 10 capacitive touch-sensing GPIOs. You can use these GPIOs to update existing simple push button projects or to create light switches, musical instruments, or custom interactive surfaces.

Let’s learn how to handle these touch-sensing pins and use them in projects.

Touch detection in ESP32 is managed by the ULP coprocessor. So these touch pins can also be used to wake ESP32 from deep sleep.

How ESP32 senses Touch?

ESP32 uses the electrical properties of the human body as input. When the touch-sensing pin is touched with a finger, a small electric charge is drawn to the point of contact.

This triggers capacitance variation resulting in an analog signal. Two successive approximation ADCs (SAR ADCs) then convert this analog signal into a digital number.

ESP32 Touch Pins

ESP32 has 10 capacitive touch-sensing GPIOs. When a capacitive load (such as a human skin) is in close proximity to the GPIO, ESP32 detects a change in capacitance.

Although the ESP32 has total 10 capacitive touch-sensing GPIO pins, only 9 of them are broken out to the pin headers on both sides of the 30 pin ESP32 development board.

esp32 touch pins

Reading the Touch Sensor

Reading the touch sensor is straightforward. In the Arduino IDE, you use the touchRead() function, which accepts as an argument the GPIO pin number you want to read.


Hardware Hookup

Enough of the theory! Let’s look at a practical example.

Let’s wire a cable to Touch #0 (GPIO #4). You can attach any conductive object like aluminum foil, conductive cloth, conductive paint etc. to this pin and turn it into a touch pad.

connecting wire to esp32 for reading touch gpio

Example Code

Let’s see how it works, using an example from the library. Open your Arduino IDE, and navigate to File > Examples > ESP32 > Touch, and open the TouchRead sketch.

This example simply reads touch pin 0 and shows the result on the serial monitor.

// ESP32 Touch Test
// Just test touch pin - Touch0 is T0 which is on GPIO 4.

void setup() {
  delay(1000); // give me time to bring up serial monitor
  Serial.println("ESP32 Touch Test");

void loop() {
  Serial.print("Touch: ");
  Serial.println(touchRead(4));  // get touch value on GPIO 4

Once you have uploaded the sketch, open the serial monitor at baud rate 115200 and press the EN button on the ESP32.

Now try touching the metal part of the wire and see how it reacts to the touch.

esp32 touch test output on serial monitor

Code Explanation:

The code is pretty straightforward. In the setup(), we first initialize the serial communication with the PC.


In loop() we use touchRead() function, and pass as argument the pin we want to read. In this case, the GPIO #4. You can also pass the touch sensor number T0.


ESP32 Project – Touch-activated LED

Let’s quickly create a project to demonstrate how the ESP32’s touch pins can be used to control devices. In this example, we are going to make a simple touch-activated LED that will light up when you touch the GPIO pin.

Of course this project can be expanded to open doors, switch relays, light LEDs, or anything else you can think of.

Finding the Threshold

Before proceeding, you should see what readings you are actually getting from the ESP32. Note the output you get when you touch the pin and when you don’t.

When you run the previous sketch, you’ll see the close to the following readings in the serial monitor:

  • when you touch the pin (~3)
  • when you don’t touch the pin (~71)

Based on the values, we can set a threshold, so that when the reading drops below the threshold, we will toggle the LED. 30 may be a good threshold value in this case.

Example Code

Below is a simple code that turns on the on-board LED when you touch the pin once and turns it off when you touch it again.

// set pin numbers
const int touchPin = 4;
const int ledPin = 2;

const int threshold = 30;  // set the threshold

int ledState = LOW;         // the current state of the output pin
int touchState;             // the current reading from the input pin
int lastTouchState = LOW;   // the previous reading from the input pin

unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(ledPin, OUTPUT);

  // set initial LED state
  digitalWrite(ledPin, ledState);

void loop() {
  // read the state of the pin
  int reading = touchRead(touchPin);

  // binarize touch reading for easy operation
  if (reading < threshold) {
    reading = HIGH;
  } else{
    reading = LOW;
  // If the pin is touched:
  if (reading != lastTouchState) {
    // reset the debouncing timer
    lastDebounceTime = millis();

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the touch state has changed:
    if (reading != touchState) {
      touchState = reading;

      // only toggle the LED if the new touch state is HIGH
      if (touchState == HIGH) {
        ledState = !ledState;

  // set the LED:
  digitalWrite(ledPin, ledState);

  // save the reading. Next time through the loop, it'll be the lastTouchState:
  lastTouchState = reading;

Upload the sketch to your ESP32. You should see the LED toggle every time you touch the wire.