1#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
11static const char *
const TAG =
"esp32_touch";
27 ESP_LOGV(TAG,
"Touch Pad '%s' state: ON (value: %" PRIu32
" > threshold: %" PRIu32
")", child->
get_name().
c_str(),
30 ESP_LOGV(TAG,
"Touch Pad '%s' state: OFF", child->
get_name().
c_str());
42 "Checking touch state for '%s' (T%d): value = %" PRIu32
", threshold = %" PRIu32
", benchmark = %" PRIu32,
57 esp_err_t init_err = touch_pad_init();
58 if (init_err != ESP_OK) {
59 ESP_LOGE(TAG,
"Failed to initialize touch pad: %s", esp_err_to_name(init_err));
66 esp_err_t config_err = touch_pad_config(child->touch_pad_);
67 if (config_err != ESP_OK) {
68 ESP_LOGE(TAG,
"Failed to configure touch pad %d: %s", child->touch_pad_, esp_err_to_name(config_err));
74 touch_filter_config_t filter_info = {
81 touch_pad_filter_set_config(&filter_info);
82 touch_pad_filter_enable();
86 touch_pad_denoise_t denoise = {
90 touch_pad_denoise_set_config(&denoise);
91 touch_pad_denoise_enable();
95 touch_pad_waterproof_t waterproof = {
99 touch_pad_waterproof_set_config(&waterproof);
100 touch_pad_waterproof_enable();
105 touch_pad_set_charge_discharge_times(this->
meas_cycle_);
109 touch_pad_timeout_set(
true, TOUCH_PAD_THRESHOLD_MAX);
113 touch_pad_isr_register(
touch_isr_handler,
this,
static_cast<touch_pad_intr_mask_t
>(TOUCH_PAD_INTR_MASK_ALL));
115 ESP_LOGE(TAG,
"Failed to register touch ISR: %s", esp_err_to_name(err));
122 for (
auto *child : this->children_) {
123 if (child->threshold_ != 0) {
124 touch_pad_set_thresh(child->touch_pad_, child->threshold_);
132 touch_pad_intr_enable(
static_cast<touch_pad_intr_mask_t
>(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_TIMEOUT));
135 touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
138 touch_pad_fsm_start();
148 const char *filter_mode_s;
150 case TOUCH_PAD_FILTER_IIR_4:
151 filter_mode_s =
"IIR_4";
153 case TOUCH_PAD_FILTER_IIR_8:
154 filter_mode_s =
"IIR_8";
156 case TOUCH_PAD_FILTER_IIR_16:
157 filter_mode_s =
"IIR_16";
159 case TOUCH_PAD_FILTER_IIR_32:
160 filter_mode_s =
"IIR_32";
162 case TOUCH_PAD_FILTER_IIR_64:
163 filter_mode_s =
"IIR_64";
165 case TOUCH_PAD_FILTER_IIR_128:
166 filter_mode_s =
"IIR_128";
168 case TOUCH_PAD_FILTER_IIR_256:
169 filter_mode_s =
"IIR_256";
171 case TOUCH_PAD_FILTER_JITTER:
172 filter_mode_s =
"JITTER";
175 filter_mode_s =
"UNKNOWN";
180 " Debounce count: %" PRIu32
"\n"
181 " Noise threshold coefficient: %" PRIu32
"\n"
182 " Jitter filter step size: %" PRIu32,
184 const char *smooth_level_s;
186 case TOUCH_PAD_SMOOTH_OFF:
187 smooth_level_s =
"OFF";
189 case TOUCH_PAD_SMOOTH_IIR_2:
190 smooth_level_s =
"IIR_2";
192 case TOUCH_PAD_SMOOTH_IIR_4:
193 smooth_level_s =
"IIR_4";
195 case TOUCH_PAD_SMOOTH_IIR_8:
196 smooth_level_s =
"IIR_8";
199 smooth_level_s =
"UNKNOWN";
202 ESP_LOGCONFIG(TAG,
" Smooth level: %s", smooth_level_s);
208 case TOUCH_PAD_DENOISE_BIT12:
211 case TOUCH_PAD_DENOISE_BIT10:
214 case TOUCH_PAD_DENOISE_BIT8:
217 case TOUCH_PAD_DENOISE_BIT4:
224 ESP_LOGCONFIG(TAG,
" Denoise grade: %s", grade_s);
226 const char *cap_level_s;
228 case TOUCH_PAD_DENOISE_CAP_L0:
231 case TOUCH_PAD_DENOISE_CAP_L1:
234 case TOUCH_PAD_DENOISE_CAP_L2:
237 case TOUCH_PAD_DENOISE_CAP_L3:
240 case TOUCH_PAD_DENOISE_CAP_L4:
243 case TOUCH_PAD_DENOISE_CAP_L5:
246 case TOUCH_PAD_DENOISE_CAP_L6:
249 case TOUCH_PAD_DENOISE_CAP_L7:
253 cap_level_s =
"UNKNOWN";
256 ESP_LOGCONFIG(TAG,
" Denoise capacitance level: %s", cap_level_s);
260 ESP_LOGCONFIG(TAG,
" Setup Mode ENABLED");
280 TouchPadEventV2 event;
281 while (xQueueReceive(this->
touch_queue_, &event, 0) == pdTRUE) {
282 ESP_LOGD(TAG,
"Event received, mask = 0x%" PRIx32
", pad = %d", event.intr_mask, event.pad);
284 if (event.intr_mask & TOUCH_PAD_INTR_MASK_TIMEOUT) {
286 touch_pad_timeout_resume();
288 }
else if (!(event.intr_mask & TOUCH_PAD_INTR_MASK_ACTIVE)) {
294 for (
auto *child : this->children_) {
295 if (child->touch_pad_ == event.pad) {
296 if (event.intr_mask & TOUCH_PAD_INTR_MASK_TIMEOUT) {
299 }
else if (event.intr_mask & TOUCH_PAD_INTR_MASK_ACTIVE) {
316 for (
auto *child : this->children_) {
317 if (child->benchmark_ == 0)
318 touch_pad_read_benchmark(child->touch_pad_, &child->benchmark_);
322 if (child->last_state_) {
325 uint32_t time_diff = now - child->last_touch_time_;
337 ESP_LOGVV(TAG,
"Touch Pad '%s' still touched after %" PRIu32
"ms timeout, resetting timer",
338 child->get_name().c_str(), this->release_timeout_ms_);
357 touch_pad_intr_disable(
static_cast<touch_pad_intr_mask_t
>(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_TIMEOUT));
366 ESP32TouchComponent *component =
static_cast<ESP32TouchComponent *
>(arg);
367 BaseType_t x_higher_priority_task_woken = pdFALSE;
370 TouchPadEventV2 event;
371 event.intr_mask = touch_pad_read_intr_status_mask();
372 event.pad = touch_pad_get_current_meas_channel();
375 xQueueSendFromISR(component->touch_queue_, &event, &x_higher_priority_task_woken);
376 component->enable_loop_soon_any_context();
378 if (x_higher_priority_task_woken) {
379 portYIELD_FROM_ISR();
390 touch_pad_filter_read_smooth(
pad, &value);
393 touch_pad_read_raw_data(
pad, &value);
uint32_t IRAM_ATTR HOT get_loop_component_start_time() const
Get the cached time in milliseconds from when the current component started its loop execution.
virtual void mark_failed()
Mark this component as failed.
const StringRef & get_name() const
constexpr const char * c_str() const
void publish_state(bool new_state)
Publish a new state to the front-end.
Simple helper class to expose a touch pad value as a binary sensor.
uint32_t last_touch_time_
uint32_t value_
Stores the last raw touch measurement value.
touch_volt_atten_t voltage_attenuation_
touch_filter_mode_t filter_mode_
bool create_touch_queue_()
bool filter_configured_() const
static void touch_isr_handler(void *arg)
touch_pad_t waterproof_guard_ring_pad_
void check_and_disable_loop_if_all_released_(size_t pads_off)
bool check_and_update_touch_state_(ESP32TouchBinarySensor *child)
void publish_initial_state_if_needed_(ESP32TouchBinarySensor *child, uint32_t now)
QueueHandle_t touch_queue_
bool waterproof_configured_() const
touch_pad_denoise_grade_t grade_
void calculate_release_timeout_()
void update_touch_state_(ESP32TouchBinarySensor *child, bool is_touched, uint32_t value)
bool denoise_configured_() const
void on_shutdown() override
touch_high_volt_t high_voltage_reference_
touch_pad_shield_driver_t waterproof_shield_driver_
uint32_t noise_threshold_
touch_smooth_mode_t smooth_level_
void process_setup_mode_logging_(uint32_t now)
uint32_t release_timeout_ms_
void dump_config_sensors_()
std::vector< ESP32TouchBinarySensor * > children_
uint32_t read_touch_value(touch_pad_t pad) const
touch_pad_denoise_cap_t cap_level_
touch_low_volt_t low_voltage_reference_
void cleanup_touch_queue_()
void configure_wakeup_pads_()
bool should_check_for_releases_(uint32_t now)
void dump_config() override
Providing packet encoding functions for exchanging data with a remote host.
Application App
Global storage of Application pointer - only one Application can exist.