Detecting long Press and Short Press using touch sensor on ESP32 Dev Module by ESPRIIFF

I am trying to detect long press and short press using touch sensor on ESP32 Wroom 32E Pin2

I use this flag when press is detected:
void IRAM_ATTR touchInterruptHandler() { pressStartTime = millis(); ClickDetected = true; }

This in Setup:

  touchAttachInterrupt(TOUCH_PIN, touchInterruptHandler, 40);
  esp_sleep_enable_touchpad_wakeup();

  lastwake = millis();
  Serial.println("Setup Complete");

And this Funtion in loop to determine the type of press:

void loop{
if (ClickDetected){
  ClickDetected = false;
  lastDebounceTime = millis();
  handleTouch();
}}
void handleTouch() {
  unsigned long touchDuration = millis() - pressStartTime;

  Serial.print("Touch Duration: "); Serial.println(touchDuration);
  Serial.print("Millis: "); Serial.println(millis());
  Serial.print("PressStartTime: "); Serial.println(pressStartTime);
  pressStartTime = 0;
  
  if (touchDuration < LONG_TOUCH) {
    // Long touch detected
    //longTouchDetected = true;
    Serial.println("Short Touch Detected");
    ShortClick();
    // Perform actions for long touch
  } else if (touchDuration >= LONG_TOUCH){
    Serial.println("Long Press Detected");
    LongPress();
  }

But it detects short touch all the time and keeps switching to short touch functions every time and donot go to the longtouch. How can i accomplish longtouch when the finger is placed on the touch sensor for a prolonged period of time.

this measures how many mSec T0 is toutched

Edit: simplified code

// ESP32 - determine length of time touch T0 is touched

int threshold = 40;

volatile unsigned long touchTimer = 0;
// when T0 is touched note start time
void gotTouch1() {
  if (touchTimer == 0)
    touchTimer = millis();
}

void setup() {
  Serial.begin(115200);
  delay(1000);  // give me time to bring up serial monitor
  Serial.println("ESP32 Touch timer Interrupt Test");
  touchAttachInterrupt(T0, gotTouch1, threshold);  // GPIO4
}

void loop() {
  // check if T0 has been touched (touchTimer>0) 
  //   and then released (touchRead(T0) > threshold)
  if ((touchRead(T0) > threshold) && touchTimer > 0) {
    Serial.printf("Touch T0 detected for %ld mSec\n", millis() - touchTimer);
    touchTimer = 0;
  }
}

a run on an ESP32 gave

ESP32 Touch timer Interrupt Test
Touch T0 detected for 0 mSec
Touch T0 detected for 1944 mSec
Touch T0 detected for 0 mSec
Touch T0 detected for 2264 mSec
Touch T0 detected for 0 mSec
Touch T0 detected for 1758 mSec
Touch T0 detected for 0 mSec
Touch T0 detected for 1622 mSec
Touch T0 detected for 0 mSec
Touch T0 detected for 1942 mSec
Touch T0 detected for 0 mSec
Touch T0 detected for 1224 mSec
Touch T0 detected for 0 mSec
Touch T0 detected for 696 mSec
Touch T0 detected for 6487 mSec
Touch T0 detected for 0 mSec
Touch T0 detected for 1 mSec
Touch T0 detected for 8231 mSec

on initial touch tends to get a short touch time - could simply ignore such readings

That does get me the readings but keeps getting multiple outputs and false positives in every touch.

what type of touch panel are you using? you may need to tune threshold and timing

using Microchip 8-way keypad testing button 8 for tap or long touch
image

code ignores any spurious touch < 5mSec and a tap is < 200mSec touch

// ESP32 - determine length of time touch T0 is touched
//   using Microchip 8-way keypad testing button 8 for tap or long touch 

int threshold = 40;

volatile unsigned long touchTimer = 0;
// when T0 is touched note start time
void gotTouch1() {
  if (touchTimer == 0)
    touchTimer = millis();
}

void setup() {
  Serial.begin(115200);
  delay(1000);  // give me time to bring up serial monitor
  Serial.println("ESP32 Touch timer Interrupt Test");
  touchAttachInterrupt(T0, gotTouch1, threshold);  // GPIO4
}

void loop() {
  // check if T0 has been touched (touchTimer>0)
  //   and then released (touchRead(T0) > threshold)
  if ((touchRead(T0) > threshold) && touchTimer > 0) {
    unsigned long timer1 = millis() - touchTimer;
    if (timer1 > 5) {       // ignore any spurious touch
      if (timer1 < 200)     // touch less than 200mSec is a tap
        Serial.printf("Touch T0 detected for %3ld mSec TAP!\n", millis() - touchTimer);
      else
        Serial.printf("Touch T0 detected for %3ld mSec LONG toutch!\n", millis() - touchTimer);
    }
    touchTimer = 0;
  }
}

test run

ESP32 Touch timer Interrupt Test
Touch T0 detected for  31 mSec TAP!
Touch T0 detected for  28 mSec TAP!
Touch T0 detected for  86 mSec TAP!
Touch T0 detected for 138 mSec TAP!
Touch T0 detected for  59 mSec TAP!
Touch T0 detected for  82 mSec TAP!
Touch T0 detected for  57 mSec TAP!
Touch T0 detected for 902 mSec LONG toutch!
Touch T0 detected for 849 mSec LONG toutch!
Touch T0 detected for 623 mSec LONG toutch!
Touch T0 detected for 543 mSec LONG toutch!
Touch T0 detected for 131 mSec TAP!
Touch T0 detected for  53 mSec TAP!
Touch T0 detected for  53 mSec TAP!
Touch T0 detected for  33 mSec TAP!
Touch T0 detected for  60 mSec TAP!
Touch T0 detected for 777 mSec LONG toutch!

Works like a Charm now. Thanks for the Help.
I am actually using the onboard Touch Pins of ESP32 to toggle changes in OLED.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.