1
0
mirror of https://github.com/esphome/esphome.git synced 2026-02-08 00:31:58 +00:00

[esp32_touch] Disable hardware timeout to prevent continuous interrupts (#13059)

Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
This commit is contained in:
marcbodea
2026-01-08 00:37:47 +01:00
committed by GitHub
parent a66df9ab0f
commit afa4fe9820
3 changed files with 26 additions and 6 deletions

View File

@@ -243,6 +243,16 @@ class ESP32TouchBinarySensor : public binary_sensor::BinarySensor {
uint32_t get_wakeup_threshold() const { return this->wakeup_threshold_; }
#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
/// Ensure benchmark value is read (v2 touch hardware only).
/// Called from multiple places - kept as helper to document shared usage.
void ensure_benchmark_read() {
if (this->benchmark_ == 0) {
touch_pad_read_benchmark(this->touch_pad_, &this->benchmark_);
}
}
#endif
protected:
friend ESP32TouchComponent;

View File

@@ -102,7 +102,16 @@ void ESP32TouchComponent::process_setup_mode_logging_(uint32_t now) {
uint32_t value = this->read_touch_value(child->get_touch_pad());
// Store the value for get_value() access in lambdas
child->value_ = value;
ESP_LOGD(TAG, "Touch Pad '%s' (T%d): %d", child->get_name().c_str(), child->get_touch_pad(), value);
// Read benchmark if not already read
child->ensure_benchmark_read();
// Calculate difference to help user set threshold
// For ESP32-S2/S3 v2: touch detected when value > benchmark + threshold
// So threshold should be < (value - benchmark) when touched
int32_t difference = static_cast<int32_t>(value) - static_cast<int32_t>(child->benchmark_);
ESP_LOGD(TAG,
"Touch Pad '%s' (T%d): value=%d, benchmark=%" PRIu32 ", difference=%" PRId32 " (set threshold < %" PRId32
" to detect touch)",
child->get_name().c_str(), child->get_touch_pad(), value, child->benchmark_, difference, difference);
#endif
}
this->setup_mode_last_log_print_ = now;

View File

@@ -105,8 +105,10 @@ void ESP32TouchComponent::setup() {
touch_pad_set_charge_discharge_times(this->meas_cycle_);
touch_pad_set_measurement_interval(this->sleep_cycle_);
// Configure timeout if needed
touch_pad_timeout_set(true, TOUCH_PAD_THRESHOLD_MAX);
// Disable hardware timeout - it causes continuous interrupts with high-capacitance
// setups (e.g., pressure sensors under cushions). The periodic release check in
// loop() handles state detection reliably without needing hardware timeout.
touch_pad_timeout_set(false, TOUCH_PAD_THRESHOLD_MAX);
// Register ISR handler with interrupt mask
esp_err_t err =
@@ -314,8 +316,7 @@ void ESP32TouchComponent::loop() {
size_t pads_off = 0;
for (auto *child : this->children_) {
if (child->benchmark_ == 0)
touch_pad_read_benchmark(child->touch_pad_, &child->benchmark_);
child->ensure_benchmark_read();
// Handle initial state publication after startup
this->publish_initial_state_if_needed_(child, now);
@@ -354,7 +355,7 @@ void ESP32TouchComponent::loop() {
void ESP32TouchComponent::on_shutdown() {
// Disable interrupts
touch_pad_intr_disable(static_cast<touch_pad_intr_mask_t>(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_TIMEOUT));
touch_pad_intr_disable(TOUCH_PAD_INTR_MASK_ACTIVE);
touch_pad_isr_deregister(touch_isr_handler, this);
this->cleanup_touch_queue_();