5 namespace pulse_counter {
7 static const char *
const TAG =
"pulse_counter";
21 const uint32_t now =
micros();
59 static pcnt_unit_t next_pcnt_unit = PCNT_UNIT_0;
60 static pcnt_channel_t next_pcnt_channel = PCNT_CHANNEL_0;
63 this->pcnt_unit = next_pcnt_unit;
64 this->pcnt_channel = next_pcnt_channel;
65 next_pcnt_unit = pcnt_unit_t(
int(next_pcnt_unit) + 1);
66 if (
int(next_pcnt_unit) >= PCNT_UNIT_0 + PCNT_UNIT_MAX) {
67 next_pcnt_unit = PCNT_UNIT_0;
68 next_pcnt_channel = pcnt_channel_t(
int(next_pcnt_channel) + 1);
71 ESP_LOGCONFIG(TAG,
" PCNT Unit Number: %u", this->pcnt_unit);
72 ESP_LOGCONFIG(TAG,
" PCNT Channel Number: %u", this->pcnt_channel);
74 pcnt_count_mode_t rising = PCNT_COUNT_DIS, falling = PCNT_COUNT_DIS;
77 rising = PCNT_COUNT_DIS;
80 rising = PCNT_COUNT_INC;
83 rising = PCNT_COUNT_DEC;
88 falling = PCNT_COUNT_DIS;
91 falling = PCNT_COUNT_INC;
94 falling = PCNT_COUNT_DEC;
98 pcnt_config_t pcnt_config = {
99 .pulse_gpio_num = this->pin->
get_pin(),
100 .ctrl_gpio_num = PCNT_PIN_NOT_USED,
101 .lctrl_mode = PCNT_MODE_KEEP,
102 .hctrl_mode = PCNT_MODE_KEEP,
107 .unit = this->pcnt_unit,
108 .channel = this->pcnt_channel,
110 esp_err_t error = pcnt_unit_config(&pcnt_config);
111 if (error != ESP_OK) {
112 ESP_LOGE(TAG,
"Configuring Pulse Counter failed: %s", esp_err_to_name(error));
117 uint16_t filter_val = std::min(static_cast<unsigned int>(this->
filter_us * 80u), 1023u);
118 ESP_LOGCONFIG(TAG,
" Filter Value: %" PRIu32
"us (val=%u)", this->
filter_us, filter_val);
119 error = pcnt_set_filter_value(this->pcnt_unit, filter_val);
120 if (error != ESP_OK) {
121 ESP_LOGE(TAG,
"Setting filter value failed: %s", esp_err_to_name(error));
124 error = pcnt_filter_enable(this->pcnt_unit);
125 if (error != ESP_OK) {
126 ESP_LOGE(TAG,
"Enabling filter failed: %s", esp_err_to_name(error));
131 error = pcnt_counter_pause(this->pcnt_unit);
132 if (error != ESP_OK) {
133 ESP_LOGE(TAG,
"Pausing pulse counter failed: %s", esp_err_to_name(error));
136 error = pcnt_counter_clear(this->pcnt_unit);
137 if (error != ESP_OK) {
138 ESP_LOGE(TAG,
"Clearing pulse counter failed: %s", esp_err_to_name(error));
141 error = pcnt_counter_resume(this->pcnt_unit);
142 if (error != ESP_OK) {
143 ESP_LOGE(TAG,
"Resuming pulse counter failed: %s", esp_err_to_name(error));
151 pcnt_get_counter_value(this->pcnt_unit, &counter);
159 ESP_LOGCONFIG(TAG,
"Setting up pulse counter '%s'...", this->name_.c_str());
160 if (!this->storage_.pulse_counter_setup(this->pin_)) {
167 this->current_total_ = pulses;
168 this->total_sensor_->publish_state(pulses);
172 LOG_SENSOR(
"",
"Pulse Counter",
this);
173 LOG_PIN(
" Pin: ", this->pin_);
174 ESP_LOGCONFIG(TAG,
" Rising Edge: %s", EDGE_MODE_TO_STRING[this->storage_.rising_edge_mode]);
175 ESP_LOGCONFIG(TAG,
" Falling Edge: %s", EDGE_MODE_TO_STRING[this->storage_.falling_edge_mode]);
176 ESP_LOGCONFIG(TAG,
" Filtering pulses shorter than %" PRIu32
" µs", this->storage_.filter_us);
177 LOG_UPDATE_INTERVAL(
this);
183 if (this->last_time_ != 0) {
184 uint32_t interval = now - this->last_time_;
185 float value = (60000.0f *
raw) /
float(interval);
186 ESP_LOGD(TAG,
"'%s': Retrieved counter: %0.2f pulses/min", this->get_name().c_str(), value);
187 this->publish_state(value);
190 if (this->total_sensor_ !=
nullptr) {
191 current_total_ +=
raw;
192 ESP_LOGD(TAG,
"'%s': Total : %" PRIu32
" pulses", this->get_name().c_str(), current_total_);
193 this->total_sensor_->publish_state(current_total_);
195 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
Implementation of SPI Controller mode.
static void gpio_intr(BasicPulseCounterStorage *arg)
void attach_interrupt(void(*func)(T *), T *arg, gpio::InterruptType type) const
PulseCounterCountMode falling_edge_mode