1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-30 06:33:51 +00:00
This commit is contained in:
J. Nick Koston
2025-06-12 20:02:39 -05:00
parent ee6b2ba6c6
commit 599e28e1cb
2 changed files with 25 additions and 46 deletions

View File

@@ -160,6 +160,9 @@ class ESP32TouchComponent : public Component {
// Returns the current touch pad value using either filtered or raw reading
// based on the filter configuration
uint32_t read_touch_value(touch_pad_t pad) const;
// Helper to read touch value and update state for a given child
void check_and_update_touch_state_(ESP32TouchBinarySensor *child);
#endif
// Helper functions for dump_config - common to both implementations

View File

@@ -10,6 +10,22 @@ namespace esp32_touch {
static const char *const TAG = "esp32_touch";
// Helper to read touch value and update state for a given child
void ESP32TouchComponent::check_and_update_touch_state_(ESP32TouchBinarySensor *child) {
// Read current touch value
uint32_t value = this->read_touch_value(child->get_touch_pad());
// ESP32-S2/S3 v2: Touch is detected when value > threshold
bool is_touched = value > child->get_threshold();
if (child->last_state_ != is_touched) {
child->last_state_ = is_touched;
child->publish_state(is_touched);
ESP_LOGD(TAG, "Touch Pad '%s' %s (value: %d %s threshold: %d)", child->get_name().c_str(),
is_touched ? "touched" : "released", value, is_touched ? ">" : "<=", child->get_threshold());
}
}
void ESP32TouchComponent::setup() {
// Create queue for touch events first
if (!this->create_touch_queue_()) {
@@ -103,15 +119,11 @@ void ESP32TouchComponent::setup() {
// Read current value
uint32_t value = this->read_touch_value(child->get_touch_pad());
// IMPORTANT: ESP32-S2/S3 v2 touch detection logic - INVERTED compared to v1!
// ESP32-S2/S3 v2: Touch is detected when capacitance INCREASES, causing the measured value to INCREASE
// Therefore: touched = (value > threshold)
// This is opposite to original ESP32 v1 where touched = (value < threshold)
// Set initial state and publish
bool is_touched = value > child->get_threshold();
child->last_state_ = is_touched;
child->publish_initial_state(is_touched);
// Note: ESP32-S2/S3 v2 uses inverted logic compared to v1 - touched when value > threshold
ESP_LOGD(TAG, "Touch Pad '%s' initial state: %s (value: %d %s threshold: %d)", child->get_name().c_str(),
is_touched ? "touched" : "released", value, is_touched ? ">" : "<=", child->get_threshold());
}
@@ -260,56 +272,20 @@ void ESP32TouchComponent::loop() {
if (event.intr_mask & TOUCH_PAD_INTR_MASK_TIMEOUT) {
// Resume measurement after timeout
touch_pad_timeout_resume();
// For timeout events, we should check if the pad is actually touched
// Timeout occurs when a pad stays above threshold for too long
for (auto *child : this->children_) {
if (child->get_touch_pad() != event.pad) {
continue;
}
// Read current value to determine actual state
uint32_t value = this->read_touch_value(event.pad);
bool is_touched = value > child->get_threshold();
// Update state if changed
if (child->last_state_ != is_touched) {
child->last_state_ = is_touched;
child->publish_state(is_touched);
ESP_LOGD(TAG, "Touch Pad '%s' %s via timeout (value: %d %s threshold: %d)", child->get_name().c_str(),
is_touched ? "touched" : "released", value, is_touched ? ">" : "<=", child->get_threshold());
}
break;
}
// For timeout events, always check the current state
} else if (!(event.intr_mask & (TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE))) {
// Skip if not an active/inactive/timeout event
continue;
}
// Skip if not an active/inactive event
if (!(event.intr_mask & (TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE))) {
continue;
}
bool is_touch_event = (event.intr_mask & TOUCH_PAD_INTR_MASK_ACTIVE) != 0;
// Find the child for the pad that triggered the interrupt
for (auto *child : this->children_) {
if (child->get_touch_pad() != event.pad) {
continue;
}
// Skip if state hasn't changed
if (child->last_state_ == is_touch_event) {
break;
}
// Read current value
uint32_t value = this->read_touch_value(event.pad);
child->last_state_ = is_touch_event;
child->publish_state(is_touch_event);
// Note: ESP32-S2/S3 v2 uses inverted logic compared to v1 - touched when value > threshold
ESP_LOGD(TAG, "Touch Pad '%s' %s (value: %d %s threshold: %d)", child->get_name().c_str(),
is_touch_event ? "touched" : "released", value, is_touch_event ? ">" : "<=", child->get_threshold());
// Check and update state
this->check_and_update_touch_state_(child);
break;
}
}