From c8f48168b4893540b248f75d04cb37ffd9484545 Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Sun, 18 Feb 2024 15:52:36 +0100 Subject: [PATCH 01/10] fixed touch buttons for ESP32 S2 and S3 touch is implemented differently on S2 and S3, these changes make touch buttons work on S2 and S3 --- wled00/button.cpp | 27 +++++++++++++++++++++++---- wled00/cfg.cpp | 13 +++++++++++-- wled00/fcn_declare.h | 1 + 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/wled00/button.cpp b/wled00/button.cpp index 29cb0abebf..bf093a2071 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -99,11 +99,21 @@ bool isButtonPressed(uint8_t i) case BTN_TYPE_TOUCH: case BTN_TYPE_TOUCH_SWITCH: #if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) - if (digitalPinToTouchChannel(btnPin[i]) >= 0 && touchRead(pin) <= touchThreshold) return true; + #ifdef SOC_TOUCH_VERSION_2 //ESP32 S2 and S3 provide a function to check touch state (state is updated in interrupt) + if (touchInterruptGetLastStatus(pin)) + { + return true; + } + #else + if (digitalPinToTouchChannel(btnPin[i]) >= 0 && touchRead(pin) <= touchThreshold) + { + return true; + } + #endif #endif - break; - } - return false; + break; + } + return false; } void handleSwitch(uint8_t b) @@ -406,3 +416,12 @@ void handleIO() offMode = true; } } + +void IRAM_ATTR touchButtonISR() +{ + +#if defined SOC_TOUCH_VERSION_1 //ESP32 original + touchInterruptSetThresholdDirection(flase); //todo: need to flip direction, for that proably need to read current state or something. +#endif + // For S2 and S3: nothing to do, ISR is just used to update registers of HAL driver +} \ No newline at end of file diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 449182fe74..5b80326679 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -228,6 +228,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { // read multiple button configuration JsonObject btn_obj = hw["btn"]; + CJSON(touchThreshold, btn_obj[F("tt")]); bool pull = btn_obj[F("pull")] | (!disablePullUp); // if true, pullup is enabled disablePullUp = !pull; JsonArray hw_btn_ins = btn_obj["ins"]; @@ -252,8 +253,16 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { btnPin[s] = -1; pinManager.deallocatePin(pin,PinOwner::Button); } + //if touch pin, enable the touch interrupt on ESP32 S2 & S3 + #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a fucntion to check touch state but need to attach an interrupt to do so + else if ((buttonType[s] == BTN_TYPE_TOUCH || buttonType[s] == BTN_TYPE_TOUCH_SWITCH)) + { + touchAttachInterrupt(btnPin[s], touchButtonISR, touchThreshold<<2); //threshold on Touch V2 is much higher (TODO: may need shift by 3 if very noisy) + } + #endif + else - #endif + #endif { if (disablePullUp) { pinMode(btnPin[s], INPUT); @@ -299,7 +308,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { } } } - CJSON(touchThreshold,btn_obj[F("tt")]); + CJSON(buttonPublishMqtt,btn_obj["mqtt"]); int hw_ir_pin = hw["ir"]["pin"] | -2; // 4 diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 20ac21129d..9b032d0313 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -20,6 +20,7 @@ void doublePressAction(uint8_t b=0); bool isButtonPressed(uint8_t b=0); void handleButton(); void handleIO(); +void IRAM_ATTR touchButtonISR(); //cfg.cpp bool deserializeConfig(JsonObject doc, bool fromFS = false); From 15526bd6e8c7a75ee1e36cf24ae397a674f63c56 Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Wed, 21 Feb 2024 18:38:34 +0100 Subject: [PATCH 02/10] some tuning for touch buttons on S2/S3 now better fits the default threshold value of 32 --- wled00/button.cpp | 17 ++++++++--------- wled00/cfg.cpp | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/wled00/button.cpp b/wled00/button.cpp index bf093a2071..05c6ad4bbc 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -100,10 +100,8 @@ bool isButtonPressed(uint8_t i) case BTN_TYPE_TOUCH_SWITCH: #if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) #ifdef SOC_TOUCH_VERSION_2 //ESP32 S2 and S3 provide a function to check touch state (state is updated in interrupt) - if (touchInterruptGetLastStatus(pin)) - { - return true; - } + if (touchInterruptGetLastStatus(pin)) + return true; #else if (digitalPinToTouchChannel(btnPin[i]) >= 0 && touchRead(pin) <= touchThreshold) { @@ -419,9 +417,10 @@ void handleIO() void IRAM_ATTR touchButtonISR() { - -#if defined SOC_TOUCH_VERSION_1 //ESP32 original - touchInterruptSetThresholdDirection(flase); //todo: need to flip direction, for that proably need to read current state or something. -#endif - // For S2 and S3: nothing to do, ISR is just used to update registers of HAL driver + // used for ESP32 S2 and S3: nothing to do, ISR is just used to update registers of HAL driver + // asm volatile("nop" ::); //prevent compiler to remove this function (TODO: is this really needed? probably not) + + // #if defined SOC_TOUCH_VERSION_1 //ESP32 original -> unused + // touchInterruptSetThresholdDirection(false); //todo: need to flip direction, for that proably need to read current state or something. + // #endif } \ No newline at end of file diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 5b80326679..905566bf20 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -257,7 +257,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a fucntion to check touch state but need to attach an interrupt to do so else if ((buttonType[s] == BTN_TYPE_TOUCH || buttonType[s] == BTN_TYPE_TOUCH_SWITCH)) { - touchAttachInterrupt(btnPin[s], touchButtonISR, touchThreshold<<2); //threshold on Touch V2 is much higher (TODO: may need shift by 3 if very noisy) + touchAttachInterrupt(btnPin[s], touchButtonISR, touchThreshold<<4); //threshold on Touch V2 is much higher (1500 is a value given by Espressif example) } #endif From 5c09ee29db4b31110e8750a07c2fbcd0cb62c8fa Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Mon, 4 Mar 2024 14:42:50 +0100 Subject: [PATCH 03/10] removed notes --- wled00/button.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/wled00/button.cpp b/wled00/button.cpp index 05c6ad4bbc..e3bd478825 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -418,9 +418,4 @@ void handleIO() void IRAM_ATTR touchButtonISR() { // used for ESP32 S2 and S3: nothing to do, ISR is just used to update registers of HAL driver - // asm volatile("nop" ::); //prevent compiler to remove this function (TODO: is this really needed? probably not) - - // #if defined SOC_TOUCH_VERSION_1 //ESP32 original -> unused - // touchInterruptSetThresholdDirection(false); //todo: need to flip direction, for that proably need to read current state or something. - // #endif } \ No newline at end of file From 509675fe6607a35243b478ab05ceb6e1ccad292f Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Sat, 9 Mar 2024 16:03:01 +0100 Subject: [PATCH 04/10] added touch interrupt activation to set.cpp for S2/S3 --- wled00/set.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/wled00/set.cpp b/wled00/set.cpp index 7137e0cd81..70e7d04706 100755 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -252,15 +252,24 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) btnPin[i] = -1; pinManager.deallocatePin(hw_btn_pin,PinOwner::Button); } - else if ((buttonType[i] == BTN_TYPE_TOUCH || buttonType[i] == BTN_TYPE_TOUCH_SWITCH) && digitalPinToTouchChannel(btnPin[i]) < 0) + else if ((buttonType[i] == BTN_TYPE_TOUCH || buttonType[i] == BTN_TYPE_TOUCH_SWITCH)) { - // not a touch pin - DEBUG_PRINTF_P(PSTR("PIN ALLOC error: GPIO%d for touch button #%d is not an touch pin!\n"), btnPin[i], i); - btnPin[i] = -1; - pinManager.deallocatePin(hw_btn_pin,PinOwner::Button); + if (digitalPinToTouchChannel(btnPin[i]) < 0) + { + // not a touch pin + DEBUG_PRINTF_P(PSTR("PIN ALLOC error: GPIO%d for touch button #%d is not an touch pin!\n"), btnPin[i], i); + btnPin[i] = -1; + pinManager.deallocatePin(hw_btn_pin,PinOwner::Button); + } + #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a fucntion to check touch state but need to attach an interrupt to do so + else + { + touchAttachInterrupt(btnPin[i], touchButtonISR, touchThreshold << 4); // threshold on Touch V2 is much higher (1500 is a value given by Espressif example) + } + #endif } else - #endif +#endif { if (disablePullUp) { pinMode(btnPin[i], INPUT); From 0453a5fb3ded8851011cbe65db747b2118555f43 Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Sun, 10 Mar 2024 16:54:25 +0100 Subject: [PATCH 05/10] added interrupt detach to cfg.cpp --- wled00/cfg.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 905566bf20..e59a342c56 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -235,6 +235,9 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { if (!hw_btn_ins.isNull()) { for (uint8_t b = 0; b < WLED_MAX_BUTTONS; b++) { // deallocate existing button pins pinManager.deallocatePin(btnPin[b], PinOwner::Button); // does nothing if trying to deallocate a pin with PinOwner != Button + #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a fucntion to check touch state, detach any previous assignments + touchDetachInterrupt(btnPin[b]); + #endif } uint8_t s = 0; for (JsonObject btn : hw_btn_ins) { @@ -260,9 +263,8 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { touchAttachInterrupt(btnPin[s], touchButtonISR, touchThreshold<<4); //threshold on Touch V2 is much higher (1500 is a value given by Espressif example) } #endif - else - #endif + #endif { if (disablePullUp) { pinMode(btnPin[s], INPUT); From 0637c1c9d4524bfe8efa83fcd4622fcd89bb8ab8 Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Sun, 10 Mar 2024 19:44:27 +0100 Subject: [PATCH 06/10] bugfixes -added minimum threshold, had some crashes when setting threshold to zero before -moved interrupt detach to GPIO deallocation where it belongs -added check for touchbutton before detaching interrupt -moved thochThreshold readout up so it gets updated before passing it to the system call --- wled00/cfg.cpp | 5 +---- wled00/pin_manager.cpp | 5 +++++ wled00/set.cpp | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index e59a342c56..91689aab4f 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -235,9 +235,6 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { if (!hw_btn_ins.isNull()) { for (uint8_t b = 0; b < WLED_MAX_BUTTONS; b++) { // deallocate existing button pins pinManager.deallocatePin(btnPin[b], PinOwner::Button); // does nothing if trying to deallocate a pin with PinOwner != Button - #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a fucntion to check touch state, detach any previous assignments - touchDetachInterrupt(btnPin[b]); - #endif } uint8_t s = 0; for (JsonObject btn : hw_btn_ins) { @@ -260,7 +257,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a fucntion to check touch state but need to attach an interrupt to do so else if ((buttonType[s] == BTN_TYPE_TOUCH || buttonType[s] == BTN_TYPE_TOUCH_SWITCH)) { - touchAttachInterrupt(btnPin[s], touchButtonISR, touchThreshold<<4); //threshold on Touch V2 is much higher (1500 is a value given by Espressif example) + touchAttachInterrupt(btnPin[s], touchButtonISR, 256 + (touchThreshold << 4)); // threshold on Touch V2 is much higher (1500 is a value given by Espressif example, I measured changes of over 5000) } #endif else diff --git a/wled00/pin_manager.cpp b/wled00/pin_manager.cpp index 044dc6c92e..e80583464d 100644 --- a/wled00/pin_manager.cpp +++ b/wled00/pin_manager.cpp @@ -32,6 +32,11 @@ bool PinManagerClass::deallocatePin(byte gpio, PinOwner tag) return false; } + #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a fucntion to check touch state, detach any previous assignments + if (digitalPinToTouchChannel(gpio) >= 0) //if touch capable pin + touchDetachInterrupt(gpio); + #endif + byte by = gpio >> 3; byte bi = gpio - 8*by; bitWrite(pinAlloc[by], bi, false); diff --git a/wled00/set.cpp b/wled00/set.cpp index 70e7d04706..8a461fbc8b 100755 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -236,6 +236,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) rlyMde = (bool)request->hasArg(F("RM")); disablePullUp = (bool)request->hasArg(F("IP")); + touchThreshold = request->arg(F("TT")).toInt(); for (uint8_t i=0; i10) char be[4] = "BE"; be[2] = (i<10?48:55)+i; be[3] = 0; // button type (use A,B,C,... if WLED_MAX_BUTTONS>10) @@ -264,7 +265,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a fucntion to check touch state but need to attach an interrupt to do so else { - touchAttachInterrupt(btnPin[i], touchButtonISR, touchThreshold << 4); // threshold on Touch V2 is much higher (1500 is a value given by Espressif example) + touchAttachInterrupt(btnPin[i], touchButtonISR, 256 + (touchThreshold << 4)); // threshold on Touch V2 is much higher (1500 is a value given by Espressif example, I measured changes of over 5000) } #endif } @@ -286,7 +287,6 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) buttonType[i] = BTN_TYPE_NONE; } } - touchThreshold = request->arg(F("TT")).toInt(); briS = request->arg(F("CA")).toInt(); From d3a97f106222d208011dd84f3aa5781579afd20e Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Sun, 7 Apr 2024 13:49:17 +0200 Subject: [PATCH 07/10] removed detachinterrupt from pin manager, added it to set.cpp instead --- wled00/pin_manager.cpp | 5 ----- wled00/set.cpp | 6 +++++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/wled00/pin_manager.cpp b/wled00/pin_manager.cpp index e80583464d..044dc6c92e 100644 --- a/wled00/pin_manager.cpp +++ b/wled00/pin_manager.cpp @@ -32,11 +32,6 @@ bool PinManagerClass::deallocatePin(byte gpio, PinOwner tag) return false; } - #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a fucntion to check touch state, detach any previous assignments - if (digitalPinToTouchChannel(gpio) >= 0) //if touch capable pin - touchDetachInterrupt(gpio); - #endif - byte by = gpio >> 3; byte bi = gpio - 8*by; bitWrite(pinAlloc[by], bi, false); diff --git a/wled00/set.cpp b/wled00/set.cpp index 8a461fbc8b..0920588fed 100755 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -108,6 +108,10 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) for (uint8_t s=0; s=0 && pinManager.isPinAllocated(btnPin[s], PinOwner::Button)) { pinManager.deallocatePin(btnPin[s], PinOwner::Button); + #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a function to check touch state, detach interrupt + if (digitalPinToTouchChannel(btnPin[i]) >= 0) // if touch capable pin + touchDetachInterrupt(btnPin[i]); // if not assigned previously, this will do nothing + #endif } } @@ -270,7 +274,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) #endif } else -#endif + #endif { if (disablePullUp) { pinMode(btnPin[i], INPUT); From 954f26308b66e19f4a1ad11fc5772b9c79f1e508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Kristan?= Date: Sun, 7 Apr 2024 22:12:01 +0200 Subject: [PATCH 08/10] Update button.cpp Indentation fix --- wled00/button.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/wled00/button.cpp b/wled00/button.cpp index e3bd478825..06683e17a5 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -100,18 +100,14 @@ bool isButtonPressed(uint8_t i) case BTN_TYPE_TOUCH_SWITCH: #if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) #ifdef SOC_TOUCH_VERSION_2 //ESP32 S2 and S3 provide a function to check touch state (state is updated in interrupt) - if (touchInterruptGetLastStatus(pin)) - return true; + if (touchInterruptGetLastStatus(pin)) return true; #else - if (digitalPinToTouchChannel(btnPin[i]) >= 0 && touchRead(pin) <= touchThreshold) - { - return true; - } + if (digitalPinToTouchChannel(btnPin[i]) >= 0 && touchRead(pin) <= touchThreshold) return true; #endif #endif break; - } - return false; + } + return false; } void handleSwitch(uint8_t b) @@ -418,4 +414,4 @@ void handleIO() void IRAM_ATTR touchButtonISR() { // used for ESP32 S2 and S3: nothing to do, ISR is just used to update registers of HAL driver -} \ No newline at end of file +} From d1d54ce9c8aacf93541dba34b457a947eed5e625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Kristan?= Date: Sun, 7 Apr 2024 22:15:58 +0200 Subject: [PATCH 09/10] Update cfg.cpp Indentation fix --- wled00/cfg.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 91689aab4f..9d36134f08 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -255,10 +255,10 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { } //if touch pin, enable the touch interrupt on ESP32 S2 & S3 #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a fucntion to check touch state but need to attach an interrupt to do so - else if ((buttonType[s] == BTN_TYPE_TOUCH || buttonType[s] == BTN_TYPE_TOUCH_SWITCH)) - { - touchAttachInterrupt(btnPin[s], touchButtonISR, 256 + (touchThreshold << 4)); // threshold on Touch V2 is much higher (1500 is a value given by Espressif example, I measured changes of over 5000) - } + if ((buttonType[s] == BTN_TYPE_TOUCH || buttonType[s] == BTN_TYPE_TOUCH_SWITCH)) + { + touchAttachInterrupt(btnPin[s], touchButtonISR, 256 + (touchThreshold << 4)); // threshold on Touch V2 is much higher (1500 is a value given by Espressif example, I measured changes of over 5000) + } #endif else #endif From b72f3baab7ecf74d56c7caacb1aa177b3ad72140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Kristan?= Date: Sun, 7 Apr 2024 22:21:41 +0200 Subject: [PATCH 10/10] Update set.cpp Compile fix --- wled00/set.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wled00/set.cpp b/wled00/set.cpp index 0920588fed..0b84160c95 100755 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -108,10 +108,10 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) for (uint8_t s=0; s=0 && pinManager.isPinAllocated(btnPin[s], PinOwner::Button)) { pinManager.deallocatePin(btnPin[s], PinOwner::Button); - #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a function to check touch state, detach interrupt - if (digitalPinToTouchChannel(btnPin[i]) >= 0) // if touch capable pin - touchDetachInterrupt(btnPin[i]); // if not assigned previously, this will do nothing - #endif + #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a function to check touch state, detach interrupt + if (digitalPinToTouchChannel(btnPin[s]) >= 0) // if touch capable pin + touchDetachInterrupt(btnPin[s]); // if not assigned previously, this will do nothing + #endif } }