ESP32 Touch Wake Up from Deep Sleep

This guide shows how to wake up the ESP32 from deep sleep using the touch sensitive pins. The ESP32 will be programmed using Arduino IDE.

The ESP32 can be awake from deep sleep using several wake up sources: timer, external wake up and touch wake up. This article shows how to use touch wake up.

To learn more about deep sleep and other wake up sources, you can follow the next tutorials:

Writing a Deep Sleep Sketch

To write a sketch to put your ESP32 into deep sleep mode, and then wake it up, you need to:

  1. First, configure the wake up sources. This means configure what will wake up the ESP32. You can use one or combine more than one wake up source. This tutorial covers how to use the touch pins as a wake up source.
  2. You can decide what peripherals to shut down or keep on during deep sleep. However, by default, the ESP32 automatically powers down the peripherals that are not needed with the wake up source you define.
  3. Finally, you use the esp_deep_sleep_start() function to put your ESP32 into deep sleep mode.

Touch Wake Up

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 ESP32 touch pins can be used to wake up the ESP32 from deep sleep.

Touch Pins

The ESP32 touch pins are highlighted in pin color in the following diagram.

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

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 GPIO 33 you should use T9. If you don’t have this issue, please ignore this note.

Learn everything you need to know about the ESP32 GPIOs: ESP32 Pinout Reference: Which GPIO pins should you use?

Enable Touch Wake Up

Enabling the ESP32 to wake up using a touchpin is simple. In the Arduino IDE, you need to use the following function:

esp_sleep_enable_touchpad_wakeup()

Code – Touch Wake Up

To program the ESP32 we’ll use Arduino IDE. So, you need to make sure you have the ESP32 add-on installed. Follow the right tutorial to install the ESP32 add-on, if you haven’t already:

Let’s see how touch wake up works using an example from the library. Open your Arduino IDE, and go to File Examples ESP32 Deep Sleep, and open the TouchWakeUp example sketch.

/*
  Deep Sleep with Touch Wake Up
  This code displays how to use deep sleep with a touch as a wake up source and how to store data in RTC memory to use it over reboots
  ESP32 can have multiple touch pads enabled as wakeup source
  ESP32-S2 and ESP32-S3 supports only 1 touch pad as wakeup source enabled
  This code is under Public Domain License. Author: Pranav Cherukupalli <[email protected]>
*/

#if CONFIG_IDF_TARGET_ESP32
  #define THRESHOLD   40      /* Greater the value, more the sensitivity */
#else //ESP32-S2 and ESP32-S3 + default for other chips (to be adjusted) */
  #define THRESHOLD   5000   /* Lower the value, more the sensitivity */
#endif

RTC_DATA_ATTR int bootCount = 0;
touch_pad_t touchPin;
/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

/*
Method to print the touchpad by which ESP32
has been awaken from sleep
*/
void print_wakeup_touchpad(){
  touchPin = esp_sleep_get_touchpad_wakeup_status();

  #if CONFIG_IDF_TARGET_ESP32
    switch(touchPin)
    {
      case 0  : Serial.println("Touch detected on GPIO 4"); break;
      case 1  : Serial.println("Touch detected on GPIO 0"); break;
      case 2  : Serial.println("Touch detected on GPIO 2"); break;
      case 3  : Serial.println("Touch detected on GPIO 15"); break;
      case 4  : Serial.println("Touch detected on GPIO 13"); break;
      case 5  : Serial.println("Touch detected on GPIO 12"); break;
      case 6  : Serial.println("Touch detected on GPIO 14"); break;
      case 7  : Serial.println("Touch detected on GPIO 27"); break;
      case 8  : Serial.println("Touch detected on GPIO 33"); break;
      case 9  : Serial.println("Touch detected on GPIO 32"); break;
      default : Serial.println("Wakeup not by touchpad"); break;
    }
  #else
    if(touchPin < TOUCH_PAD_MAX)
    {
      Serial.printf("Touch detected on GPIO %d\n", touchPin); 
    }
    else
    {
      Serial.println("Wakeup not by touchpad");
    }
  #endif
}

void setup(){
  Serial.begin(115200);
  delay(1000); //Take some time to open up the Serial Monitor

  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  //Print the wakeup reason for ESP32 and touchpad too
  print_wakeup_reason();
  print_wakeup_touchpad();

  #if CONFIG_IDF_TARGET_ESP32 
  //Setup sleep wakeup on Touch Pad 3 + 7 (GPIO15 + GPIO 27) 
  touchSleepWakeUpEnable(T3,THRESHOLD);
  touchSleepWakeUpEnable(T7,THRESHOLD);
  
  #else //ESP32-S2 + ESP32-S3
  //Setup sleep wakeup on Touch Pad 3 (GPIO3) 
  touchSleepWakeUpEnable(T3,THRESHOLD);

  #endif

  //Go to sleep now
  Serial.println("Going to sleep now");
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop(){
  //This will never be reached
}

View raw code

Setting the Threshold

The first thing you need to do is setting a threshold value for the touch pins. In this case we’re setting the Threshold to 40. You may need to change the threshold value depending on your project.

#define Threshold 40

When you touch a touch-sensitive GPIO, the value read by the sensor decreases. So, you can set a threshold value that makes something happen when touch is detected.

The threshold value set here means that when the value read by the touch-sensitive GPIO is below 40, the ESP32 should wake up. You can adjust that value accordingly to the desired sensitivity.

Attach Interrupts

You need to attach interrupts to the touch sensitive pins. When touch is detected on a specified GPIO, a callback function is executed. For example, take a look at the following line:

//Setup interrupt on Touch Pad 3 (GPIO15)
touchAttachInterrupt(T3, callback, Threshold); 

When the value read on T3 (GPIO 15) is lower than the value set on the Threshold variable, the ESP32 wakes up and the callback function is executed.

The callback() function will only be executed if the ESP32 is awake.

  • If the ESP32 is asleep and you touch T3, the ESP will wake up – the callback() function won’t be executed if you just press and release the touch pin;
  • If the ESP32 is awake and you touch T3, the callback function will be executed. So, if you want to execute the callback() function when you wake up the ESP32, you need to hold the touch on that pin for a while, until the function is executed.

In this case the callback() function is empty.

void callback(){
   //placeholder callback function
}

If you want to wake up the ESP32 using different touch pins, you just have to attach interrupts to those pins.

Next, you need to use the esp_sleep_enable_touchpad_wakeup() function to set the touch pins as a wake up source.

//Configure Touchpad as wakeup source
esp_sleep_enable_touchpad_wakeup()

Schematic

To test this example, wire a cable to GPIO 15, as shown in the schematic below.

(This schematic uses the ESP32 DEVKIT V1 module version with 30 GPIOs – if you’re using another model, please check the pinout for the board you’re using.)

Parts Required:

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!

Testing the Example

Upload the code to your ESP32, and open the Serial Monitor at a baud rate of 115200.

The ESP32 goes into deep sleep mode.

You can wake it up by touching the wire connected to Touch Pin 3.

When you touch the pin, the ESP32 displays on the Serial Monitor: the boot number, the wake up cause, and which touch-sensitive GPIO caused the wake up.

Wrapping Up

In this article we’ve shown you how to wake up the ESP32 using the touch-sensitive GPIOs. When touch is detected on a specified GPIO, the ESP32 wakes up and runs a callback function. After that, it goes back to sleep.

You can learn more about deep sleep with the ESP32 with our complete guide: ESP32 Deep Sleep with Arduino IDE and Wake Up Sources.

If you like ESP32, you may also like the following resources:

This is an excerpt from our course: Learn ESP32 with Arduino IDE. If you like ESP32 and you want to learn more, we recommend enrolling in Learn ESP32 with Arduino IDE course.



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 »

Enjoyed this project? Stay updated by subscribing our newsletter!

15 thoughts on “ESP32 Touch Wake Up from Deep Sleep”

      • thank you very much Sara I get Guru Meditation Error: Core 1 panic’ed (Coprocessor exception)
        instead of the function, why does this happen?

        Reply
        • Hi David.
          It depends on the code you’re trying to run.
          I think to avoid those kind of errors, you should add your code before the esp_deep_sleep_start(); function instead of putting it inside the callback function.
          Regards,
          Sara

          Reply
          • Oh I will make that im making a temperature sensor and the code is a simple :
            Serial.begin(115200);
            sensors.begin(); //Se inicia el sensor
            sensors.requestTemperatures(); //Se envía el comando para leer la temperatura
            float temp= sensors.getTempCByIndex(0); //Se obtiene la temperatura en ºC
            Serial.print(“Temperatura= “);
            Serial.print(temp);
            Serial.println(” C”);

          • I think it worked, not sure how to tell if its really sleeping but it displayed the temperature 🙂 thank you so much!

  1. This is nice Sara (I presume), thanks!

    Have you (or anyone) had any testing with the current draw to see what the deep sleep actually pulls?
    I’ve read as low as 10uA, but curious how that looks with the touch sensor enabled.

    Reply
  2. Hi Sara
    Thanks for all theses informations.
    I’ve a problem when I use touch pins with interrupts with an ESP32 TTGO :
    as soon as i touch a pin the ESP re-starts like a boot.
    Do you know this disorder?

    Reply
  3. hi
    can we use esp32 as a touch key ?
    place a pad on pcb and then put a glass (3mm) on it and then touch the area above pad and sense the touch .
    Is it possible ?

    Reply
  4. Hi
    The Sketch work on ESP32 S2 bat not on ESP32 S3
    After going sleep it wake up instantly witch error:

    Boot number: 2
    Wakeup caused by touchpad
    E (1021) TOUCH_SENSOR: touch_pad_get_wakeup_status(222): Touch channel error

    assert failed: esp_sleep_get_touchpad_wakeup_status sleep_modes.c:931 (ret == ESP_OK && “wakeup reason is RTC_TOUCH_TRIG_EN but SENS_TOUCH_MEAS_EN is zero”)

    Wy thir error?

    Reply

Leave a Reply to Gerstl Reinhold Cancel reply

Download Our Free eBooks and Resources

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