ESPHome 2026.5.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
7static const char *const 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", this->name_.c_str());
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", this->name_.c_str(), elapsed);
77 this->publish_state(NAN);
78 this->measurement_pending_ = false;
79 return;
80 }
81 }
82
83 if (this->store_.echo_end) {
84 uint32_t pulse_duration = this->store_.echo_end_us - this->store_.echo_start_us;
85 ESP_LOGV(TAG, "Echo took %" PRIu32 "us", pulse_duration);
86 float result = UltrasonicSensorComponent::us_to_m(pulse_duration);
87 ESP_LOGD(TAG, "'%s' - Got distance: %.3f m", this->name_.c_str(), result);
88 this->publish_state(result);
89 this->measurement_pending_ = false;
90 return;
91 }
92}
93
95 LOG_SENSOR("", "Ultrasonic Sensor", this);
96 LOG_PIN(" Echo Pin: ", this->echo_pin_);
97 LOG_PIN(" Trigger Pin: ", this->trigger_pin_);
98 ESP_LOGCONFIG(TAG,
99 " Pulse time: %" PRIu32 " µs\n"
100 " Timeout: %" PRIu32 " µs",
101 this->pulse_time_us_, this->timeout_us_);
102 LOG_UPDATE_INTERVAL(this);
103}
104
106 const float speed_sound_m_per_s = 343.0f;
107 const float time_s = us / 1e6f;
108 const float total_dist = time_s * speed_sound_m_per_s;
109 return total_dist / 2.0f;
110}
111
112} // namespace esphome::ultrasonic
virtual void setup()=0
virtual void digital_write(bool value)=0
void digital_write(bool value)
Definition gpio.cpp:148
void attach_interrupt(void(*func)(T *), T *arg, gpio::InterruptType type) const
Definition gpio.h:107
virtual ISRInternalGPIOPin to_isr() const =0
Helper class to disable interrupts.
Definition helpers.h:2104
constexpr const char * c_str() const
Definition string_ref.h:73
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:68
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.h:52
void IRAM_ATTR HOT delayMicroseconds(uint32_t us)
Definition core.cpp:30
uint32_t IRAM_ATTR HOT micros()
Definition core.cpp:29
static void uint32_t
static void gpio_intr(UltrasonicSensorStore *arg)