BLYNK
HOME       📲 GETTING STARTED       📗 DOCS       ❓HELP CENTER       👉 SKETCH BUILDER

Crashing ESP32 - Touch Sensors

I am currently working on a quite complicated project which involves controlling a pump and solenoid valve with 5 different float switches. These together will be used to drain 1/8 of an aquarium and refill it with fresh water. Now, this is my problem, I decided to use the integrated touch sensors in the ESP32 to be able to control the system from either the Blynk app or a small PCB touch Panel. I tried the ESP32`s touch sensor without BLYNK and they worked but when I tried to integrate Blynk I get frequent crashes

This is an example:

21:10:26.619 -> Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1)
21:10:26.723 -> Core 1 register dump:
21:10:26.723 -> PC      : 0x4008b92e  PS      : 0x00060d34  A0      : 0x8008aa7b  A1      : 0x3ffbdf90  
21:10:26.828 -> A2      : 0x3ffcb3ec  A3      : 0x3ffb8074  A4      : 0x00000001  A5      : 0x00000001  
21:10:26.933 -> A6      : 0x00060d23  A7      : 0x00000000  A8      : 0x3ffb8074  A9      : 0x3ffb8074  
21:10:27.002 -> A10     : 0x00000018  A11     : 0x00000018  A12     : 0x00000001  A13     : 0x00000001  
21:10:27.107 -> A14     : 0x00060d21  A15     : 0x00000000  SAR     : 0x00000019  EXCCAUSE: 0x00000006  
21:10:27.211 -> EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff  
21:10:27.281 -> Core 1 was running in ISR context:
21:10:27.350 -> EPC1    : 0x40089f02  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x4008b92e
21:10:27.419 -> 
21:10:27.419 -> Backtrace: 0x4008b92e:0x3ffbdf90 0x4008aa78:0x3ffbdfb0 0x4008950b:0x3ffbdfd0 0x40101ad9:0x3ffbe010 0x400f0857:0x3ffbe030 0x40102011:0x3ffbe060 0x40102471:0x3ffbe080 0x400ef69e:0x3ffbe0c0 0x400f0159⸮

This occurs very randomly, sometimes when the ESP32 Connects to wifi and sometimes when using the touch inputs. Sometimes the ESP32 resets and does not display a crash.

I have attached the program I am using below. This is a very small part of the complete code because It would be very long to include here.

In this example, I am changing the message on the LCD Widget.

#define BLYNK_PRINT Serial

#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

int threshold = 10;

int notif = 0;
int lastnotif = 0;

WidgetLCD lcd(V13);

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "50107xxxxxxxxxxxxxxxxxxxxxxxxxxxxdcd1071a2";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "OnePlus";
char pass[] = "oneplus7pro";
void setup()
{
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass);

  touchAttachInterrupt(T4, FILL, threshold);
  touchAttachInterrupt(T5, DRAIN, threshold);
  touchAttachInterrupt(T0, AUTO, threshold);
  touchAttachInterrupt(T2, _OFF, threshold);
}

BLYNK_WRITE(V0) // Fill
{
  if (param.asInt() == 1)
  {
    FILL();
  }
}

BLYNK_WRITE(V1) // Drain
{
  if ( param.asInt() == 1 )
  {
    DRAIN();
  }
}

BLYNK_WRITE(V5) // Auto
{
  if ( param.asInt() == 1 )
  {
    AUTO();
  }
}

BLYNK_WRITE(V6) // Off
{
  if ((param.asInt() == 1))
  {
    _OFF();
   }
}

void FILL() {
  notification(1);
  Serial.println("FILL");
}

void DRAIN() {
  notification(2);
  Serial.println("DRAIN");
}

void _OFF() {
  notification(16);
  Serial.println("OFF");
}

void AUTO() {
  notification(8);
  Serial.println("AUTO");
}

void loop()
{
  Blynk.run();
}

void notification(int notif) {
 if (notif != lastnotif) {
    lcd.clear();
    BLYNK_LOG("Notif = %d", notif);
    switch (notif) {
      case 1: lcd.print(0, 0, "Draining");
        break;
      case 2: lcd.print(0, 0, "Drained");
        Blynk.notify("Drained");
        break;
      case 3: lcd.print(0, 0, "Draining");
        lcd.print(0, 1, "Bucket Full");
        Blynk.notify("Bucket Full");
        break;
      case 4: lcd.print(0, 0, "Filling");
        break;
      case 5: lcd.print(0, 0, "Filled");
        Blynk.notify("Filled");
        break;
      case 6: lcd.print(0, 0, "Filling");
        lcd.print(0, 1, "Bucket Empty");
        Blynk.notify("Bucket Empty");
        break;
      case 7: lcd.print(0, 0, "Automatic");
        lcd.print(0, 1, "Draining");
        break;
      case 8: lcd.print(0, 0, "Automatic");
        lcd.print(0, 1, "Bucket Full");
        Blynk.notify("Bucket Full");
        break;
      case 9: lcd.print(0, 0, "Automatic");
        lcd.print(0, 1, "Drained");
        break;
      case 10: lcd.print(0, 0, "Automatic");
        lcd.print(0, 1, "Filling");
        break;
      case 11: lcd.print(0, 0, "Automatic");
        lcd.print(0, 1, "Bucket Empty");
        Blynk.notify("Bucket Empty");
        break;
      case 12: lcd.print(0, 0, "Done");
        Blynk.notify("Done");
        break;
      case 13: Blynk.notify("Water Detected, Operation Haulted");
        lcd.print(0, 0, "Water Detected, Operation Haulted");
        break;
      case 14:  Blynk.notify("Timeout 1hr Passed");
        lcd.print(0, 0, "Timeout 1hr Passed");
        break;
      case 15: lcd.print(0, 0, "Blynk Disconnected");
        Blynk.notify("Blynk Disconnected");
        break;
      case 16:lcd.clear();
        break;
      default:
        //lcd.clear();
        break;
    }
    lastnotif = notif;
  }
}

One other problem I also noticed is sometimes the ESP32 Hangs on Connecting to xxxWifi-Namexxxx on the Serial Monitor. The only way to get it to connect is to reset it until it connects successfully.

I think your interrupt service routine (ISR) creates problems (watchdog resets, etc…). Please research how to write a better ISR.
The code hereafter is just the some suggestion to fix the issues:
Pls pay attention to the volatile variables using inside ISRs, which must be very short. Then use a timer to check the flags set by ISRs.

#define BLYNK_PRINT Serial

#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

int threshold = 10;

int notif = 0;
int lastnotif = 0;

WidgetLCD lcd(V13);

BlynkTimer  timer;

#define TIME_TO_CHECK_REQUEST			2000

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "50107xxxxxxxxxxxxxxxxxxxxxxxxxxxxdcd1071a2";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "OnePlus";
char pass[] = "oneplus7pro";
void setup()
{
  // Debug console
  Serial.begin(9600);

  touchAttachInterrupt(T4, iFILL, threshold);
  touchAttachInterrupt(T5, iDRAIN, threshold);
  touchAttachInterrupt(T0, iAUTO, threshold);
  touchAttachInterrupt(T2, i_OFF, threshold);
  
  Blynk.begin(auth, ssid, pass);
  timer.setInterval(TIME_TO_CHECK_REQUEST, checkRequest);   
}

BLYNK_WRITE(V0) // Fill
{
  if (param.asInt() == 1)
  {
    FILL();
  }
}

BLYNK_WRITE(V1) // Drain
{
  if ( param.asInt() == 1 )
  {
    DRAIN();
  }
}

BLYNK_WRITE(V5) // Auto
{
  if ( param.asInt() == 1 )
  {
    AUTO();
  }
}

BLYNK_WRITE(V6) // Off
{
  if ((param.asInt() == 1))
  {
    _OFF();
   }
}

volatile boolean toFILL = false;

void iFILL() {
  toFILL = true;
}

volatile boolean toDRAIN = false;

void iDRAIN() {
  toDRAIN = true;
}

volatile boolean toOFF = false;

void i_OFF() {
	toOFF = true;
}

volatile boolean toAUTO = false;

void iAUTO() {
	toAUTO = true;
}

void checkRequest()
{
	if (toFILL)
	{
		toFILL = false;
		FILL();
	}
	
	if (toDRAIN)
	{
		toDRAIN = false;
		DRAIN();
	}

	if (toOFF)
	{
		toOFF = false;
		_OFF();
	}
	
	if (toAUTO)
	{
		toAUTO = false;
		AUTO();
	}
	
}

void FILL() {
  notification(1);
  Serial.println("FILL");
}

void DRAIN() {
  notification(2);
  Serial.println("DRAIN");
}

void _OFF() {
  notification(16);
  Serial.println("OFF");
}

void AUTO() {
  notification(8);
  Serial.println("AUTO");
}

void loop()
{
  Blynk.run();
  timer.run();
}

void notification(int notif) {
 if (notif != lastnotif) {
    lcd.clear();
    BLYNK_LOG("Notif = %d", notif);
    switch (notif) {
      case 1: lcd.print(0, 0, "Draining");
        break;
      case 2: lcd.print(0, 0, "Drained");
        Blynk.notify("Drained");
        break;
      case 3: lcd.print(0, 0, "Draining");
        lcd.print(0, 1, "Bucket Full");
        Blynk.notify("Bucket Full");
        break;
      case 4: lcd.print(0, 0, "Filling");
        break;
      case 5: lcd.print(0, 0, "Filled");
        Blynk.notify("Filled");
        break;
      case 6: lcd.print(0, 0, "Filling");
        lcd.print(0, 1, "Bucket Empty");
        Blynk.notify("Bucket Empty");
        break;
      case 7: lcd.print(0, 0, "Automatic");
        lcd.print(0, 1, "Draining");
        break;
      case 8: lcd.print(0, 0, "Automatic");
        lcd.print(0, 1, "Bucket Full");
        Blynk.notify("Bucket Full");
        break;
      case 9: lcd.print(0, 0, "Automatic");
        lcd.print(0, 1, "Drained");
        break;
      case 10: lcd.print(0, 0, "Automatic");
        lcd.print(0, 1, "Filling");
        break;
      case 11: lcd.print(0, 0, "Automatic");
        lcd.print(0, 1, "Bucket Empty");
        Blynk.notify("Bucket Empty");
        break;
      case 12: lcd.print(0, 0, "Done");
        Blynk.notify("Done");
        break;
      case 13: Blynk.notify("Water Detected, Operation Haulted");
        lcd.print(0, 0, "Water Detected, Operation Haulted");
        break;
      case 14:  Blynk.notify("Timeout 1hr Passed");
        lcd.print(0, 0, "Timeout 1hr Passed");
        break;
      case 15: lcd.print(0, 0, "Blynk Disconnected");
        Blynk.notify("Blynk Disconnected");
        break;
      case 16:lcd.clear();
        break;
      default:
        //lcd.clear();
        break;
    }
    lastnotif = notif;
  }
}

Thanks this worked flawlessly but I need to play around with the threshold value because at setting 8 I get false touch events. The touch pads are on a 1.5meter ribbon cable. Maybe that is the cause? Too much interference?