What I want to do: I have 7 touch buttons on my board (ESP32 TTGO T-Display) and I want to attach interrupts to everyone, calling the same function. In this function I would like to use touch_pad_get_status() or other to get which button was touched. Then a switch case would do the rest.

What I'm facing: This code

  Serial.print("Button ");
  uint32_t touch = touch_pad_get_status();

always returns 0, no matter what.

What I've tried: Including this part of code to the setup

  touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); //tried the SW MODE too

But nothing seem to work. I don't want to make 7 different functions...

Thanks in advance.

  • have you tried the example code that is included with the library?
    – jsotola
    Feb 9, 2021 at 19:08
  • @jsotola yes, but none uses this function. There was one example that was similar to this application, but it implemented one function for each button :( Feb 9, 2021 at 19:35
  • See: docs.espressif.com/projects/esp-idf/en/latest/esp32/… See part 'Touch Detection' and 'Touch Triggered Interrupts'. Feb 9, 2021 at 20:22
  • @MichelKeijzers You're saying the touchAttachInterrupt(...) cannot be used in this scenario? Also I don't know what a intr_handler_t is, there isn't any example online. Feb 9, 2021 at 20:52
  • 1
    Thank you all, I'll post an answer to my own question as now I have solved this problem. Feb 9, 2021 at 21:49

1 Answer 1


As pointed out from people in the comments, things need to be different. If you use the function touchAttachInterrupt, things are a bit simpler. The example that comes with the ESP32 library is enough to make you understand.

If you want to do what I did, this is how:

  touch_pad_config(TOUCH_PAD_GPIO2_CHANNEL, 500);
  touch_pad_config(TOUCH_PAD_GPIO15_CHANNEL, 500);
  touch_pad_config(TOUCH_PAD_GPIO13_CHANNEL, 500);
  touch_pad_isr_register(TouchButton, NULL);

Put this code in the setup(). Of course needs the init(), but also needs to be set to timer mode, or otherwise you're going to need to start() probably. The config() is to configure the pin as an interrupt. I've set 500 in the threshold because the readings of touch_pad_read() told me it went from 800 untouched to 50 touched, so the midterm I chose 500. isr_register is the function that tells to call TouchButton(), with NULL as argument to it.

void TouchButton(void *arg)
  uint32_t touch = touch_pad_get_status();
  Serial.print("Button ");

This is the declaration of the callback function I've done. It should be noted that clear_status() should be called as soon as possible after the get_status(), preventing the system from panicking (that's the name). You'll also see in the serial monitor that each button represents a power of 2. That's because the get_status() returns the pin mask in binary. So just do something similar to this

for (int i = 0; i < TOUCH_PAD_MAX; i++) {
    if ((pad_intr >> i) & 0x01) {
        s_pad_activated[i] = true;

and you'll get a vector of which one was pressed.

  • Upvoted for the detailed answer and helping others. Feb 9, 2021 at 23:30
  • And one give you a little nudge over the comment everywhere threshold sooner rather than later. In a few days you'll be able to mark your own answer as accepted.
    – timemage
    Feb 10, 2021 at 0:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.