1
0
mirror of https://github.com/esphome/esphome.git synced 2026-02-08 00:31:58 +00:00

[ultrasonic] adjust timeouts and bring the parameter back (#13738)

Co-authored-by: Samuel Sieb <samuel@sieb.net>
This commit is contained in:
Samuel Sieb
2026-02-04 01:29:27 -08:00
committed by Jesse Hills
parent 900aab45f1
commit bafbd4235a
5 changed files with 50 additions and 26 deletions

View File

@@ -528,7 +528,7 @@ esphome/components/uart/packet_transport/* @clydebarrow
esphome/components/udp/* @clydebarrow
esphome/components/ufire_ec/* @pvizeli
esphome/components/ufire_ise/* @pvizeli
esphome/components/ultrasonic/* @OttoWinter
esphome/components/ultrasonic/* @ssieb @swoboda1337
esphome/components/update/* @jesserockz
esphome/components/uponor_smatrix/* @kroimon
esphome/components/usb_cdc_acm/* @kbx81

View File

@@ -1 +1 @@
CODEOWNERS = ["@OttoWinter"]
CODEOWNERS = ["@swoboda1337", "@ssieb"]

View File

@@ -34,7 +34,7 @@ CONFIG_SCHEMA = (
{
cv.Required(CONF_TRIGGER_PIN): pins.internal_gpio_output_pin_schema,
cv.Required(CONF_ECHO_PIN): pins.internal_gpio_input_pin_schema,
cv.Optional(CONF_TIMEOUT): cv.distance,
cv.Optional(CONF_TIMEOUT, default="2m"): cv.distance,
cv.Optional(
CONF_PULSE_TIME, default="10us"
): cv.positive_time_period_microseconds,
@@ -52,12 +52,5 @@ async def to_code(config):
cg.add(var.set_trigger_pin(trigger))
echo = await cg.gpio_pin_expression(config[CONF_ECHO_PIN])
cg.add(var.set_echo_pin(echo))
# Remove before 2026.8.0
if CONF_TIMEOUT in config:
_LOGGER.warning(
"'timeout' option is deprecated and will be removed in 2026.8.0. "
"The option has no effect and can be safely removed."
)
cg.add(var.set_timeout_us(config[CONF_TIMEOUT] / (0.000343 / 2)))
cg.add(var.set_pulse_time_us(config[CONF_PULSE_TIME]))

View File

@@ -6,12 +6,11 @@ namespace esphome::ultrasonic {
static const char *const TAG = "ultrasonic.sensor";
static constexpr uint32_t DEBOUNCE_US = 50; // Ignore edges within 50us (noise filtering)
static constexpr uint32_t MEASUREMENT_TIMEOUT_US = 80000; // Maximum time to wait for measurement completion
static constexpr uint32_t START_TIMEOUT_US = 40000; // Maximum time to wait for echo pulse to start
void IRAM_ATTR UltrasonicSensorStore::gpio_intr(UltrasonicSensorStore *arg) {
uint32_t now = micros();
if (!arg->echo_start || (now - arg->echo_start_us) <= DEBOUNCE_US) {
if (arg->echo_pin_isr.digital_read()) {
arg->echo_start_us = now;
arg->echo_start = true;
} else {
@@ -38,6 +37,7 @@ void UltrasonicSensorComponent::setup() {
this->trigger_pin_->digital_write(false);
this->trigger_pin_isr_ = this->trigger_pin_->to_isr();
this->echo_pin_->setup();
this->store_.echo_pin_isr = this->echo_pin_->to_isr();
this->echo_pin_->attach_interrupt(UltrasonicSensorStore::gpio_intr, &this->store_, gpio::INTERRUPT_ANY_EDGE);
}
@@ -53,21 +53,44 @@ void UltrasonicSensorComponent::loop() {
return;
}
if (this->store_.echo_end) {
uint32_t pulse_duration = this->store_.echo_end_us - this->store_.echo_start_us;
ESP_LOGV(TAG, "Echo took %" PRIu32 "us", pulse_duration);
float result = UltrasonicSensorComponent::us_to_m(pulse_duration);
ESP_LOGD(TAG, "'%s' - Got distance: %.3f m", this->name_.c_str(), result);
this->publish_state(result);
if (!this->store_.echo_start) {
uint32_t elapsed = micros() - this->measurement_start_us_;
if (elapsed >= START_TIMEOUT_US) {
ESP_LOGW(TAG, "'%s' - Measurement start timed out", this->name_.c_str());
this->publish_state(NAN);
this->measurement_pending_ = false;
return;
}
uint32_t elapsed = micros() - this->measurement_start_us_;
if (elapsed >= MEASUREMENT_TIMEOUT_US) {
ESP_LOGD(TAG, "'%s' - Measurement timed out after %" PRIu32 "us", this->name_.c_str(), elapsed);
} else {
uint32_t elapsed;
if (this->store_.echo_end) {
elapsed = this->store_.echo_end_us - this->store_.echo_start_us;
} else {
elapsed = micros() - this->store_.echo_start_us;
}
if (elapsed >= this->timeout_us_) {
ESP_LOGD(TAG, "'%s' - Measurement pulse timed out after %" PRIu32 "us", this->name_.c_str(), elapsed);
this->publish_state(NAN);
this->measurement_pending_ = false;
return;
}
}
if (this->store_.echo_end) {
float result;
if (this->store_.echo_start) {
uint32_t pulse_duration = this->store_.echo_end_us - this->store_.echo_start_us;
ESP_LOGV(TAG, "pulse start took %" PRIu32 "us, echo took %" PRIu32 "us",
this->store_.echo_start_us - this->measurement_start_us_, pulse_duration);
result = UltrasonicSensorComponent::us_to_m(pulse_duration);
ESP_LOGD(TAG, "'%s' - Got distance: %.3f m", this->name_.c_str(), result);
} else {
ESP_LOGW(TAG, "'%s' - pulse end before pulse start, does the echo pin need to be inverted?", this->name_.c_str());
result = NAN;
}
this->publish_state(result);
this->measurement_pending_ = false;
return;
}
}
@@ -75,7 +98,10 @@ void UltrasonicSensorComponent::dump_config() {
LOG_SENSOR("", "Ultrasonic Sensor", this);
LOG_PIN(" Echo Pin: ", this->echo_pin_);
LOG_PIN(" Trigger Pin: ", this->trigger_pin_);
ESP_LOGCONFIG(TAG, " Pulse time: %" PRIu32 " us", this->pulse_time_us_);
ESP_LOGCONFIG(TAG,
" Pulse time: %" PRIu32 " µs\n"
" Timeout: %" PRIu32 " µs",
this->pulse_time_us_, this->timeout_us_);
LOG_UPDATE_INTERVAL(this);
}

View File

@@ -11,6 +11,8 @@ namespace esphome::ultrasonic {
struct UltrasonicSensorStore {
static void gpio_intr(UltrasonicSensorStore *arg);
ISRInternalGPIOPin echo_pin_isr;
volatile uint32_t wait_start_us{0};
volatile uint32_t echo_start_us{0};
volatile uint32_t echo_end_us{0};
volatile bool echo_start{false};
@@ -29,6 +31,8 @@ class UltrasonicSensorComponent : public sensor::Sensor, public PollingComponent
float get_setup_priority() const override { return setup_priority::DATA; }
/// Set the maximum time in µs to wait for the echo to return
void set_timeout_us(uint32_t timeout_us) { this->timeout_us_ = timeout_us; }
/// Set the time in µs the trigger pin should be enabled for in µs, defaults to 10µs (for HC-SR04)
void set_pulse_time_us(uint32_t pulse_time_us) { this->pulse_time_us_ = pulse_time_us; }
@@ -41,6 +45,7 @@ class UltrasonicSensorComponent : public sensor::Sensor, public PollingComponent
ISRInternalGPIOPin trigger_pin_isr_;
InternalGPIOPin *echo_pin_;
UltrasonicSensorStore store_;
uint32_t timeout_us_{};
uint32_t pulse_time_us_{};
uint32_t measurement_start_us_{0};