ESPHome  2024.6.1
esp32_touch.cpp
Go to the documentation of this file.
1 #ifdef USE_ESP32
2 
3 #include "esp32_touch.h"
5 #include "esphome/core/log.h"
6 #include "esphome/core/hal.h"
7 
8 #include <cinttypes>
9 
10 namespace esphome {
11 namespace esp32_touch {
12 
13 static const char *const TAG = "esp32_touch";
14 
16  ESP_LOGCONFIG(TAG, "Setting up ESP32 Touch Hub...");
17  touch_pad_init();
18 // set up and enable/start filtering based on ESP32 variant
19 #if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
20  if (this->filter_configured_()) {
21  touch_filter_config_t filter_info = {
22  .mode = this->filter_mode_,
23  .debounce_cnt = this->debounce_count_,
24  .noise_thr = this->noise_threshold_,
25  .jitter_step = this->jitter_step_,
26  .smh_lvl = this->smooth_level_,
27  };
28  touch_pad_filter_set_config(&filter_info);
29  touch_pad_filter_enable();
30  }
31 
32  if (this->denoise_configured_()) {
33  touch_pad_denoise_t denoise = {
34  .grade = this->grade_,
35  .cap_level = this->cap_level_,
36  };
37  touch_pad_denoise_set_config(&denoise);
38  touch_pad_denoise_enable();
39  }
40 
41  if (this->waterproof_configured_()) {
42  touch_pad_waterproof_t waterproof = {
43  .guard_ring_pad = this->waterproof_guard_ring_pad_,
44  .shield_driver = this->waterproof_shield_driver_,
45  };
46  touch_pad_waterproof_set_config(&waterproof);
47  touch_pad_waterproof_enable();
48  }
49 #else
50  if (this->iir_filter_enabled_()) {
51  touch_pad_filter_start(this->iir_filter_);
52  }
53 #endif
54 
55  touch_pad_set_meas_time(this->sleep_cycle_, this->meas_cycle_);
56  touch_pad_set_voltage(this->high_voltage_reference_, this->low_voltage_reference_, this->voltage_attenuation_);
57 
58  for (auto *child : this->children_) {
59 #if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
60  touch_pad_config(child->get_touch_pad());
61 #else
62  // Disable interrupt threshold
63  touch_pad_config(child->get_touch_pad(), 0);
64 #endif
65  }
66 #if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
67  touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
68  touch_pad_fsm_start();
69 #endif
70 }
71 
73  ESP_LOGCONFIG(TAG, "Config for ESP32 Touch Hub:");
74  ESP_LOGCONFIG(TAG, " Meas cycle: %.2fms", this->meas_cycle_ / (8000000.0f / 1000.0f));
75  ESP_LOGCONFIG(TAG, " Sleep cycle: %.2fms", this->sleep_cycle_ / (150000.0f / 1000.0f));
76 
77  const char *lv_s;
78  switch (this->low_voltage_reference_) {
79  case TOUCH_LVOLT_0V5:
80  lv_s = "0.5V";
81  break;
82  case TOUCH_LVOLT_0V6:
83  lv_s = "0.6V";
84  break;
85  case TOUCH_LVOLT_0V7:
86  lv_s = "0.7V";
87  break;
88  case TOUCH_LVOLT_0V8:
89  lv_s = "0.8V";
90  break;
91  default:
92  lv_s = "UNKNOWN";
93  break;
94  }
95  ESP_LOGCONFIG(TAG, " Low Voltage Reference: %s", lv_s);
96 
97  const char *hv_s;
98  switch (this->high_voltage_reference_) {
99  case TOUCH_HVOLT_2V4:
100  hv_s = "2.4V";
101  break;
102  case TOUCH_HVOLT_2V5:
103  hv_s = "2.5V";
104  break;
105  case TOUCH_HVOLT_2V6:
106  hv_s = "2.6V";
107  break;
108  case TOUCH_HVOLT_2V7:
109  hv_s = "2.7V";
110  break;
111  default:
112  hv_s = "UNKNOWN";
113  break;
114  }
115  ESP_LOGCONFIG(TAG, " High Voltage Reference: %s", hv_s);
116 
117  const char *atten_s;
118  switch (this->voltage_attenuation_) {
119  case TOUCH_HVOLT_ATTEN_1V5:
120  atten_s = "1.5V";
121  break;
122  case TOUCH_HVOLT_ATTEN_1V:
123  atten_s = "1V";
124  break;
125  case TOUCH_HVOLT_ATTEN_0V5:
126  atten_s = "0.5V";
127  break;
128  case TOUCH_HVOLT_ATTEN_0V:
129  atten_s = "0V";
130  break;
131  default:
132  atten_s = "UNKNOWN";
133  break;
134  }
135  ESP_LOGCONFIG(TAG, " Voltage Attenuation: %s", atten_s);
136 
137 #if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
138  if (this->filter_configured_()) {
139  const char *filter_mode_s;
140  switch (this->filter_mode_) {
141  case TOUCH_PAD_FILTER_IIR_4:
142  filter_mode_s = "IIR_4";
143  break;
144  case TOUCH_PAD_FILTER_IIR_8:
145  filter_mode_s = "IIR_8";
146  break;
147  case TOUCH_PAD_FILTER_IIR_16:
148  filter_mode_s = "IIR_16";
149  break;
150  case TOUCH_PAD_FILTER_IIR_32:
151  filter_mode_s = "IIR_32";
152  break;
153  case TOUCH_PAD_FILTER_IIR_64:
154  filter_mode_s = "IIR_64";
155  break;
156  case TOUCH_PAD_FILTER_IIR_128:
157  filter_mode_s = "IIR_128";
158  break;
159  case TOUCH_PAD_FILTER_IIR_256:
160  filter_mode_s = "IIR_256";
161  break;
162  case TOUCH_PAD_FILTER_JITTER:
163  filter_mode_s = "JITTER";
164  break;
165  default:
166  filter_mode_s = "UNKNOWN";
167  break;
168  }
169  ESP_LOGCONFIG(TAG, " Filter mode: %s", filter_mode_s);
170  ESP_LOGCONFIG(TAG, " Debounce count: %" PRIu32, this->debounce_count_);
171  ESP_LOGCONFIG(TAG, " Noise threshold coefficient: %" PRIu32, this->noise_threshold_);
172  ESP_LOGCONFIG(TAG, " Jitter filter step size: %" PRIu32, this->jitter_step_);
173  const char *smooth_level_s;
174  switch (this->smooth_level_) {
175  case TOUCH_PAD_SMOOTH_OFF:
176  smooth_level_s = "OFF";
177  break;
178  case TOUCH_PAD_SMOOTH_IIR_2:
179  smooth_level_s = "IIR_2";
180  break;
181  case TOUCH_PAD_SMOOTH_IIR_4:
182  smooth_level_s = "IIR_4";
183  break;
184  case TOUCH_PAD_SMOOTH_IIR_8:
185  smooth_level_s = "IIR_8";
186  break;
187  default:
188  smooth_level_s = "UNKNOWN";
189  break;
190  }
191  ESP_LOGCONFIG(TAG, " Smooth level: %s", smooth_level_s);
192  }
193 
194  if (this->denoise_configured_()) {
195  const char *grade_s;
196  switch (this->grade_) {
197  case TOUCH_PAD_DENOISE_BIT12:
198  grade_s = "BIT12";
199  break;
200  case TOUCH_PAD_DENOISE_BIT10:
201  grade_s = "BIT10";
202  break;
203  case TOUCH_PAD_DENOISE_BIT8:
204  grade_s = "BIT8";
205  break;
206  case TOUCH_PAD_DENOISE_BIT4:
207  grade_s = "BIT4";
208  break;
209  default:
210  grade_s = "UNKNOWN";
211  break;
212  }
213  ESP_LOGCONFIG(TAG, " Denoise grade: %s", grade_s);
214 
215  const char *cap_level_s;
216  switch (this->cap_level_) {
217  case TOUCH_PAD_DENOISE_CAP_L0:
218  cap_level_s = "L0";
219  break;
220  case TOUCH_PAD_DENOISE_CAP_L1:
221  cap_level_s = "L1";
222  break;
223  case TOUCH_PAD_DENOISE_CAP_L2:
224  cap_level_s = "L2";
225  break;
226  case TOUCH_PAD_DENOISE_CAP_L3:
227  cap_level_s = "L3";
228  break;
229  case TOUCH_PAD_DENOISE_CAP_L4:
230  cap_level_s = "L4";
231  break;
232  case TOUCH_PAD_DENOISE_CAP_L5:
233  cap_level_s = "L5";
234  break;
235  case TOUCH_PAD_DENOISE_CAP_L6:
236  cap_level_s = "L6";
237  break;
238  case TOUCH_PAD_DENOISE_CAP_L7:
239  cap_level_s = "L7";
240  break;
241  default:
242  cap_level_s = "UNKNOWN";
243  break;
244  }
245  ESP_LOGCONFIG(TAG, " Denoise capacitance level: %s", cap_level_s);
246  }
247 #else
248  if (this->iir_filter_enabled_()) {
249  ESP_LOGCONFIG(TAG, " IIR Filter: %" PRIu32 "ms", this->iir_filter_);
250  } else {
251  ESP_LOGCONFIG(TAG, " IIR Filter DISABLED");
252  }
253 #endif
254 
255  if (this->setup_mode_) {
256  ESP_LOGCONFIG(TAG, " Setup Mode ENABLED");
257  }
258 
259  for (auto *child : this->children_) {
260  LOG_BINARY_SENSOR(" ", "Touch Pad", child);
261  ESP_LOGCONFIG(TAG, " Pad: T%" PRIu32, (uint32_t) child->get_touch_pad());
262  ESP_LOGCONFIG(TAG, " Threshold: %" PRIu32, child->get_threshold());
263  }
264 }
265 
267 #if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
268  uint32_t value = 0;
269  if (this->filter_configured_()) {
270  touch_pad_filter_read_smooth(tp, &value);
271  } else {
272  touch_pad_read_raw_data(tp, &value);
273  }
274 #else
275  uint16_t value = 0;
276  if (this->iir_filter_enabled_()) {
277  touch_pad_read_filtered(tp, &value);
278  } else {
279  touch_pad_read(tp, &value);
280  }
281 #endif
282  return value;
283 }
284 
286  const uint32_t now = millis();
287  bool should_print = this->setup_mode_ && now - this->setup_mode_last_log_print_ > 250;
288  for (auto *child : this->children_) {
289  child->value_ = this->component_touch_pad_read(child->get_touch_pad());
290 #if !(defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3))
291  child->publish_state(child->value_ < child->get_threshold());
292 #else
293  child->publish_state(child->value_ > child->get_threshold());
294 #endif
295 
296  if (should_print) {
297  ESP_LOGD(TAG, "Touch Pad '%s' (T%" PRIu32 "): %" PRIu32, child->get_name().c_str(),
298  (uint32_t) child->get_touch_pad(), child->value_);
299  }
300 
301  App.feed_wdt();
302  }
303 
304  if (should_print) {
305  // Avoid spamming logs
306  this->setup_mode_last_log_print_ = now;
307  }
308 }
309 
311  bool is_wakeup_source = false;
312 
313 #if !(defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3))
314  if (this->iir_filter_enabled_()) {
315  touch_pad_filter_stop();
316  touch_pad_filter_delete();
317  }
318 #endif
319 
320  for (auto *child : this->children_) {
321  if (child->get_wakeup_threshold() != 0) {
322  if (!is_wakeup_source) {
323  is_wakeup_source = true;
324  // Touch sensor FSM mode must be 'TOUCH_FSM_MODE_TIMER' to use it to wake-up.
325  touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
326  }
327 
328 #if !(defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3))
329  // No filter available when using as wake-up source.
330  touch_pad_config(child->get_touch_pad(), child->get_wakeup_threshold());
331 #endif
332  }
333  }
334 
335  if (!is_wakeup_source) {
336  touch_pad_deinit();
337  }
338 }
339 
340 ESP32TouchBinarySensor::ESP32TouchBinarySensor(touch_pad_t touch_pad, uint32_t threshold, uint32_t wakeup_threshold)
341  : touch_pad_(touch_pad), threshold_(threshold), wakeup_threshold_(wakeup_threshold) {}
342 
343 } // namespace esp32_touch
344 } // namespace esphome
345 
346 #endif
std::vector< ESP32TouchBinarySensor * > children_
Definition: esp32_touch.h:75
touch_pad_denoise_cap_t cap_level_
Definition: esp32_touch.h:91
ESP32TouchBinarySensor(touch_pad_t touch_pad, uint32_t threshold, uint32_t wakeup_threshold)
uint32_t component_touch_pad_read(touch_pad_t tp)
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:25
touch_pad_shield_driver_t waterproof_shield_driver_
Definition: esp32_touch.h:93
Application App
Global storage of Application pointer - only one Application can exist.
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
touch_pad_denoise_grade_t grade_
Definition: esp32_touch.h:90