ESPHome 2026.1.5
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 START_TIMEOUT_US = 40000; // Maximum time to wait for echo pulse to start
10
12 uint32_t now = micros();
13 if (arg->echo_pin_isr.digital_read()) {
14 arg->echo_start_us = now;
15 arg->echo_start = true;
16 } else {
17 arg->echo_end_us = now;
18 arg->echo_end = true;
19 }
20}
21
23 InterruptLock lock;
24 this->store_.echo_start_us = 0;
25 this->store_.echo_end_us = 0;
26 this->store_.echo_start = false;
27 this->store_.echo_end = false;
31 this->measurement_pending_ = true;
33}
34
43
45 if (this->measurement_pending_) {
46 return;
47 }
48 this->send_trigger_pulse_();
49}
50
52 if (!this->measurement_pending_) {
53 return;
54 }
55
56 if (!this->store_.echo_start) {
57 uint32_t elapsed = micros() - this->measurement_start_us_;
58 if (elapsed >= START_TIMEOUT_US) {
59 ESP_LOGW(TAG, "'%s' - Measurement start timed out", this->name_.c_str());
60 this->publish_state(NAN);
61 this->measurement_pending_ = false;
62 return;
63 }
64 } else {
65 uint32_t elapsed;
66 if (this->store_.echo_end) {
67 elapsed = this->store_.echo_end_us - this->store_.echo_start_us;
68 } else {
69 elapsed = micros() - this->store_.echo_start_us;
70 }
71 if (elapsed >= this->timeout_us_) {
72 ESP_LOGD(TAG, "'%s' - Measurement pulse timed out after %" PRIu32 "us", this->name_.c_str(), elapsed);
73 this->publish_state(NAN);
74 this->measurement_pending_ = false;
75 return;
76 }
77 }
78
79 if (this->store_.echo_end) {
80 float result;
81 if (this->store_.echo_start) {
82 uint32_t pulse_duration = this->store_.echo_end_us - this->store_.echo_start_us;
83 ESP_LOGV(TAG, "pulse start took %" PRIu32 "us, echo took %" PRIu32 "us",
84 this->store_.echo_start_us - this->measurement_start_us_, pulse_duration);
85 result = UltrasonicSensorComponent::us_to_m(pulse_duration);
86 ESP_LOGD(TAG, "'%s' - Got distance: %.3f m", this->name_.c_str(), result);
87 } else {
88 ESP_LOGW(TAG, "'%s' - pulse end before pulse start, does the echo pin need to be inverted?", this->name_.c_str());
89 result = NAN;
90 }
91 this->publish_state(result);
92 this->measurement_pending_ = false;
93 return;
94 }
95}
96
98 LOG_SENSOR("", "Ultrasonic Sensor", this);
99 LOG_PIN(" Echo Pin: ", this->echo_pin_);
100 LOG_PIN(" Trigger Pin: ", this->trigger_pin_);
101 ESP_LOGCONFIG(TAG,
102 " Pulse time: %" PRIu32 " µs\n"
103 " Timeout: %" PRIu32 " µs",
104 this->pulse_time_us_, this->timeout_us_);
105 LOG_UPDATE_INTERVAL(this);
106}
107
109 const float speed_sound_m_per_s = 343.0f;
110 const float time_s = us / 1e6f;
111 const float total_dist = time_s * speed_sound_m_per_s;
112 return total_dist / 2.0f;
113}
114
115} // 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:1322
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:76
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:28
uint32_t IRAM_ATTR HOT micros()
Definition core.cpp:27
static void gpio_intr(UltrasonicSensorStore *arg)