Make the pulse meter timeout on startup when no pulses are received (#5388)

This commit is contained in:
Trent Houliston 2023-09-21 08:04:03 +10:00 committed by Jesse Hills
parent 7ebe6a5894
commit 807c47a076
No known key found for this signature in database
GPG key ID: BEAAE804EFD8E83A
2 changed files with 27 additions and 11 deletions

View file

@ -11,6 +11,9 @@ void PulseMeterSensor::setup() {
this->pin_->setup(); this->pin_->setup();
this->isr_pin_ = pin_->to_isr(); this->isr_pin_ = pin_->to_isr();
// Set the last processed edge to now for the first timeout
this->last_processed_edge_us_ = micros();
if (this->filter_mode_ == FILTER_EDGE) { if (this->filter_mode_ == FILTER_EDGE) {
this->pin_->attach_interrupt(PulseMeterSensor::edge_intr, this, gpio::INTERRUPT_RISING_EDGE); this->pin_->attach_interrupt(PulseMeterSensor::edge_intr, this, gpio::INTERRUPT_RISING_EDGE);
} else if (this->filter_mode_ == FILTER_PULSE) { } else if (this->filter_mode_ == FILTER_PULSE) {
@ -38,12 +41,16 @@ void PulseMeterSensor::loop() {
} }
// We need to detect at least two edges to have a valid pulse width // We need to detect at least two edges to have a valid pulse width
if (!this->initialized_) { switch (this->meter_state_) {
this->initialized_ = true; case MeterState::INITIAL:
} else { case MeterState::TIMED_OUT: {
uint32_t delta_us = this->get_->last_detected_edge_us_ - this->last_processed_edge_us_; this->meter_state_ = MeterState::RUNNING;
float pulse_width_us = delta_us / float(this->get_->count_); } break;
this->publish_state((60.0f * 1000000.0f) / pulse_width_us); case MeterState::RUNNING: {
uint32_t delta_us = this->get_->last_detected_edge_us_ - this->last_processed_edge_us_;
float pulse_width_us = delta_us / float(this->get_->count_);
this->publish_state((60.0f * 1000000.0f) / pulse_width_us);
} break;
} }
this->last_processed_edge_us_ = this->get_->last_detected_edge_us_; this->last_processed_edge_us_ = this->get_->last_detected_edge_us_;
@ -53,10 +60,18 @@ void PulseMeterSensor::loop() {
const uint32_t now = micros(); const uint32_t now = micros();
const uint32_t time_since_valid_edge_us = now - this->last_processed_edge_us_; const uint32_t time_since_valid_edge_us = now - this->last_processed_edge_us_;
if (this->initialized_ && time_since_valid_edge_us > this->timeout_us_) { switch (this->meter_state_) {
ESP_LOGD(TAG, "No pulse detected for %us, assuming 0 pulses/min", time_since_valid_edge_us / 1000000); // Running and initial states can timeout
this->initialized_ = false; case MeterState::INITIAL:
this->publish_state(0.0f); case MeterState::RUNNING: {
if (time_since_valid_edge_us > this->timeout_us_) {
this->meter_state_ = MeterState::TIMED_OUT;
ESP_LOGD(TAG, "No pulse detected for %us, assuming 0 pulses/min", time_since_valid_edge_us / 1000000);
this->publish_state(0.0f);
}
} break;
default:
break;
} }
} }
} }

View file

@ -38,7 +38,8 @@ class PulseMeterSensor : public sensor::Sensor, public Component {
InternalFilterMode filter_mode_{FILTER_EDGE}; InternalFilterMode filter_mode_{FILTER_EDGE};
// Variables used in the loop // Variables used in the loop
bool initialized_ = false; enum class MeterState { INITIAL, RUNNING, TIMED_OUT };
MeterState meter_state_ = MeterState::INITIAL;
uint32_t total_pulses_ = 0; uint32_t total_pulses_ = 0;
uint32_t last_processed_edge_us_ = 0; uint32_t last_processed_edge_us_ = 0;