Multiple Touch Interrupt Issue

Queequack
Posts: 3
Joined: Wed Apr 15, 2020 9:19 am

Multiple Touch Interrupt Issue

Postby Queequack » Wed Apr 15, 2020 9:35 am

Hi,

I attached 2 wires to Touch-Inputs T0 and T3. The touch of T0 shall decrease a value, the touch of T3 shall increase a value. Sound simple! But: Every time I touch one wire and then the other, an interrupt is executed for both (not only for the one that has been touched!).
If I touch one wire multiple times (with defined delay of minimum 500ms), it works properly. E.g. for T3 the value is increased each time I touch the wire for T3. Same for T0 (decreases value).

The code seems to be correct. I also tested other Touch-Pins as well as different ESP32 DEVKIT V1 boards. The behaviour every time is the same. I used Arduino IDE and Visual Studio Code (with necessary Plugins...) to test it.

Code: Select all

int threshold = 60;
bool touchdetected0 = false;
bool touchdetected3 = false;
int value = 0;
volatile unsigned long sinceLastTouch0 = 0;
volatile unsigned long sinceLastTouch3 = 0;

void gotTouch0()
{
	if (millis() - sinceLastTouch0 < 500) return;
	sinceLastTouch0 = millis();
	//Serial.println("T3 to true");
	touchdetected0 = true;
}

void gotTouch3()
{
	if (millis() - sinceLastTouch3 < 500) return;
	sinceLastTouch3 = millis();
	//Serial.println("T3 to true");
	touchdetected3 = true;
}

void setup() 
{
	Serial.begin(115200);
	delay(1000);
	touchAttachInterrupt(T0, gotTouch0, threshold); // T0 = GPIO 4
	touchAttachInterrupt(T3, gotTouch3, threshold); // T3 = GPIO 15
	Serial.println("Ready... ");
}

void loop()
{
	if(touchdetected0)
	{
		//Serial.println("T0 to false");
		touchdetected0 = false;
		Serial.print("Touch 0 detected - Value: "); Serial.println(value=value-1);
	}
	if(touchdetected3)
	{
		//Serial.println("T3 to false");
		touchdetected3 = false;
		Serial.print("Touch 3 detected - Value: "); Serial.println(value=value+1);
	}
}

Queequack
Posts: 3
Joined: Wed Apr 15, 2020 9:19 am

Re: Multiple Touch Interrupt Issue

Postby Queequack » Wed Apr 15, 2020 1:36 pm

Hi, with a little help I found the solution. As compact as the code in the interrupt function is, it is not compact enough. When an interrupt occurs, nothing should happen except setting a flag.
The correct way is to compare the time since the last touch with a delay value within the loop() function.
In the code below the interrupt is executed on every touch (flag is set to true) This flag is queried in the loop() function. If it is true, it is first set to false again (the touch was pressed was finally detected). The time of the "successful" touch input is stored for the next comparison: sinceLastTouchT0 = millis();.
Only then does a swapped-out function query whether enough time has passed since the last touch: if (touchDelayComp(sinceLastTouchT0)). If the function returns false, the if-query is finished and nothing happens. However, if it returns true, the value "Value" is modified in this case.

Code: Select all

#include <Arduino.h>

const uint8_t threshold = 60;
bool touchedT0 = false; // Touch 0 ist GPIO4
bool touchedT3 = false; // Touch 0 ist GPI15

const long touchDelay = 350; //ms
int value = 0;

volatile unsigned long sinceLastTouchT0 = 0;
volatile unsigned long sinceLastTouchT3 = 0;

bool touchDelayComp(unsigned long);

void IRAM_ATTR T0wasActivated() { touchedT0 = true; }
void IRAM_ATTR T3wasActivated() { touchedT3 = true; }

void setup() {
  Serial.begin(115200);
  delay(1000);
  touchAttachInterrupt(T0, T0wasActivated, threshold);
  touchAttachInterrupt(T3, T3wasActivated, threshold);
  Serial.println("Ready...");
}

void loop() 
{
  if (touchedT0) 
  {
    touchedT0 = false;
    if (touchDelayComp(sinceLastTouchT0))
    {
      value = value - 1;
      Serial.print("T0: "); Serial.println(value);
      sinceLastTouchT0 = millis();
    }
  }

  if (touchedT3) 
  {
    touchedT3 = false;
    if (touchDelayComp(sinceLastTouchT3))
    {
      value = value + 1;
      Serial.print("T3: "); Serial.println(value);
      sinceLastTouchT3 = millis();
    }
  }
}

bool touchDelayComp(unsigned long lastTouch)
{
  if (millis() - lastTouch < touchDelay) return false;
  return true;
}

User avatar
fasani
Posts: 195
Joined: Wed Jan 30, 2019 12:00 pm
Location: Barcelona
Contact:

Re: Multiple Touch Interrupt Issue

Postby fasani » Fri Apr 17, 2020 5:46 am

Your findings look interesting. I found similar problem in the past using touch and I ended up using physical buttons :)
With this solution could you get touch working correctly for your 2 different actions?
epdiy collaborator | http://fasani.de Fan of Espressif MCUs and electronic design

Who is online

Users browsing this forum: No registered users and 126 guests