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;
56 static pcnt_channel_t next_pcnt_channel = PCNT_CHANNEL_0;
59 this->pcnt_unit = next_pcnt_unit;
60 this->pcnt_channel = next_pcnt_channel;
61 next_pcnt_unit = pcnt_unit_t(
int(next_pcnt_unit) + 1);
62 if (
int(next_pcnt_unit) >= PCNT_UNIT_0 + PCNT_UNIT_MAX) {
63 next_pcnt_unit = PCNT_UNIT_0;
64 next_pcnt_channel = pcnt_channel_t(
int(next_pcnt_channel) + 1);
67 ESP_LOGCONFIG(TAG,
" PCNT Unit Number: %u", this->pcnt_unit);
68 ESP_LOGCONFIG(TAG,
" PCNT Channel Number: %u", this->pcnt_channel);
70 pcnt_count_mode_t rising = PCNT_COUNT_DIS, falling = PCNT_COUNT_DIS;
73 rising = PCNT_COUNT_DIS;
76 rising = PCNT_COUNT_INC;
79 rising = PCNT_COUNT_DEC;
84 falling = PCNT_COUNT_DIS;
87 falling = PCNT_COUNT_INC;
90 falling = PCNT_COUNT_DEC;
94 pcnt_config_t pcnt_config = {
95 .pulse_gpio_num = this->pin->
get_pin(),
96 .ctrl_gpio_num = PCNT_PIN_NOT_USED,
97 .lctrl_mode = PCNT_MODE_KEEP,
98 .hctrl_mode = PCNT_MODE_KEEP,
103 .unit = this->pcnt_unit,
104 .channel = this->pcnt_channel,
106 esp_err_t error = pcnt_unit_config(&pcnt_config);
107 if (error != ESP_OK) {
108 ESP_LOGE(TAG,
"Configuring Pulse Counter failed: %s", esp_err_to_name(error));
113 uint16_t filter_val = std::min(static_cast<unsigned int>(this->
filter_us * 80u), 1023u);
114 ESP_LOGCONFIG(TAG,
" Filter Value: %" PRIu32
"us (val=%u)", this->
filter_us, filter_val);
115 error = pcnt_set_filter_value(this->pcnt_unit, filter_val);
116 if (error != ESP_OK) {
117 ESP_LOGE(TAG,
"Setting filter value failed: %s", esp_err_to_name(error));
120 error = pcnt_filter_enable(this->pcnt_unit);
121 if (error != ESP_OK) {
122 ESP_LOGE(TAG,
"Enabling filter failed: %s", esp_err_to_name(error));
127 error = pcnt_counter_pause(this->pcnt_unit);
128 if (error != ESP_OK) {
129 ESP_LOGE(TAG,
"Pausing pulse counter failed: %s", esp_err_to_name(error));
132 error = pcnt_counter_clear(this->pcnt_unit);
133 if (error != ESP_OK) {
134 ESP_LOGE(TAG,
"Clearing pulse counter failed: %s", esp_err_to_name(error));
137 error = pcnt_counter_resume(this->pcnt_unit);
138 if (error != ESP_OK) {
139 ESP_LOGE(TAG,
"Resuming pulse counter failed: %s", esp_err_to_name(error));
146 pcnt_get_counter_value(this->pcnt_unit, &counter);
154 ESP_LOGCONFIG(TAG,
"Setting up pulse counter '%s'...", this->name_.c_str());
155 if (!this->storage_.pulse_counter_setup(this->pin_)) {
162 this->current_total_ = pulses;
163 this->total_sensor_->publish_state(pulses);
167 LOG_SENSOR(
"",
"Pulse Counter",
this);
168 LOG_PIN(
" Pin: ", this->pin_);
169 ESP_LOGCONFIG(TAG,
" Rising Edge: %s", EDGE_MODE_TO_STRING[this->storage_.rising_edge_mode]);
170 ESP_LOGCONFIG(TAG,
" Falling Edge: %s", EDGE_MODE_TO_STRING[this->storage_.falling_edge_mode]);
171 ESP_LOGCONFIG(TAG,
" Filtering pulses shorter than %" PRIu32
" µs", this->storage_.filter_us);
172 LOG_UPDATE_INTERVAL(
this);
178 if (this->last_time_ != 0) {
179 uint32_t interval = now - this->last_time_;
180 float value = (60000.0f *
raw) /
float(interval);
181 ESP_LOGD(TAG,
"'%s': Retrieved counter: %0.2f pulses/min", this->get_name().c_str(), value);
182 this->publish_state(value);
185 if (this->total_sensor_ !=
nullptr) {
186 current_total_ +=
raw;
187 ESP_LOGD(TAG,
"'%s': Total : %" PRIu32
" pulses", this->get_name().c_str(), current_total_);
188 this->total_sensor_->publish_state(current_total_);
190 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