ESPHome 2025.6.3
Loading...
Searching...
No Matches
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
10namespace esphome {
11namespace esp32_touch {
12
13static const char *const TAG = "esp32_touch";
14
16 ESP_LOGCONFIG(TAG, "Running setup");
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#if ESP_IDF_VERSION_MAJOR >= 5 && defined(USE_ESP32_VARIANT_ESP32)
56 touch_pad_set_measurement_clock_cycles(this->meas_cycle_);
57 touch_pad_set_measurement_interval(this->sleep_cycle_);
58#else
59 touch_pad_set_meas_time(this->sleep_cycle_, this->meas_cycle_);
60#endif
61 touch_pad_set_voltage(this->high_voltage_reference_, this->low_voltage_reference_, this->voltage_attenuation_);
62
63 for (auto *child : this->children_) {
64#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
65 touch_pad_config(child->get_touch_pad());
66#else
67 // Disable interrupt threshold
68 touch_pad_config(child->get_touch_pad(), 0);
69#endif
70 }
71#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
72 touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
73 touch_pad_fsm_start();
74#endif
75}
76
78 ESP_LOGCONFIG(TAG,
79 "Config for ESP32 Touch Hub:\n"
80 " Meas cycle: %.2fms\n"
81 " Sleep cycle: %.2fms",
82 this->meas_cycle_ / (8000000.0f / 1000.0f), this->sleep_cycle_ / (150000.0f / 1000.0f));
83
84 const char *lv_s;
85 switch (this->low_voltage_reference_) {
86 case TOUCH_LVOLT_0V5:
87 lv_s = "0.5V";
88 break;
89 case TOUCH_LVOLT_0V6:
90 lv_s = "0.6V";
91 break;
92 case TOUCH_LVOLT_0V7:
93 lv_s = "0.7V";
94 break;
95 case TOUCH_LVOLT_0V8:
96 lv_s = "0.8V";
97 break;
98 default:
99 lv_s = "UNKNOWN";
100 break;
101 }
102 ESP_LOGCONFIG(TAG, " Low Voltage Reference: %s", lv_s);
103
104 const char *hv_s;
105 switch (this->high_voltage_reference_) {
106 case TOUCH_HVOLT_2V4:
107 hv_s = "2.4V";
108 break;
109 case TOUCH_HVOLT_2V5:
110 hv_s = "2.5V";
111 break;
112 case TOUCH_HVOLT_2V6:
113 hv_s = "2.6V";
114 break;
115 case TOUCH_HVOLT_2V7:
116 hv_s = "2.7V";
117 break;
118 default:
119 hv_s = "UNKNOWN";
120 break;
121 }
122 ESP_LOGCONFIG(TAG, " High Voltage Reference: %s", hv_s);
123
124 const char *atten_s;
125 switch (this->voltage_attenuation_) {
126 case TOUCH_HVOLT_ATTEN_1V5:
127 atten_s = "1.5V";
128 break;
129 case TOUCH_HVOLT_ATTEN_1V:
130 atten_s = "1V";
131 break;
132 case TOUCH_HVOLT_ATTEN_0V5:
133 atten_s = "0.5V";
134 break;
135 case TOUCH_HVOLT_ATTEN_0V:
136 atten_s = "0V";
137 break;
138 default:
139 atten_s = "UNKNOWN";
140 break;
141 }
142 ESP_LOGCONFIG(TAG, " Voltage Attenuation: %s", atten_s);
143
144#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
145 if (this->filter_configured_()) {
146 const char *filter_mode_s;
147 switch (this->filter_mode_) {
148 case TOUCH_PAD_FILTER_IIR_4:
149 filter_mode_s = "IIR_4";
150 break;
151 case TOUCH_PAD_FILTER_IIR_8:
152 filter_mode_s = "IIR_8";
153 break;
154 case TOUCH_PAD_FILTER_IIR_16:
155 filter_mode_s = "IIR_16";
156 break;
157 case TOUCH_PAD_FILTER_IIR_32:
158 filter_mode_s = "IIR_32";
159 break;
160 case TOUCH_PAD_FILTER_IIR_64:
161 filter_mode_s = "IIR_64";
162 break;
163 case TOUCH_PAD_FILTER_IIR_128:
164 filter_mode_s = "IIR_128";
165 break;
166 case TOUCH_PAD_FILTER_IIR_256:
167 filter_mode_s = "IIR_256";
168 break;
169 case TOUCH_PAD_FILTER_JITTER:
170 filter_mode_s = "JITTER";
171 break;
172 default:
173 filter_mode_s = "UNKNOWN";
174 break;
175 }
176 ESP_LOGCONFIG(TAG,
177 " Filter mode: %s\n"
178 " Debounce count: %" PRIu32 "\n"
179 " Noise threshold coefficient: %" PRIu32 "\n"
180 " Jitter filter step size: %" PRIu32,
181 filter_mode_s, this->debounce_count_, this->noise_threshold_, this->jitter_step_);
182 const char *smooth_level_s;
183 switch (this->smooth_level_) {
184 case TOUCH_PAD_SMOOTH_OFF:
185 smooth_level_s = "OFF";
186 break;
187 case TOUCH_PAD_SMOOTH_IIR_2:
188 smooth_level_s = "IIR_2";
189 break;
190 case TOUCH_PAD_SMOOTH_IIR_4:
191 smooth_level_s = "IIR_4";
192 break;
193 case TOUCH_PAD_SMOOTH_IIR_8:
194 smooth_level_s = "IIR_8";
195 break;
196 default:
197 smooth_level_s = "UNKNOWN";
198 break;
199 }
200 ESP_LOGCONFIG(TAG, " Smooth level: %s", smooth_level_s);
201 }
202
203 if (this->denoise_configured_()) {
204 const char *grade_s;
205 switch (this->grade_) {
206 case TOUCH_PAD_DENOISE_BIT12:
207 grade_s = "BIT12";
208 break;
209 case TOUCH_PAD_DENOISE_BIT10:
210 grade_s = "BIT10";
211 break;
212 case TOUCH_PAD_DENOISE_BIT8:
213 grade_s = "BIT8";
214 break;
215 case TOUCH_PAD_DENOISE_BIT4:
216 grade_s = "BIT4";
217 break;
218 default:
219 grade_s = "UNKNOWN";
220 break;
221 }
222 ESP_LOGCONFIG(TAG, " Denoise grade: %s", grade_s);
223
224 const char *cap_level_s;
225 switch (this->cap_level_) {
226 case TOUCH_PAD_DENOISE_CAP_L0:
227 cap_level_s = "L0";
228 break;
229 case TOUCH_PAD_DENOISE_CAP_L1:
230 cap_level_s = "L1";
231 break;
232 case TOUCH_PAD_DENOISE_CAP_L2:
233 cap_level_s = "L2";
234 break;
235 case TOUCH_PAD_DENOISE_CAP_L3:
236 cap_level_s = "L3";
237 break;
238 case TOUCH_PAD_DENOISE_CAP_L4:
239 cap_level_s = "L4";
240 break;
241 case TOUCH_PAD_DENOISE_CAP_L5:
242 cap_level_s = "L5";
243 break;
244 case TOUCH_PAD_DENOISE_CAP_L6:
245 cap_level_s = "L6";
246 break;
247 case TOUCH_PAD_DENOISE_CAP_L7:
248 cap_level_s = "L7";
249 break;
250 default:
251 cap_level_s = "UNKNOWN";
252 break;
253 }
254 ESP_LOGCONFIG(TAG, " Denoise capacitance level: %s", cap_level_s);
255 }
256#else
257 if (this->iir_filter_enabled_()) {
258 ESP_LOGCONFIG(TAG, " IIR Filter: %" PRIu32 "ms", this->iir_filter_);
259 } else {
260 ESP_LOGCONFIG(TAG, " IIR Filter DISABLED");
261 }
262#endif
263
264 if (this->setup_mode_) {
265 ESP_LOGCONFIG(TAG, " Setup Mode ENABLED");
266 }
267
268 for (auto *child : this->children_) {
269 LOG_BINARY_SENSOR(" ", "Touch Pad", child);
270 ESP_LOGCONFIG(TAG, " Pad: T%" PRIu32, (uint32_t) child->get_touch_pad());
271 ESP_LOGCONFIG(TAG, " Threshold: %" PRIu32, child->get_threshold());
272 }
273}
274
276#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
277 uint32_t value = 0;
278 if (this->filter_configured_()) {
279 touch_pad_filter_read_smooth(tp, &value);
280 } else {
281 touch_pad_read_raw_data(tp, &value);
282 }
283#else
284 uint16_t value = 0;
285 if (this->iir_filter_enabled_()) {
286 touch_pad_read_filtered(tp, &value);
287 } else {
288 touch_pad_read(tp, &value);
289 }
290#endif
291 return value;
292}
293
295 const uint32_t now = App.get_loop_component_start_time();
296 bool should_print = this->setup_mode_ && now - this->setup_mode_last_log_print_ > 250;
297 for (auto *child : this->children_) {
298 child->value_ = this->component_touch_pad_read(child->get_touch_pad());
299#if !(defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3))
300 child->publish_state(child->value_ < child->get_threshold());
301#else
302 child->publish_state(child->value_ > child->get_threshold());
303#endif
304
305 if (should_print) {
306 ESP_LOGD(TAG, "Touch Pad '%s' (T%" PRIu32 "): %" PRIu32, child->get_name().c_str(),
307 (uint32_t) child->get_touch_pad(), child->value_);
308 }
309
310 App.feed_wdt();
311 }
312
313 if (should_print) {
314 // Avoid spamming logs
315 this->setup_mode_last_log_print_ = now;
316 }
317}
318
320 bool is_wakeup_source = false;
321
322#if !(defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3))
323 if (this->iir_filter_enabled_()) {
324 touch_pad_filter_stop();
325 touch_pad_filter_delete();
326 }
327#endif
328
329 for (auto *child : this->children_) {
330 if (child->get_wakeup_threshold() != 0) {
331 if (!is_wakeup_source) {
332 is_wakeup_source = true;
333 // Touch sensor FSM mode must be 'TOUCH_FSM_MODE_TIMER' to use it to wake-up.
334 touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
335 }
336
337#if !(defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3))
338 // No filter available when using as wake-up source.
339 touch_pad_config(child->get_touch_pad(), child->get_wakeup_threshold());
340#endif
341 }
342 }
343
344 if (!is_wakeup_source) {
345 touch_pad_deinit();
346 }
347}
348
349ESP32TouchBinarySensor::ESP32TouchBinarySensor(touch_pad_t touch_pad, uint32_t threshold, uint32_t wakeup_threshold)
350 : touch_pad_(touch_pad), threshold_(threshold), wakeup_threshold_(wakeup_threshold) {}
351
352} // namespace esp32_touch
353} // namespace esphome
354
355#endif
void feed_wdt(uint32_t time=0)
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.
ESP32TouchBinarySensor(touch_pad_t touch_pad, uint32_t threshold, uint32_t wakeup_threshold)
uint32_t component_touch_pad_read(touch_pad_t tp)
touch_pad_shield_driver_t waterproof_shield_driver_
Definition esp32_touch.h:93
std::vector< ESP32TouchBinarySensor * > children_
Definition esp32_touch.h:75
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
Application App
Global storage of Application pointer - only one Application can exist.