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.
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.
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:
- Windows instructions – ESP32 Board in Arduino IDE
- Mac and Linux instructions – ESP32 Board in Arduino IDE
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);
}
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.
You can also use the serial plotter to better see the values. Close the serial monitor, go to Tools > SerialPlotter.
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:
- ESP32 DOIT DEVKIT V1 Board (read Best ESP32 Development Boards)
- 5mm LED
- 330 Ohm resistor
- Breadboard
- Jumper wires
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.
With the previous code running, go back to the serial monitor.
Now, touch the aluminium foil, and you’ll see the values changing again.
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.
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);
}
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.
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.
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.
Hi Vicen.
Next time, try to post your question in english so that everyone can understand.
That error means that your ESP32 is not in flashing mode.
When you start seeing those doots …._____….._____ you need to press the on-board BOOT button for a while (maybe 2 seconds)
Then, the code should be uploaded successfully.
You can follow this article that addresses that subject: https://randomnerdtutorials.com/solved-failed-to-connect-to-esp32-timed-out-waiting-for-packet-header/
Regards,
Sara
Hi, Sara, Vincen.
I had the same too, tried several options without succes.
But finally I found that I had no correct driver installed (in my case CH340). After installing everything worked fine.
How to Use touch_pad_get_voltage() function.
Has anyone tried the capacitive sensors in ESP32 for liquid level sensing?
Hi Luís.
No, we didn’t 🙁
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?
Hi.
Take a look at these tutorials with the SIM800L and see if it helps:
https://randomnerdtutorials.com/esp32-sim800l-send-text-messages-sms/
https://randomnerdtutorials.com/esp32-sim800l-publish-data-to-cloud/
Regards,
Sara
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 ?
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.!!
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?
Hi.
I’m not sure what’s the issue. But, it can be sensitive to the surroundings.
However, I would suggest that you try different GPIOs to connect the LEDs and try to choose another touch pin.
Regards,
Sara
You might be dealing with a noise ‘glitch’ on the pin. I wrote a little example that helps deal with this you might want to check out. Good luck! Regards, John. https://github.com/digamesystems/CapacitiveTouchTest
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.
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 ?
Hi.
GPIO 0 is pulled HIGH by default.
See the ESP32 pinout Guide: https://randomnerdtutorials.com/esp32-pinout-reference-gpios/.
I would recommend using another Touch Pin other than GPIO 0.
Regards,
Sara
how can read and write the configuration registers of the ESP32?
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.
Hello, how to add a second led with a second touchread in the program? Thank you 🙂
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.
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
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.
Hello,
touch works, but there are also Signals coming in, without touch.
@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.
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.
I am working on ESP32 touch sensor to act as a liquid level sensor.
Please do guide me as i am really new to arduino
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…
Hi.
What code are you using?
Are you following a specific tutorial?
Regards,
Sara
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
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 ?
I want to change the pin from 22 to 13 as I use esp32 S3, but it seems there is no pin assignment
Hi.
What do you mean?
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