ESP32 Capacitive Touch Sensor Pins with Arduino IDE

This article shows how to use the ESP32 touch pins with Arduino IDE. The ESP32 touch pins can sense variations in anything that holds an electrical charge. They are often used to wake up the ESP32 from deep sleep.

ESP32 Touch Pins with Arduino IDE

To read the value of the ESP32 touch pins, use the touchRead(GPIO) function, that accepts as argument, the GPIO you want to read.

Watch the Video Tutorial

You can watch the video tutorial or keep reading this page for the written instructions.

Introducing the ESP32 Touch Sensor

The ESP32 has 10 capacitive touch GPIOs. These GPIOs can sense variations in anything that holds an electrical charge, like the human skin. So they can detect variations induced when touching the GPIOs with a finger.

These pins can be easily integrated into capacitive pads, and replace mechanical buttons. Additionally, the touch pins can also be used as a wake up source when the ESP32 is in deep sleep.

Take a look at your board pinout to locate the 10 different touch sensors – the touch sensitive pins are highlighted in pink color.

ESP32 Touch Sensitive Pins GPIOs

Learn more about the ESP32 GPIOs: ESP32 Pinout Reference.

You can see that touch sensor 0 corresponds to GPIO 4, touch sensor 2 to GPIO 2, and so on.

Note: Touch sensor 1 is GPIO 0. However, it’s not available as a pin in this particular ESP32 development board (version with 30 GPIOs). GPIO 0 is available on the version with 36 pins.

Note: at the time of writing this tutorial, there is an issue with touch pin assignment in Arduino IDE. GPIO 33 is swapped with GPIO 32 in the assignment. This means that if you want to refer to GPIO 32 you should use T8 in the code. If you want to refer to GPIO33 you should use T9. If you don’t have this issue, please ignore this note.

touchRead()

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

touchRead(GPIO);

Code – Reading the Touch Sensor

We’ll program the ESP32 using Arduino IDE, so make sure you have the ESP32 add-on installed before proceeding:

Let’s see how that function works by using an example from the library. In the Arduino IDE, go to File > Examples > ESP32 > Touch and open the TouchRead sketch.

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

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

void loop() {
  Serial.println(touchRead(4));  // get value of Touch 0 pin = GPIO 4
  delay(1000);
}

View raw code

This example reads the touch pin 0 and displays the results in the Serial Monitor.

The T0 pin (touch pin 0), corresponds to GPIO 4, as we’ve seen previously in the pinout.

In this code, in the setup(), you start by initializing the Serial Monitor to display the sensor readings.

Serial.begin(115200);

In the loop() is where you read the sensor.

Serial.println(touchRead(4));

Use the touchRead() function, and pass as an argument the pin you want to read. In this case, the example uses T0, which is the touch sensor 0, in GPIO 4. You can either pass the touch sensor number (T0) or the GPIO number (4).

Now, upload the code to your ESP32 board. Make sure you have the right board and COM port selected.

Testing the sketch example

Connect a jumper wire to GPIO 4. You will touch the metal part of this wire so that it senses the touch.

In the Arduino IDE window, go to Tools and open the Serial Monitor at a baud rate of 115200. You’ll see the new values being displayed every second.

Touch the wire connected to GPIO 4 and you’ll see the values decreasing.

ESP32 Touch Pins with Arduino IDE Demonstration

You can also use the serial plotter to better see the values. Close the serial monitor, go to Tools > SerialPlotter.

ESP32 Touch Pins with Arduino IDE Demonstration Serial Plotter

Touch Sensitive LED

You can use this feature to control outputs. In this example, we’ll build a simple touch controlled LED circuit. When you touch the GPIO with your finger, the LED lights up.

For this example, you need the following parts:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Finding the threshold value

Grab a piece of aluminium foil, cut a small square, and wrap it around the wire as shown in the following figure.

ESP32 Touch Pins with Arduino IDE threshold

With the previous code running, go back to the serial monitor.

Now, touch the aluminium foil, and you’ll see the values changing again.

ESP32 Touch Pins with Arduino IDE Demonstration with aluminium foil

In our case, when we’re not touching the pin, the normal value is above 70. And when we touch the aluminum foil it drops to some value below 10.

So, we can set a threshold value, and when the reading goes below that value, an LED lights up. A good threshold value in this case is 20, for example.

Schematic

Add an LED to your circuit by following the next schematic diagram. In this case, we’re connecting the LED to GPIO 16.

Touch Sensitive LED with ESP32 Touch Pins Schematic Diagram

Code

Copy the following code to your Arduino IDE.

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

// change with your threshold value
const int threshold = 20;
// variable for storing the touch pin value 
int touchValue;

void setup(){
  Serial.begin(115200);
  delay(1000); // give me time to bring up serial monitor
  // initialize the LED pin as an output:
  pinMode (ledPin, OUTPUT);
}

void loop(){
  // read the state of the pushbutton value:
  touchValue = touchRead(touchPin);
  Serial.print(touchValue);
  // check if the touchValue is below the threshold
  // if it is, set ledPin to HIGH
  if(touchValue < threshold){
    // turn LED on
    digitalWrite(ledPin, HIGH);
    Serial.println(" - LED on");
  }
  else{
    // turn LED off
    digitalWrite(ledPin, LOW);
    Serial.println(" - LED off");
  }
  delay(500);
}

View raw code

This code reads the touch value from the pin we’ve defined, and lights up an LED when the value is below the threshold. This means that when you place your finger in the aluminium pad, the LED lights up.

Testing the Project

Upload the sketch to your ESP32. Now, test your circuit. Touch the aluminum foil and see the LED lighting up.

Touch Sensitive LED with ESP32 Touch Pins Demonstration

Wrapping Up

In this tutorial you’ve learned how to use the ESP32 touch pins. In summary:

  • The ESP32 has 10 capacitive touch GPIOs.
  • When you touch a touch-sensitive GPIO, the value read by the sensor drops.
  • You can set a threshold value to make something happen when it detects touch.
  • The ESP32 touch pins can be used to wake up the ESP32 from deep sleep.

We hope you’ve found this tutorial interesting. If you want to learn more about the ESP32, enroll in our course: Learn ESP32 with Arduino IDE.

You might also want to take a look at our free ESP32 projects and tutorials.

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Recommended Resources

Build a Home Automation System from Scratch » With Raspberry Pi, ESP8266, Arduino, and Node-RED.

Home Automation using ESP8266 eBook and video course » Build IoT and home automation projects.

Arduino Step-by-Step Projects » Build 25 Arduino projects with our course, even with no prior experience!

What to Read Next…


Enjoyed this project? Stay updated by subscribing our newsletter!

33 thoughts on “ESP32 Capacitive Touch Sensor Pins with Arduino IDE”

  1. Hola! fantástico trabajo.
    Estoy siguiendo tus artículos y estoy aprendiendo mucho, cosa que te agradezco.
    Tengo un problema que no acierto a descifrar, cuando intento subir un sketch a mi placa (ESP32 DEVKIT V1 de http://www.doit.am), siempre de da el mismo error:
    “…
    El Sketch usa 245148 bytes (18%) del espacio de almacenamiento de programa. El máximo es 1310720 bytes.
    Las variables Globales usan 13588 bytes (4%) de la memoria dinámica, dejando 314092 bytes para las variables locales. El máximo es 327680 bytes.
    esptool.py v2.6
    Serial port COM6
    Connecting…….._____….._____….._____….._____….._____….._____…..____Ha ocurrido un error mientras se enviaba el sketch
    _

    A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header”
    No encuentro el motivo. Estoy usando WIN10 32Bits y el IDE Arduino.
    Pensando que se tratara de una tarjeta diferente, he probado distintas tarjetas, con los mismos resultados.
    Como puedo saber realmente que placa tengo. Hay alguna forma de saberlo.
    Agradecería que alguien me indicara como salvar este problema.
    Gracias por todo.

    Reply
  2. hi everyone does anyone knows the exactlly pin to interface sim800l with esp32-nodemcuS? i have tried many pins even defined or tried the example code provided by TINYGSM but it doesn’t work
    does anyone can help me?

    Reply
  3. Are the touch GPIO’s protected against ESD – static electricity – internally ? If a metal foil is connected to the pin will the ESP32 be damaged if the person touching it carries a high static charge ? Is it better to cover the metal with a thin insulator to avoid a direct conductive path to the device ?

    Reply
    • All the GPIO’s have an internal pullup resistor. I am not sure if this is functional if not called in code. I have never experienced any bad ESD feedback on my units. I immerse mine in water tanks and have done everything possible to short them out. Just use the wires as they are and experiment. Lots of possibilities with this feature.!!

      Reply
  4. Hi I’m making a kids robot with an oled panel and some led lights .I’m using a touch pin to start a random sequence of led palettes and it works fine. Now comes the part i dont get, when i send a message to the oled panel whether from mqtt or internally from the esp32 the leds start up by themselves after the text has rolled on for a couple of seconds. There is no programmed connection between the two so my conclusion so far is that the touch pin is somehow sensitive to the text being displayed. i have set it to go off at value below 20 , i tried using 10 but it wouldn’t sense at that level. Any ideas whats going on?

    Reply
  5. Hello! I was just wondering if it’s actually possible to use this to measure capacitance. Much like a multimeter would with its two probes.

    Reply
  6. Hi, I am using 8 touch inputs on a ESP32 WROOM with GPIO0 accessable. Just for testing I am printing all inputs to the serial monitor.
    While all inputs in ‘high state’ (not touched), I found that just one (GPIO0) stays at a value of 1. Should I do something with initialising ?

    Reply
  7. Hey Sara and Rui!
    Firstly, thank you for these tutorials – I’m learning a lot!

    I notice that you haven’t included a PinMode line for the touch input. What’s the reason behind that?

    All the best,
    Dax.

    Reply
    • I can field this one, Rodrigues.
      It’s quite simple, actually! 🙂

      You need to duplicate the lines that mention the LED and the touch pin. For example:

      // set pin numbers
      const int touchPin = 4;
      const int ledPin = 16;
      const int touch2Pin = 5; //add these new lines, choose your own GPIO pins
      const int led2Pin = 17;

      // variable for storing the touch pin value
      int touchValue;
      int touch2Value; //new line

      void setup(){
      Serial.begin(115200);
      delay(1000); // give me time to bring up serial monitor
      // initialize the LED pin as an output:
      pinMode (ledPin, OUTPUT);
      pinMode (led2Pin, OUTPUT); //new line
      }

      etc..

      Hope that helps!
      Dax.

      Reply
      • Hello thanks you ! I have an error when I compile. I have this, why?

        Code___moi: In function ‘void loop()’:
        Code___moi:40: error: expected primary-expression before ‘}’ token
        }

        ^

        expected primary-expression before ‘}’ token

        // set pin numbers
        const int touchPin = 4;
        const int ledPin = 16;
        const int touch2Pin = 5; //add these new lines, choose your own GPIO pins
        const int led2Pin = 17;

        // variable for storing the touch pin value
        int touchValue;
        int touch2Value; //new line

        void setup(){
        Serial.begin(115200);
        delay(1000); // give me time to bring up serial monitor
        // initialize the LED pin as an output:
        pinMode (ledPin, OUTPUT);
        pinMode (led2Pin, OUTPUT); //new line
        }
        void loop(){
        // read the state of the pushbutton value:
        touchValue = touchRead(touchPin);
        Serial.print(touchValue);
        touch2Value = touchRead(touch2Pin);
        Serial.print(touch2Value);
        // check if the touchValue is below the threshold
        // if it is, set ledPin to HIGH
        if(touchValue < threshold){
        // turn LED on
        digitalWrite(ledPin, HIGH);
        Serial.println(” – LED on”);
        } if(touch2Value < threshold){
        // turn LED on
        digitalWrite(led2Pin, HIGH);
        Serial.println(” – LED on”);
        }
        else
        }

        thanks

        Reply
        • It means you have an uneven number of braces { } in your code.
          If you are using the Arduino IDE, putting the text cursor on a closed brace will popup a little text box showing the opening line (where associated the { is found), put your cursor on an open brace and the closing brace will be highlighted. That’s one way to work out what is missing.
          Good luck!

          Hot tip: press CTRL+T in Arduino IDE to auto-format your code. That can help in finding the error.

          Reply
  8. @H. Helfmann, hmm.. maybe you have some noise? Which pins are you using? Is it possible you’re using a pin fron ADC2? Those are shared with the on-board wifi module, so could be interference from there.

    Try changing to a few other touch-enabled pins and see if they exhibit the same noisy behaviour.

    Reply
    • Thanks for your reply.
      I tested all GPIOs with the same effect.
      But I tried touch with deepSleep and there were no “noise”.
      Next I used interrupt: no false signals.

      Reply
  9. Hello ,
    I am checking the Deep Sleep Using Touchpad, But I am facing this issue in Serial Monitor when i touch the pin.
    Guru Meditation Error: Core 1 panic’ed (Coprocessor exception)
    14:22:03.541 -> Core 1 register dump:
    14:22:03.574 -> PC : 0x400d0d13 PS : 0x00060e31 A0 : 0x8008124e A1 : 0x3ffbea80
    14:22:03.674 -> A2 : 0x3ffbfe88 A3 : 0x00000001 A4 : 0x8008676a A5 : 0x00000000
    14:22:03.773 -> A6 : 0x3ffbeb88 A7 : 0x00000001 A8 : 0x800d0d13 A9 : 0x3ffbeb10
    14:22:03.839 -> A10 : 0x7fc00000 A11 : 0x00000000 A12 : 0x00000000 A13 : 0x3ffbeb10
    14:22:03.939 -> A14 : 0x00000008 A15 : 0x00000000 SAR : 0x0000000a EXCCAUSE: 0x00000004
    14:22:04.038 -> EXCVADDR: 0x00000000 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xffffffff
    14:22:04.137 -> Core 1 was running in ISR context:
    14:22:04.170 -> EPC1 : 0x400d0d13 EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x40083f9b
    14:22:04.270 ->
    14:22:04.270 -> ELF file SHA256: 0000000000000000
    14:22:04.303 ->
    14:22:04.303 -> Backtrace: 0x400d0d13:0x3ffbea80 0x4008124b:0x3ffbeb40 0x4008124b:0x3ffbeb60 0x40083d81:0x3ffbeb80 0x4000bfed:0x3ffb1f30 0x400874d9:0x3ffb1f40 0x400e2137:0x3ffb1f60 0x400d0db8:0x3ffb1f90 0x400d1fad:0x3ffb1fb0 0x40086675:0x3ffb1fd0
    14:22:04.535 ->
    14:22:04.535 -> Rebooting…

    Reply
  10. Hello, is there any way to disable the capacitive touch feature on the ESP32? I am using those pins to read ADC signal, and whenever those pins were touched it would pull the input HIGH. I Couldn’t use pull up or pull down because the input I am reading were analog. Any clue? Thanks

    Reply
  11. When I Use the touch sensor with the function touchSetCycles( 33000, 6300 ); in the Arduino IDE it works fine, but hen I run the same code in Platform IO touchSetCycles( 33000, 6300 ); does not have the same effect in the sensitivity of the touch pad, why is that ?

    Reply
  12. You’re using touch wrong!
    The pin or metal foil needs an insulator. A plastic cover, a foil, etc.
    Never directly touch the pin/wire/metal by itself. This wouldn’t form a capacitive coupling!

    You can glue the metal foil inside of a housing, and touch on the outside – so your finger is earth potential, and forms a capacitor to the metal foil through the (non-conducting) housing material.

    This way, you get more robustness, water tightness etc, as you are used from other touch applications.
    If you have a metal part, you can use a small capacitor in series, like it is done in those metal lamps with touch functionality.
    You can read in the guidelines from the typical IC suppliers:
    microchip.com/downloads/en/Appnotes/Capacitive-Touch-Sensor-Design-Guide-DS00002934-B.pdf

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.