ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
ultrasonic_sensor.cpp
Go to the documentation of this file.
1#include "ultrasonic_sensor.h"
2#include "esphome/core/hal.h"
3#include "esphome/core/log.h"
4
6
7ESPHOME_LOG_TAG(TAG, "ultrasonic.sensor");
8
9static constexpr uint32_t DEBOUNCE_US = 50; // Ignore edges within 50us of each other (noise filtering)
10static constexpr uint32_t START_DELAY_US = 100; // Ignore edges within 100us of trigger (filters bleed-through)
11static constexpr uint32_t START_TIMEOUT_US = 40000; // Maximum time to wait for echo pulse to start
12
14 uint32_t now = micros();
15 // Ignore edges after measurement complete or too soon after trigger pulse
16 if (arg->echo_end || (now - arg->measurement_start_us) <= START_DELAY_US) {
17 return;
18 }
19 if (!arg->echo_start || (now - arg->echo_start_us) <= DEBOUNCE_US) {
20 arg->echo_start_us = now;
21 arg->echo_start = true;
22 } else {
23 arg->echo_end_us = now;
24 arg->echo_end = true;
25 }
26}
27
39
47
49 if (this->measurement_pending_) {
50 return;
51 }
52 this->send_trigger_pulse_();
53}
54
56 if (!this->measurement_pending_) {
57 return;
58 }
59
60 if (!this->store_.echo_start) {
61 uint32_t elapsed = micros() - this->measurement_start_us_;
62 if (elapsed >= START_TIMEOUT_US) {
63 ESP_LOGW(TAG, "'%s' - Measurement start timed out", LOG_STR_ARG(this->get_log_name()));
64 this->publish_state(NAN);
65 this->measurement_pending_ = false;
66 return;
67 }
68 } else {
69 uint32_t elapsed;
70 if (this->store_.echo_end) {
71 elapsed = this->store_.echo_end_us - this->store_.echo_start_us;
72 } else {
73 elapsed = micros() - this->store_.echo_start_us;
74 }
75 if (elapsed >= this->timeout_us_) {
76 ESP_LOGD(TAG, "'%s' - Measurement pulse timed out after %" PRIu32 "us", LOG_STR_ARG(this->get_log_name()),
77 elapsed);
78 this->publish_state(NAN);
79 this->measurement_pending_ = false;
80 return;
81 }
82 }
83
84 if (this->store_.echo_end) {
85 uint32_t pulse_duration = this->store_.echo_end_us - this->store_.echo_start_us;
86 ESP_LOGV(TAG, "Echo took %" PRIu32 "us", pulse_duration);
87 float result = UltrasonicSensorComponent::us_to_m(pulse_duration);
88 ESP_LOGD(TAG, "'%s' - Got distance: %.3f m", LOG_STR_ARG(this->get_log_name()), result);
89 this->publish_state(result);
90 this->measurement_pending_ = false;
91 return;
92 }
93}
94
96 LOG_SENSOR("", "Ultrasonic Sensor", this);
97 LOG_PIN(" Echo Pin: ", this->echo_pin_);
98 LOG_PIN(" Trigger Pin: ", this->trigger_pin_);
99 ESP_LOGCONFIG(TAG,
100 " Pulse time: %" PRIu32 " µs\n"
101 " Timeout: %" PRIu32 " µs",
102 this->pulse_time_us_, this->timeout_us_);
103 LOG_UPDATE_INTERVAL(this);
104}
105
107 const float speed_sound_m_per_s = 343.0f;
108 const float time_s = us / 1e6f;
109 const float total_dist = time_s * speed_sound_m_per_s;
110 return total_dist / 2.0f;
111}
112
113} // namespace esphome::ultrasonic
const LogString * get_log_name() const
Get the name for a "%s" log argument (LOG_STR_ARG).
void digital_write(bool value)
Definition gpio.cpp:227
Helper class to disable interrupts.
Definition helpers.h:2164
void attach_interrupt(void(*func)(T *), T *arg, gpio::InterruptType type) const
Definition gpio.h:29
void digital_write(bool value) override
Definition gpio.cpp:208
ISRInternalGPIOPin to_isr() const
Definition gpio.cpp:91
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:65
static float us_to_m(uint32_t us)
Helper function to convert the specified echo duration in µs to meters.
@ INTERRUPT_ANY_EDGE
Definition gpio_pin.h:54
ESPHOME_LOG_TAG(TAG, "ultrasonic.sensor")
void IRAM_ATTR HOT delayMicroseconds(uint32_t us)
Definition hal.cpp:48
uint32_t IRAM_ATTR HOT micros()
Definition hal.cpp:43
static void uint32_t
static void gpio_intr(UltrasonicSensorStore *arg)
SemaphoreHandle_t lock