Skip to content

Instantly share code, notes, and snippets.

@darianbjohnson
Created January 8, 2022 17:43
Show Gist options
  • Save darianbjohnson/268bff40ea72642dd2e05123ec5b8c40 to your computer and use it in GitHub Desktop.
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
#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;
}
/*
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