5 namespace pulse_counter {
7 static const char *
const TAG =
"pulse_counter";
21 const uint32_t now =
micros();
55 static pcnt_unit_t next_pcnt_unit = PCNT_UNIT_0;
58 this->pcnt_unit = next_pcnt_unit;
59 next_pcnt_unit = pcnt_unit_t(
int(next_pcnt_unit) + 1);
61 ESP_LOGCONFIG(TAG,
" PCNT Unit Number: %u", this->pcnt_unit);
63 pcnt_count_mode_t rising = PCNT_COUNT_DIS, falling = PCNT_COUNT_DIS;
66 rising = PCNT_COUNT_DIS;
69 rising = PCNT_COUNT_INC;
72 rising = PCNT_COUNT_DEC;
77 falling = PCNT_COUNT_DIS;
80 falling = PCNT_COUNT_INC;
83 falling = PCNT_COUNT_DEC;
87 pcnt_config_t pcnt_config = {
88 .pulse_gpio_num = this->pin->
get_pin(),
89 .ctrl_gpio_num = PCNT_PIN_NOT_USED,
90 .lctrl_mode = PCNT_MODE_KEEP,
91 .hctrl_mode = PCNT_MODE_KEEP,
96 .unit = this->pcnt_unit,
97 .channel = PCNT_CHANNEL_0,
99 esp_err_t error = pcnt_unit_config(&pcnt_config);
100 if (error != ESP_OK) {
101 ESP_LOGE(TAG,
"Configuring Pulse Counter failed: %s", esp_err_to_name(error));
106 uint16_t filter_val = std::min(static_cast<unsigned int>(this->
filter_us * 80u), 1023u);
107 ESP_LOGCONFIG(TAG,
" Filter Value: %uus (val=%u)", this->
filter_us, filter_val);
108 error = pcnt_set_filter_value(this->pcnt_unit, filter_val);
109 if (error != ESP_OK) {
110 ESP_LOGE(TAG,
"Setting filter value failed: %s", esp_err_to_name(error));
113 error = pcnt_filter_enable(this->pcnt_unit);
114 if (error != ESP_OK) {
115 ESP_LOGE(TAG,
"Enabling filter failed: %s", esp_err_to_name(error));
120 error = pcnt_counter_pause(this->pcnt_unit);
121 if (error != ESP_OK) {
122 ESP_LOGE(TAG,
"Pausing pulse counter failed: %s", esp_err_to_name(error));
125 error = pcnt_counter_clear(this->pcnt_unit);
126 if (error != ESP_OK) {
127 ESP_LOGE(TAG,
"Clearing pulse counter failed: %s", esp_err_to_name(error));
130 error = pcnt_counter_resume(this->pcnt_unit);
131 if (error != ESP_OK) {
132 ESP_LOGE(TAG,
"Resuming pulse counter failed: %s", esp_err_to_name(error));
139 pcnt_get_counter_value(this->pcnt_unit, &counter);
147 ESP_LOGCONFIG(TAG,
"Setting up pulse counter '%s'...", this->name_.c_str());
148 if (!this->storage_.pulse_counter_setup(this->pin_)) {
155 this->current_total_ = pulses;
156 this->total_sensor_->publish_state(pulses);
160 LOG_SENSOR(
"",
"Pulse Counter",
this);
161 LOG_PIN(
" Pin: ", this->pin_);
162 ESP_LOGCONFIG(TAG,
" Rising Edge: %s", EDGE_MODE_TO_STRING[this->storage_.rising_edge_mode]);
163 ESP_LOGCONFIG(TAG,
" Falling Edge: %s", EDGE_MODE_TO_STRING[this->storage_.falling_edge_mode]);
164 ESP_LOGCONFIG(TAG,
" Filtering pulses shorter than %u µs", this->storage_.filter_us);
165 LOG_UPDATE_INTERVAL(
this);
171 if (this->last_time_ != 0) {
172 uint32_t interval = now - this->last_time_;
173 float value = (60000.0f *
raw) /
float(interval);
174 ESP_LOGD(TAG,
"'%s': Retrieved counter: %0.2f pulses/min", this->get_name().c_str(), value);
175 this->publish_state(value);
178 if (this->total_sensor_ !=
nullptr) {
179 current_total_ +=
raw;
180 ESP_LOGD(TAG,
"'%s': Total : %i pulses", this->get_name().c_str(), current_total_);
181 this->total_sensor_->publish_state(current_total_);
183 this->last_time_ = now;
void setup() override
Unit of measurement is "pulses/min".
const char *const EDGE_MODE_TO_STRING[]
PulseCounterCountMode rising_edge_mode
PulseCounterStorageBase * get_storage(bool hw_pcnt)
ISRInternalGPIOPin isr_pin
uint32_t IRAM_ATTR HOT micros()
uint32_t IRAM_ATTR HOT millis()
pulse_counter_t read_raw_value() override
bool pulse_counter_setup(InternalGPIOPin *pin) override
virtual uint8_t get_pin() const =0
void dump_config() override
volatile uint32_t last_pulse
BedjetMode mode
BedJet operating mode.
void set_total_pulses(uint32_t pulses)
bool pulse_counter_setup(InternalGPIOPin *pin) override
virtual ISRInternalGPIOPin to_isr() const =0
pulse_counter_t last_value
pulse_counter_t read_raw_value() override
volatile pulse_counter_t counter
static void gpio_intr(BasicPulseCounterStorage *arg)
void attach_interrupt(void(*func)(T *), T *arg, gpio::InterruptType type) const
PulseCounterCountMode falling_edge_mode