mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 23:21:54 +00:00 
			
		
		
		
	fixes
This commit is contained in:
		| @@ -160,6 +160,9 @@ class ESP32TouchComponent : public Component { | |||||||
|   // Returns the current touch pad value using either filtered or raw reading |   // Returns the current touch pad value using either filtered or raw reading | ||||||
|   // based on the filter configuration |   // based on the filter configuration | ||||||
|   uint32_t read_touch_value(touch_pad_t pad) const; |   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 | #endif | ||||||
|  |  | ||||||
|   // Helper functions for dump_config - common to both implementations |   // Helper functions for dump_config - common to both implementations | ||||||
|   | |||||||
| @@ -10,6 +10,22 @@ namespace esp32_touch { | |||||||
|  |  | ||||||
| static const char *const TAG = "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() { | void ESP32TouchComponent::setup() { | ||||||
|   // Create queue for touch events first |   // Create queue for touch events first | ||||||
|   if (!this->create_touch_queue_()) { |   if (!this->create_touch_queue_()) { | ||||||
| @@ -103,15 +119,11 @@ void ESP32TouchComponent::setup() { | |||||||
|     // Read current value |     // Read current value | ||||||
|     uint32_t value = this->read_touch_value(child->get_touch_pad()); |     uint32_t value = this->read_touch_value(child->get_touch_pad()); | ||||||
|  |  | ||||||
|     // IMPORTANT: ESP32-S2/S3 v2 touch detection logic - INVERTED compared to v1! |     // Set initial state and publish | ||||||
|     // 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) |  | ||||||
|     bool is_touched = value > child->get_threshold(); |     bool is_touched = value > child->get_threshold(); | ||||||
|     child->last_state_ = is_touched; |     child->last_state_ = is_touched; | ||||||
|     child->publish_initial_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(), |     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()); |              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) { |     if (event.intr_mask & TOUCH_PAD_INTR_MASK_TIMEOUT) { | ||||||
|       // Resume measurement after timeout |       // Resume measurement after timeout | ||||||
|       touch_pad_timeout_resume(); |       touch_pad_timeout_resume(); | ||||||
|  |       // For timeout events, always check the current state | ||||||
|       // For timeout events, we should check if the pad is actually touched |     } else if (!(event.intr_mask & (TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE))) { | ||||||
|       // Timeout occurs when a pad stays above threshold for too long |       // Skip if not an active/inactive/timeout event | ||||||
|       for (auto *child : this->children_) { |  | ||||||
|         if (child->get_touch_pad() != event.pad) { |  | ||||||
|       continue; |       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; |  | ||||||
|       } |  | ||||||
|       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 |     // Find the child for the pad that triggered the interrupt | ||||||
|     for (auto *child : this->children_) { |     for (auto *child : this->children_) { | ||||||
|       if (child->get_touch_pad() != event.pad) { |       if (child->get_touch_pad() != event.pad) { | ||||||
|         continue; |         continue; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       // Skip if state hasn't changed |       // Check and update state | ||||||
|       if (child->last_state_ == is_touch_event) { |       this->check_and_update_touch_state_(child); | ||||||
|         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()); |  | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user