mirror of
https://github.com/esphome/esphome.git
synced 2024-11-27 17:27:59 +01:00
pulse_counter_ulp: Store mean_exec_time in Ulp Program
This lets the estimated interval survive sleep, and finally provide reasonable interval estimates over deep sleep periods.
This commit is contained in:
parent
2b453289a9
commit
4a8907d70d
3 changed files with 28 additions and 24 deletions
|
@ -57,6 +57,7 @@ std::unique_ptr<UlpProgram> UlpProgram::start(gpio_num_t gpio_num, microseconds
|
||||||
ulp_debounce_max_count = 3;
|
ulp_debounce_max_count = 3;
|
||||||
ulp_next_edge = 0;
|
ulp_next_edge = 0;
|
||||||
ulp_io_number = rtcio_num; /* map from GPIO# to RTC_IO# */
|
ulp_io_number = rtcio_num; /* map from GPIO# to RTC_IO# */
|
||||||
|
ulp_mean_exec_time = sleep_duration / microseconds{1};
|
||||||
|
|
||||||
/* Initialize selected GPIO as RTC IO, enable input */
|
/* Initialize selected GPIO as RTC IO, enable input */
|
||||||
rtc_gpio_init(gpio_num);
|
rtc_gpio_init(gpio_num);
|
||||||
|
@ -78,19 +79,23 @@ std::unique_ptr<UlpProgram> UlpProgram::start(gpio_num_t gpio_num, microseconds
|
||||||
return std::unique_ptr<UlpProgram>(new UlpProgram());
|
return std::unique_ptr<UlpProgram>(new UlpProgram());
|
||||||
}
|
}
|
||||||
|
|
||||||
UlpProgram::state UlpProgram::pop_state() {
|
UlpProgram::State UlpProgram::pop_state() {
|
||||||
// TODO count edges separately
|
// TODO count edges separately
|
||||||
auto edge_count = static_cast<uint16_t>(ulp_edge_count);
|
State state = UlpProgram::peek_state();
|
||||||
auto run_count = static_cast<uint16_t>(ulp_run_count);
|
|
||||||
ulp_edge_count = 0;
|
ulp_edge_count = 0;
|
||||||
ulp_run_count = 0;
|
ulp_run_count = 0;
|
||||||
return {.edge_count = edge_count, .run_count = run_count};
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
UlpProgram::state UlpProgram::peek_state() const {
|
UlpProgram::State UlpProgram::peek_state() const {
|
||||||
auto edge_count = static_cast<uint16_t>(ulp_edge_count);
|
auto edge_count = static_cast<uint16_t>(ulp_edge_count);
|
||||||
auto run_count = static_cast<uint16_t>(ulp_run_count);
|
auto run_count = static_cast<uint16_t>(ulp_run_count);
|
||||||
return {.edge_count = edge_count, .run_count = run_count};
|
auto mean_exec_time = microseconds{1} * static_cast<uint16_t>(ulp_mean_exec_time);
|
||||||
|
return {.edge_count = edge_count, .run_count = run_count, .mean_exec_time = mean_exec_time};
|
||||||
|
}
|
||||||
|
|
||||||
|
void UlpProgram::set_mean_exec_time(microseconds mean_exec_time) {
|
||||||
|
ulp_mean_exec_time = static_cast<uint16_t>(mean_exec_time / microseconds{1});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* === END ULP ===*/
|
/* === END ULP ===*/
|
||||||
|
@ -106,9 +111,9 @@ void PulseCounterUlpSensor::setup() {
|
||||||
this->rising_edge_mode, this->falling_edge_mode);
|
this->rising_edge_mode, this->falling_edge_mode);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGD(TAG, "Woke up from sleep, skipping set-up of ULP program");
|
ESP_LOGD(TAG, "Woke up from sleep, skipping set-up of ULP program");
|
||||||
// TODO need to store estimate in UlpProgram and load it in load. Maybe.
|
this->storage_ = std::unique_ptr<UlpProgram>(new UlpProgram);
|
||||||
// this->storage_ = UlpProgram::load();
|
UlpProgram::State state = this->storage_->peek_state();
|
||||||
// this->last_time = clock::now() - this->storage_->peek_state().run_count * this->storage_->estimate ;
|
this->last_time_ = clock::now() - state.run_count * state.mean_exec_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->storage_) {
|
if (!this->storage_) {
|
||||||
|
@ -135,16 +140,13 @@ void PulseCounterUlpSensor::update() {
|
||||||
if (!this->storage_) {
|
if (!this->storage_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UlpProgram::state raw = this->storage_->pop_state();
|
UlpProgram::State raw = this->storage_->pop_state();
|
||||||
clock::time_point now = clock::now();
|
clock::time_point now = clock::now();
|
||||||
clock::duration interval = now - this->last_time_;
|
clock::duration interval = now - this->last_time_;
|
||||||
auto estimated_interval = ulp_mean_exec_time_ * raw.run_count;
|
|
||||||
if (interval != clock::duration::zero()) {
|
if (interval != clock::duration::zero()) {
|
||||||
ulp_mean_exec_time_ = interval / static_cast<float>(raw.run_count);
|
this->storage_->set_mean_exec_time(std::chrono::duration_cast<microseconds>(interval / raw.run_count));
|
||||||
float value = std::chrono::minutes{1} * static_cast<float>(raw.edge_count) / interval; // pulses per minute
|
float value = std::chrono::minutes{1} * static_cast<float>(raw.edge_count) / interval; // pulses per minute
|
||||||
ESP_LOGD(TAG, "'%s': Retrieved counter: %0.2f pulses/min", this->get_name().c_str(), value);
|
ESP_LOGD(TAG, "'%s': Retrieved counter: %0.2f pulses/min", this->get_name().c_str(), value);
|
||||||
ESP_LOGD(TAG, "'%s': Interval: %0.2f\nEstimated: %0.2f", this->get_name().c_str(),
|
|
||||||
1.0f * interval / std::chrono::seconds{1}, 1.0f * estimated_interval / std::chrono::seconds{1});
|
|
||||||
this->publish_state(value);
|
this->publish_state(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,16 +20,17 @@ using microseconds = std::chrono::duration<uint32_t, std::micro>;
|
||||||
|
|
||||||
class UlpProgram {
|
class UlpProgram {
|
||||||
public:
|
public:
|
||||||
struct state {
|
struct State {
|
||||||
uint16_t edge_count;
|
uint16_t edge_count;
|
||||||
uint16_t run_count;
|
uint16_t run_count;
|
||||||
|
microseconds mean_exec_time;
|
||||||
};
|
};
|
||||||
state pop_state();
|
State pop_state();
|
||||||
state peek_state() const;
|
State peek_state() const;
|
||||||
|
void set_mean_exec_time(microseconds mean_exec_time);
|
||||||
|
|
||||||
static std::unique_ptr<UlpProgram> start(gpio_num_t gpio_num, microseconds sleep_duration, CountMode rising_edge_mode,
|
static std::unique_ptr<UlpProgram> start(gpio_num_t gpio_num, microseconds sleep_duration, CountMode rising_edge_mode,
|
||||||
CountMode falling_edge_mode);
|
CountMode falling_edge_mode);
|
||||||
// static std::unique_ptr<UlpProgram> load();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PulseCounterUlpSensor : public sensor::Sensor, public PollingComponent {
|
class PulseCounterUlpSensor : public sensor::Sensor, public PollingComponent {
|
||||||
|
@ -39,11 +40,7 @@ class PulseCounterUlpSensor : public sensor::Sensor, public PollingComponent {
|
||||||
void set_pin(InternalGPIOPin *pin) { pin_ = pin; }
|
void set_pin(InternalGPIOPin *pin) { pin_ = pin; }
|
||||||
void set_rising_edge_mode(CountMode mode) { this->rising_edge_mode = mode; }
|
void set_rising_edge_mode(CountMode mode) { this->rising_edge_mode = mode; }
|
||||||
void set_falling_edge_mode(CountMode mode) { this->falling_edge_mode = mode; }
|
void set_falling_edge_mode(CountMode mode) { this->falling_edge_mode = mode; }
|
||||||
void set_sleep_duration(uint32_t duration_us) {
|
void set_sleep_duration(uint32_t duration_us) { this->sleep_duration_ = duration_us * microseconds{1}; }
|
||||||
this->sleep_duration_ = duration_us * microseconds{1};
|
|
||||||
// Initial estimate assumes sleep duration >> execution time
|
|
||||||
this->ulp_mean_exec_time_ = duration_us * microseconds{1};
|
|
||||||
}
|
|
||||||
void set_total_sensor(sensor::Sensor *total_sensor) { total_sensor_ = total_sensor; }
|
void set_total_sensor(sensor::Sensor *total_sensor) { total_sensor_ = total_sensor; }
|
||||||
|
|
||||||
void set_total_pulses(uint32_t pulses);
|
void set_total_pulses(uint32_t pulses);
|
||||||
|
@ -60,7 +57,6 @@ class PulseCounterUlpSensor : public sensor::Sensor, public PollingComponent {
|
||||||
CountMode falling_edge_mode{CountMode::disable};
|
CountMode falling_edge_mode{CountMode::disable};
|
||||||
std::unique_ptr<UlpProgram> storage_{};
|
std::unique_ptr<UlpProgram> storage_{};
|
||||||
clock::time_point last_time_{};
|
clock::time_point last_time_{};
|
||||||
std::chrono::duration<float> ulp_mean_exec_time_{};
|
|
||||||
microseconds sleep_duration_{20000};
|
microseconds sleep_duration_{20000};
|
||||||
uint32_t current_total_{0};
|
uint32_t current_total_{0};
|
||||||
sensor::Sensor *total_sensor_{nullptr};
|
sensor::Sensor *total_sensor_{nullptr};
|
||||||
|
|
|
@ -71,6 +71,12 @@ edge_count_total:
|
||||||
io_number:
|
io_number:
|
||||||
.long 0
|
.long 0
|
||||||
|
|
||||||
|
/* Estimate of how long each execution of the ULP program takes. Managed
|
||||||
|
* entirely by main program, it is only defined here to survive deep sleep */
|
||||||
|
.global mean_exec_time
|
||||||
|
mean_exec_time:
|
||||||
|
.long 0
|
||||||
|
|
||||||
/* Code goes into .text section */
|
/* Code goes into .text section */
|
||||||
.text
|
.text
|
||||||
.global entry
|
.global entry
|
||||||
|
|
Loading…
Reference in a new issue