From 9ebe075f9b85ff5940748df3ce393bccc1e72c88 Mon Sep 17 00:00:00 2001 From: Christian Taedcke Date: Mon, 20 Sep 2021 10:12:32 +0200 Subject: [PATCH] Add deep sleep wakeup from touch (#1238) (#2281) --- esphome/components/deep_sleep/__init__.py | 5 ++++ .../deep_sleep/deep_sleep_component.cpp | 7 ++++++ .../deep_sleep/deep_sleep_component.h | 3 +++ .../components/esp32_touch/binary_sensor.py | 3 +++ .../components/esp32_touch/esp32_touch.cpp | 25 ++++++++++++++++--- esphome/components/esp32_touch/esp32_touch.h | 4 ++- 6 files changed, 43 insertions(+), 4 deletions(-) diff --git a/esphome/components/deep_sleep/__init__.py b/esphome/components/deep_sleep/__init__.py index 3f59ad52cf..1e07b75173 100644 --- a/esphome/components/deep_sleep/__init__.py +++ b/esphome/components/deep_sleep/__init__.py @@ -44,6 +44,7 @@ EXT1_WAKEUP_MODES = { CONF_WAKEUP_PIN_MODE = "wakeup_pin_mode" CONF_ESP32_EXT1_WAKEUP = "esp32_ext1_wakeup" +CONF_TOUCH_WAKEUP = "touch_wakeup" CONFIG_SCHEMA = cv.Schema( { @@ -67,6 +68,7 @@ CONFIG_SCHEMA = cv.Schema( } ), ), + cv.Optional(CONF_TOUCH_WAKEUP): cv.All(cv.only_on_esp32, cv.boolean), } ).extend(cv.COMPONENT_SCHEMA) @@ -95,6 +97,9 @@ async def to_code(config): ) cg.add(var.set_ext1_wakeup(struct)) + if CONF_TOUCH_WAKEUP in config: + cg.add(var.set_touch_wakeup(config[CONF_TOUCH_WAKEUP])) + cg.add_define("USE_DEEP_SLEEP") diff --git a/esphome/components/deep_sleep/deep_sleep_component.cpp b/esphome/components/deep_sleep/deep_sleep_component.cpp index 00f660f41a..9c354c8513 100644 --- a/esphome/components/deep_sleep/deep_sleep_component.cpp +++ b/esphome/components/deep_sleep/deep_sleep_component.cpp @@ -44,6 +44,7 @@ void DeepSleepComponent::set_wakeup_pin_mode(WakeupPinMode wakeup_pin_mode) { this->wakeup_pin_mode_ = wakeup_pin_mode; } void DeepSleepComponent::set_ext1_wakeup(Ext1Wakeup ext1_wakeup) { this->ext1_wakeup_ = ext1_wakeup; } +void DeepSleepComponent::set_touch_wakeup(bool touch_wakeup) { this->touch_wakeup_ = touch_wakeup; } #endif void DeepSleepComponent::set_run_duration(uint32_t time_ms) { this->run_duration_ = time_ms; } void DeepSleepComponent::begin_sleep(bool manual) { @@ -80,6 +81,12 @@ void DeepSleepComponent::begin_sleep(bool manual) { if (this->ext1_wakeup_.has_value()) { esp_sleep_enable_ext1_wakeup(this->ext1_wakeup_->mask, this->ext1_wakeup_->wakeup_mode); } + + if (this->touch_wakeup_.has_value() && *(this->touch_wakeup_)) { + esp_sleep_enable_touchpad_wakeup(); + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); + } + esp_deep_sleep_start(); #endif diff --git a/esphome/components/deep_sleep/deep_sleep_component.h b/esphome/components/deep_sleep/deep_sleep_component.h index 5050bd6b4d..575f7be72b 100644 --- a/esphome/components/deep_sleep/deep_sleep_component.h +++ b/esphome/components/deep_sleep/deep_sleep_component.h @@ -53,6 +53,8 @@ class DeepSleepComponent : public Component { void set_wakeup_pin_mode(WakeupPinMode wakeup_pin_mode); void set_ext1_wakeup(Ext1Wakeup ext1_wakeup); + + void set_touch_wakeup(bool touch_wakeup); #endif /// Set a duration in ms for how long the code should run before entering deep sleep mode. void set_run_duration(uint32_t time_ms); @@ -74,6 +76,7 @@ class DeepSleepComponent : public Component { optional wakeup_pin_; WakeupPinMode wakeup_pin_mode_{WAKEUP_PIN_MODE_IGNORE}; optional ext1_wakeup_; + optional touch_wakeup_; #endif optional run_duration_; bool next_enter_deep_sleep_{false}; diff --git a/esphome/components/esp32_touch/binary_sensor.py b/esphome/components/esp32_touch/binary_sensor.py index 300de23f08..198a43a738 100644 --- a/esphome/components/esp32_touch/binary_sensor.py +++ b/esphome/components/esp32_touch/binary_sensor.py @@ -15,6 +15,7 @@ ESP_PLATFORMS = [ESP_PLATFORM_ESP32] DEPENDENCIES = ["esp32_touch"] CONF_ESP32_TOUCH_ID = "esp32_touch_id" +CONF_WAKEUP_THRESHOLD = "wakeup_threshold" TOUCH_PADS = { 4: cg.global_ns.TOUCH_PAD_NUM0, @@ -47,6 +48,7 @@ CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend( cv.GenerateID(CONF_ESP32_TOUCH_ID): cv.use_id(ESP32TouchComponent), cv.Required(CONF_PIN): validate_touch_pad, cv.Required(CONF_THRESHOLD): cv.uint16_t, + cv.Optional(CONF_WAKEUP_THRESHOLD, default=0): cv.uint16_t, } ) @@ -58,6 +60,7 @@ async def to_code(config): config[CONF_NAME], TOUCH_PADS[config[CONF_PIN]], config[CONF_THRESHOLD], + config[CONF_WAKEUP_THRESHOLD], ) await binary_sensor.register_binary_sensor(var, config) cg.add(hub.register_touch_pad(var)) diff --git a/esphome/components/esp32_touch/esp32_touch.cpp b/esphome/components/esp32_touch/esp32_touch.cpp index a990e632af..9ae671a4a9 100644 --- a/esphome/components/esp32_touch/esp32_touch.cpp +++ b/esphome/components/esp32_touch/esp32_touch.cpp @@ -133,15 +133,34 @@ void ESP32TouchComponent::loop() { } void ESP32TouchComponent::on_shutdown() { + bool is_wakeup_source = false; + if (this->iir_filter_enabled_()) { touch_pad_filter_stop(); touch_pad_filter_delete(); } - touch_pad_deinit(); + + for (auto *child : this->children_) { + if (child->get_wakeup_threshold() != 0) { + if (!is_wakeup_source) { + is_wakeup_source = true; + // Touch sensor FSM mode must be 'TOUCH_FSM_MODE_TIMER' to use it to wake-up. + touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); + } + + // No filter available when using as wake-up source. + touch_pad_config(child->get_touch_pad(), child->get_wakeup_threshold()); + } + } + + if (!is_wakeup_source) { + touch_pad_deinit(); + } } -ESP32TouchBinarySensor::ESP32TouchBinarySensor(const std::string &name, touch_pad_t touch_pad, uint16_t threshold) - : BinarySensor(name), touch_pad_(touch_pad), threshold_(threshold) {} +ESP32TouchBinarySensor::ESP32TouchBinarySensor(const std::string &name, touch_pad_t touch_pad, uint16_t threshold, + uint16_t wakeup_threshold) + : BinarySensor(name), touch_pad_(touch_pad), threshold_(threshold), wakeup_threshold_(wakeup_threshold) {} } // namespace esp32_touch } // namespace esphome diff --git a/esphome/components/esp32_touch/esp32_touch.h b/esphome/components/esp32_touch/esp32_touch.h index 45d459a2ff..8b92a482c0 100644 --- a/esphome/components/esp32_touch/esp32_touch.h +++ b/esphome/components/esp32_touch/esp32_touch.h @@ -57,12 +57,13 @@ class ESP32TouchComponent : public Component { /// Simple helper class to expose a touch pad value as a binary sensor. class ESP32TouchBinarySensor : public binary_sensor::BinarySensor { public: - ESP32TouchBinarySensor(const std::string &name, touch_pad_t touch_pad, uint16_t threshold); + ESP32TouchBinarySensor(const std::string &name, touch_pad_t touch_pad, uint16_t threshold, uint16_t wakeup_threshold); touch_pad_t get_touch_pad() const { return touch_pad_; } uint16_t get_threshold() const { return threshold_; } void set_threshold(uint16_t threshold) { threshold_ = threshold; } uint16_t get_value() const { return value_; } + uint16_t get_wakeup_threshold() const { return wakeup_threshold_; } protected: friend ESP32TouchComponent; @@ -70,6 +71,7 @@ class ESP32TouchBinarySensor : public binary_sensor::BinarySensor { touch_pad_t touch_pad_; uint16_t threshold_; uint16_t value_; + const uint16_t wakeup_threshold_; }; } // namespace esp32_touch