Skip to content

Add touch sleep wakeup API #7439

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Nov 9, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions cores/esp32/esp32-hal-touch.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ static touch_value_t __touchRead(uint8_t pin)
{
int8_t pad = digitalPinToTouchChannel(pin);
if(pad < 0){
log_e(" No touch pad on selected pin!");
return 0;
}

Expand All @@ -202,6 +203,7 @@ static void __touchConfigInterrupt(uint8_t pin, void (*userFunc)(void), void *Ar
{
int8_t pad = digitalPinToTouchChannel(pin);
if(pad < 0){
log_e(" No touch pad on selected pin!");
return;
}

Expand Down Expand Up @@ -264,6 +266,27 @@ bool touchInterruptGetLastStatus(uint8_t pin) {
}
#endif

void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold)
{
int8_t pad = digitalPinToTouchChannel(pin);
if(pad < 0){
log_e(" No touch pad on selected pin!");
return;
}
__touchInit();
__touchChannelInit(pad);

#if SOC_TOUCH_VERSION_1 // Only for ESP32 SoC
touch_pad_set_thresh(pad, threshold);

#elif SOC_TOUCH_VERSION_2
touch_pad_sleep_channel_enable(pad, true);
touch_pad_sleep_set_threshold(pad, threshold);

#endif
esp_sleep_enable_touchpad_wakeup();
}

extern touch_value_t touchRead(uint8_t) __attribute__ ((weak, alias("__touchRead")));
extern void touchAttachInterrupt(uint8_t, voidFuncPtr, touch_value_t) __attribute__ ((weak, alias("__touchAttachInterrupt")));
extern void touchAttachInterruptArg(uint8_t, voidArgFuncPtr, void *, touch_value_t) __attribute__ ((weak, alias("__touchAttachArgsInterrupt")));
Expand Down
5 changes: 5 additions & 0 deletions cores/esp32/esp32-hal-touch.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ void touchInterruptSetThresholdDirection(bool mustbeLower);
bool touchInterruptGetLastStatus(uint8_t pin);
#endif

/*
* Setup touch pad wake up from deep sleep with given threshold.
**/
void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold);

#endif // SOC_TOUCH_SENSOR_NUM > 0

#ifdef __cplusplus
Expand Down
12 changes: 12 additions & 0 deletions docs/source/api/touch.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ This function is used to detach interrupt from the touch pad.

* ``pin`` GPIO TOUCH pad pin.

touchSleepWakeUpEnable
^^^^^^^^^^^^^^^^^^^^^^

This function is used to setup touch pad as the wake up source from the deep sleep.

.. code-block:: arduino

void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold);

* ``pin`` GPIO TOUCH pad pin
* ``threshold`` Sets the threshold when to wake up

TOUCH API specific for ESP32 chip (TOUCH_V1)
********************************************

Expand Down
60 changes: 35 additions & 25 deletions libraries/ESP32/examples/DeepSleep/TouchWakeUp/TouchWakeUp.ino
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ Author:
Pranav Cherukupalli <[email protected]>
*/

#define Threshold 40 /* Greater the value, more the sensitivity */
#if CONFIG_IDF_TARGET_ESP32
#define THRESHOLD 40 /* Greater the value, more the sensitivity */
#elif CONFIG_IDF_TARGET_ESP32S2
#define THRESHOLD 30000 /* Lower the value, more the sensitivity */
#else //CONFIG_IDF_TARGET_ESP32S3 + default for other chips (to be adjusted) */
#define THRESHOLD 80000 /* Lower the value, more the sensitivity */
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tested it and it works better with this setup:

ESP32 -> Threshold = 40
S2/S3 -> Threshold = 1000

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For ESP32 we do have threshold 40.
But for S2/S3 it cannot be that small. Normal reading is higher that this value.
For S2 if the pad is touched, reading from touchRead is above 45k. For S3 its above 95k

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this is actually the delta, not the reading value itself.
It worked better (faster when touching the S2/S3 pad) when I changed it to 1,000
You can try it to check it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tested that a bit now, and managed to change it to 5000. That worked the best for me.
The 1000 was too much sensitive. I have attached the Dupont cable to the pin and it triggered even if I touched the rubber part of the cable, not the wire.
The 5000 triggers immediately I touch the wire :)


RTC_DATA_ATTR int bootCount = 0;
touch_pad_t touchPin;
Expand Down Expand Up @@ -42,24 +48,31 @@ has been awaken from sleep
void print_wakeup_touchpad(){
touchPin = esp_sleep_get_touchpad_wakeup_status();

switch(touchPin)
{
case 0 : Serial.println("Touch detected on GPIO 4"); break;
case 1 : Serial.println("Touch detected on GPIO 0"); break;
case 2 : Serial.println("Touch detected on GPIO 2"); break;
case 3 : Serial.println("Touch detected on GPIO 15"); break;
case 4 : Serial.println("Touch detected on GPIO 13"); break;
case 5 : Serial.println("Touch detected on GPIO 12"); break;
case 6 : Serial.println("Touch detected on GPIO 14"); break;
case 7 : Serial.println("Touch detected on GPIO 27"); break;
case 8 : Serial.println("Touch detected on GPIO 33"); break;
case 9 : Serial.println("Touch detected on GPIO 32"); break;
default : Serial.println("Wakeup not by touchpad"); break;
}
}

void callback(){
//placeholder callback function
#if CONFIG_IDF_TARGET_ESP32
switch(touchPin)
{
case 0 : Serial.println("Touch detected on GPIO 4"); break;
case 1 : Serial.println("Touch detected on GPIO 0"); break;
case 2 : Serial.println("Touch detected on GPIO 2"); break;
case 3 : Serial.println("Touch detected on GPIO 15"); break;
case 4 : Serial.println("Touch detected on GPIO 13"); break;
case 5 : Serial.println("Touch detected on GPIO 12"); break;
case 6 : Serial.println("Touch detected on GPIO 14"); break;
case 7 : Serial.println("Touch detected on GPIO 27"); break;
case 8 : Serial.println("Touch detected on GPIO 33"); break;
case 9 : Serial.println("Touch detected on GPIO 32"); break;
default : Serial.println("Wakeup not by touchpad"); break;
}
#else
if(touchPin < TOUCH_PAD_MAX)
{
Serial.printf("Touch detected on GPIO %d\n", touchPin);
}
else
{
Serial.println("Wakeup not by touchpad");
}
#endif
}

void setup(){
Expand All @@ -74,11 +87,8 @@ void setup(){
print_wakeup_reason();
print_wakeup_touchpad();

//Setup interrupt on Touch Pad 3 (GPIO15)
touchAttachInterrupt(T3, callback, Threshold);

//Configure Touchpad as wakeup source
esp_sleep_enable_touchpad_wakeup();
//Setup sleep wakeup on Touch Pad 3 (GPIO15 for ESP32) / (GPIO3 for ESP32-S2 and S3)
touchSleepWakeUpEnable(T3,THRESHOLD);
Copy link
Collaborator

@SuGlider SuGlider Nov 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tested it adding 2 touch pin to the sketch:

touchSleepWakeUpEnable(T2,THRESHOLD);
touchSleepWakeUpEnable(T7,THRESHOLD);

ESP32 wakes up with both and reports the right pin.
S2/S3 only wakes up with the last Touch Pad used in touchSleepWakeUpEnable(), in the example above, it means the the SoC only wakes up when touching GPIO7.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to add more pins for wakeup to the example?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe... when it is an ESP32 only. Just to demonstrate it?!
Also, maybe, add commentaries about the limitation for the S2/S3 in the sketch?
Just a few suggestions.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added both :)

  • Demontration for ESP32
  • Comment in header about limitation


//Go to sleep now
Serial.println("Going to sleep now");
Expand All @@ -88,4 +98,4 @@ void setup(){

void loop(){
//This will never be reached
}
}