Created
January 8, 2022 17:43
-
-
Save darianbjohnson/268bff40ea72642dd2e05123ec5b8c40 to your computer and use it in GitHub Desktop.
This is the function I use for wake-up and interrupts on the NEWT (which uses an ESP32-S2) https://www.crowdsupply.com/phambili/newt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define TOUCH_CHANGE_CONFIG 0 | |
//these defines are specific to the NEWT breakout board = https://www.crowdsupply.com/phambili/newt | |
#define BUTTON_A 14 | |
#define BUTTON_A_NAME GPIO_NUM_14 | |
#define BUTTON_A_TOUCH_NAME TOUCH_PAD_NUM14 | |
#define BUTTON_B 13 | |
#define BUTTON_B_NAME GPIO_NUM_13 | |
#define BUTTON_B_TOUCH_NAME TOUCH_PAD_NUM13 | |
#define BUTTON_C 12 | |
#define BUTTON_C_NAME GPIO_NUM_12 | |
#define BUTTON_C_TOUCH_NAME TOUCH_PAD_NUM12 | |
#define BUTTON_D 11 | |
#define BUTTON_D_NAME GPIO_NUM_11 | |
#define BUTTON_D_TOUCH_NAME TOUCH_PAD_NUM11 | |
#define BUTTON_E 10 | |
#define BUTTON_E_NAME GPIO_NUM_10 | |
#define BUTTON_E_TOUCH_NAME TOUCH_PAD_NUM10 | |
#define BUTTON_F 9 | |
#define BUTTON_F_NAME GPIO_NUM_9 | |
#define BUTTON_F_TOUCH_NAME TOUCH_PAD_NUM9 | |
#define PAD_ONE 5 | |
#define PAD_ONE_NAME GPIO_NUM_5 | |
#define PAD_ONE_TOUCH_NAME TOUCH_PAD_NUM5 | |
#define PAD_TWO 6 | |
#define PAD_TWO_NAME GPIO_NUM_6 | |
#define PAD_TWO_TOUCH_NAME TOUCH_PAD_NUM6 | |
#define PAD_THREE 7 | |
#define PAD_THREE_NAME GPIO_NUM_7 | |
#define PAD_THREE_TOUCH_NAME TOUCH_PAD_NUM7 | |
#define PAD_FOUR 8 | |
#define PAD_FOUR_NAME GPIO_NUM_8 | |
#define PAD_FOUR_TOUCH_NAME TOUCH_PAD_NUM8 | |
#define TOUCH_BUTTON_NUM 10 //2 //10 | |
static const touch_pad_t button[TOUCH_BUTTON_NUM] = { | |
BUTTON_A_TOUCH_NAME, | |
BUTTON_B_TOUCH_NAME, | |
BUTTON_C_TOUCH_NAME, | |
BUTTON_D_TOUCH_NAME, | |
BUTTON_E_TOUCH_NAME, | |
BUTTON_F_TOUCH_NAME, | |
PAD_ONE_TOUCH_NAME, | |
PAD_TWO_TOUCH_NAME, | |
PAD_THREE_TOUCH_NAME, | |
PAD_FOUR_TOUCH_NAME | |
}; | |
struct Button { | |
const uint8_t PIN; | |
uint32_t numberKeyPresses; | |
bool pressed; | |
uint32_t thresholdVal; | |
}; | |
//The threshold value is the reading that will trigger a touch - as tested on the NEWT breakout board = https://www.crowdsupply.com/phambili/newt | |
Button buttonA = {BUTTON_A, 0, false, 15000}; | |
Button buttonB = {BUTTON_B, 0, false, 14000}; | |
Button buttonC = {BUTTON_C, 0, false, 13000}; | |
Button buttonD = {BUTTON_D, 0, false, 12000}; | |
Button buttonE = {BUTTON_E, 0, false, 12000}; | |
Button buttonF = {BUTTON_F, 0, false, 10000}; | |
Button padONE = {PAD_ONE, 0, false, 10000}; | |
Button padTWO = {PAD_TWO, 0, false, 10000}; | |
Button padTHREE = {PAD_THREE, 0, false, 10000}; | |
Button padFOUR = {PAD_FOUR, 0, false, 11000}; | |
int selectedTouchpad = 0; | |
boolean padPressed = false; | |
//set this function before going to deep sleep. On ESP32-S2, only 1 touchpad can awake from deep sleep. | |
void setupTouchPadForSleep(touch_pad_t tPad) { | |
touch_pad_init(); | |
/* Only support one touch channel in sleep mode. */ | |
touch_pad_config(tPad); | |
/* Filter setting */ | |
touch_filter_config_t filter_info = { | |
.mode = TOUCH_PAD_FILTER_IIR_16, | |
.debounce_cnt = 1, // 1 time count. | |
.noise_thr = 0, // 50% | |
.jitter_step = 4, // use for jitter mode. | |
.smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, | |
}; | |
touch_pad_filter_set_config(&filter_info); | |
touch_pad_filter_enable(); | |
printf("touch pad filter init %d\n", TOUCH_PAD_FILTER_IIR_8); | |
/* Set sleep touch pad. */ | |
touch_pad_sleep_channel_enable(tPad, true); | |
touch_pad_sleep_channel_enable_proximity(tPad, false); | |
/* Reducing the operating frequency can effectively reduce power consumption. */ | |
touch_pad_sleep_channel_set_work_time(10000, TOUCH_PAD_MEASURE_CYCLE_DEFAULT); //1000 //5000 works /10000 works | |
/* Enable touch sensor clock. Work mode is "timer trigger". */ | |
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); | |
touch_pad_fsm_start(); | |
vTaskDelay(100 / portTICK_RATE_MS); | |
/* set touchpad wakeup threshold */ | |
uint32_t touch_value, wake_threshold; | |
touch_pad_sleep_channel_read_smooth(tPad, &touch_value); //this was working | |
wake_threshold = touch_value * 0.1; // wakeup when touch sensor crosses 10% of background level | |
touch_pad_sleep_set_threshold(tPad, wake_threshold); | |
} | |
//call this function when waking from deep sleep - this will run every 200 ms | |
void setupTouchPadWhileAwake() { | |
/* Initialize touch pad peripheral. */ | |
touch_pad_init(); | |
for (int i = 0; i < TOUCH_BUTTON_NUM; i++) { | |
touch_pad_config(button[i]); | |
} | |
/* Enable touch sensor clock. Work mode is "timer trigger". */ | |
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); | |
touch_pad_fsm_start(); | |
} | |
//this function will set the pressed parameter of the Button structure to true if a touch is registered. This is used in the main loop to take the appropriate action | |
static void touchpad_check_value(void *pvParameter) | |
{ | |
uint32_t touch_value; | |
/* Wait touch sensor init done */ | |
vTaskDelay(100 / portTICK_RATE_MS); | |
while (1) { | |
for (int i = 0; i < TOUCH_BUTTON_NUM; i++) { | |
touch_pad_read_raw_data(button[i], &touch_value); // read raw data. | |
switch (button[i]) { | |
case BUTTON_A_TOUCH_NAME: | |
if (touch_value > buttonA.thresholdVal) { | |
buttonA.pressed = true; | |
padPressed = true; | |
selectedTouchpad = BUTTON_A; | |
} | |
break; | |
case BUTTON_B_TOUCH_NAME: | |
if (touch_value > buttonB.thresholdVal) { | |
buttonB.pressed = true; | |
padPressed = true; | |
selectedTouchpad = BUTTON_B; | |
} | |
break; | |
case BUTTON_C_TOUCH_NAME: | |
if (touch_value > buttonC.thresholdVal) { | |
buttonC.pressed = true; | |
padPressed = true; | |
selectedTouchpad = BUTTON_C; | |
} | |
break; | |
case BUTTON_D_TOUCH_NAME: | |
if (touch_value > buttonD.thresholdVal) { | |
buttonD.pressed = true; | |
padPressed = true; | |
selectedTouchpad = BUTTON_D; | |
} | |
break; | |
case BUTTON_E_TOUCH_NAME: | |
if (touch_value > buttonE.thresholdVal) { | |
buttonE.pressed = true; | |
padPressed = true; | |
selectedTouchpad = BUTTON_E; | |
} | |
break; | |
case BUTTON_F_TOUCH_NAME: | |
if (touch_value > buttonF.thresholdVal) { | |
buttonF.pressed = true; | |
padPressed = true; | |
selectedTouchpad = BUTTON_F; | |
} | |
break; | |
case PAD_ONE_TOUCH_NAME: | |
if (touch_value > padONE.thresholdVal) { | |
padONE.pressed = true; | |
padPressed = true; | |
selectedTouchpad = PAD_ONE; | |
} | |
break; | |
case PAD_TWO_TOUCH_NAME: | |
if (touch_value > padTWO.thresholdVal) { | |
padTWO.pressed = true; | |
} | |
break; | |
case PAD_THREE_TOUCH_NAME: | |
if (touch_value > padTHREE.thresholdVal) { | |
padTHREE.pressed = true; | |
} | |
break; | |
case PAD_FOUR_TOUCH_NAME: | |
if (touch_value > padFOUR.thresholdVal) { | |
padFOUR.pressed = true; | |
} | |
break; | |
default: | |
break; | |
} | |
} | |
vTaskDelay(200 / portTICK_PERIOD_MS); | |
} | |
} | |
void IRAM_ATTR isr(void* arg) { | |
Button* s = static_cast<Button*>(arg); | |
s->numberKeyPresses += 1; | |
s->pressed = true; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Notes - this works on version 2.0.0 - doesn't seem to work on 2.0.2 - yet | |
I stripped out a lot of the functions that were not needed, but might have missed something. | |
This was build for the Newt Smart display - support me by purchasing one - https://www.crowdsupply.com/phambili/newt | |
*/ | |
#include <stdio.h> | |
#include "freertos/FreeRTOS.h" | |
#include "freertos/task.h" | |
#include "driver/touch_pad.h" | |
#include "esp_log.h" | |
#include "buttonFunctions.h" | |
void handleWakeupReason() { | |
touch_pad_t touchPin; | |
esp_sleep_wakeup_cause_t wakeup_reason; | |
wakeup_reason = esp_sleep_get_wakeup_cause(); | |
//Serial.println("Wakeup reason:"); | |
//Serial.println(wakeup_reason); | |
rtc_gpio_deinit(RTC_PIN_NAME); | |
rtc_gpio_deinit(USB_IN_NAME); | |
rtc_gpio_deinit(PAD_ONE_NAME); | |
rtc_gpio_deinit(PAD_TWO_NAME); | |
rtc_gpio_deinit(PAD_THREE_NAME); | |
rtc_gpio_deinit(PAD_FOUR_NAME); | |
rtc_gpio_deinit(BUTTON_A_NAME); | |
rtc_gpio_deinit(BUTTON_B_NAME); | |
rtc_gpio_deinit(BUTTON_C_NAME); | |
rtc_gpio_deinit(BUTTON_D_NAME); | |
rtc_gpio_deinit(BUTTON_E_NAME); | |
rtc_gpio_deinit(BUTTON_F_NAME); | |
setupTouchPadWhileAwake(); | |
uint64_t GPIO_reason; | |
int selectedGPIO; | |
switch (wakeup_reason) { | |
case ESP_SLEEP_WAKEUP_EXT0: | |
Serial.println("Wakeup caused by external signal using RTC_IO"); | |
break; | |
case ESP_SLEEP_WAKEUP_EXT1: | |
USBSerial.println("Wakeup caused by external signal using RTC_CNTL"); | |
GPIO_reason = esp_sleep_get_ext1_wakeup_status(); | |
selectedGPIO = (log(GPIO_reason)) / log(2); | |
//Serial.print("GPIO that triggered the wake up: GPIO "); | |
//Serial.println(selectedGPIO); | |
break; | |
case ESP_SLEEP_WAKEUP_TIMER: | |
//Serial.println("Wakeup caused by internal timer"); | |
break; | |
case ESP_SLEEP_WAKEUP_TOUCHPAD: | |
//Serial.println("Wakeup caused by touchpad"); | |
break; | |
case ESP_SLEEP_WAKEUP_ULP: USBSerial.println("Wakeup caused by ULP program"); break; | |
default: USBSerial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break; | |
} | |
} | |
void setup() { | |
//do setup stuff | |
//Print the wakeup reason for ESP32-S2 | |
handleWakeupReason(); | |
/* Start task to read values by pads. */ | |
xTaskCreate(&touchpad_check_value, "touchpad_check_value", 2048, NULL, 5, NULL); | |
} | |
void loop() { | |
//do loop stuff | |
//if pad is pressed, then do something | |
if (padPressed) { | |
//do whatever needs to be done; | |
padPressed = false; | |
selectedTouchpad = 0; | |
delay(200);//debounce value | |
} | |
//when ready for deep sleep, call handleSleep() | |
} | |
void handleSleep(){ | |
setupTouchPadForSleep(PAD_ONE_TOUCH_NAME); //setup Touch Pad - this example uses PAD_ONE | |
esp_sleep_enable_touchpad_wakeup(); | |
//Serial.println("Going to deep sleep now"); | |
//Serial.flush(); | |
esp_deep_sleep_start(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment