ESPHome  2024.11.0
pulse_counter_sensor.cpp
Go to the documentation of this file.
1 #include "pulse_counter_sensor.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace pulse_counter {
6 
7 static const char *const TAG = "pulse_counter";
8 
9 const char *const EDGE_MODE_TO_STRING[] = {"DISABLE", "INCREMENT", "DECREMENT"};
10 
11 #ifdef HAS_PCNT
13  return (hw_pcnt ? (PulseCounterStorageBase *) (new HwPulseCounterStorage)
15 }
16 #else
18 #endif
19 
21  const uint32_t now = micros();
22  const bool discard = now - arg->last_pulse < arg->filter_us;
23  arg->last_pulse = now;
24  if (discard)
25  return;
26 
28  switch (mode) {
30  break;
32  arg->counter++;
33  break;
35  arg->counter--;
36  break;
37  }
38 }
40  this->pin = pin;
41  this->pin->setup();
42  this->isr_pin = this->pin->to_isr();
44  return true;
45 }
48  pulse_counter_t ret = counter - this->last_value;
49  this->last_value = counter;
50  return ret;
51 }
52 
53 #ifdef HAS_PCNT
55  static pcnt_unit_t next_pcnt_unit = PCNT_UNIT_0;
56  static pcnt_channel_t next_pcnt_channel = PCNT_CHANNEL_0;
57  this->pin = pin;
58  this->pin->setup();
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);
65  }
66 
67  ESP_LOGCONFIG(TAG, " PCNT Unit Number: %u", this->pcnt_unit);
68  ESP_LOGCONFIG(TAG, " PCNT Channel Number: %u", this->pcnt_channel);
69 
70  pcnt_count_mode_t rising = PCNT_COUNT_DIS, falling = PCNT_COUNT_DIS;
71  switch (this->rising_edge_mode) {
73  rising = PCNT_COUNT_DIS;
74  break;
76  rising = PCNT_COUNT_INC;
77  break;
79  rising = PCNT_COUNT_DEC;
80  break;
81  }
82  switch (this->falling_edge_mode) {
84  falling = PCNT_COUNT_DIS;
85  break;
87  falling = PCNT_COUNT_INC;
88  break;
90  falling = PCNT_COUNT_DEC;
91  break;
92  }
93 
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,
99  .pos_mode = rising,
100  .neg_mode = falling,
101  .counter_h_lim = 0,
102  .counter_l_lim = 0,
103  .unit = this->pcnt_unit,
104  .channel = this->pcnt_channel,
105  };
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));
109  return false;
110  }
111 
112  if (this->filter_us != 0) {
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));
118  return false;
119  }
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));
123  return false;
124  }
125  }
126 
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));
130  return false;
131  }
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));
135  return false;
136  }
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));
140  return false;
141  }
142  return true;
143 }
146  pcnt_get_counter_value(this->pcnt_unit, &counter);
147  pulse_counter_t ret = counter - this->last_value;
148  this->last_value = counter;
149  return ret;
150 }
151 #endif
152 
154  ESP_LOGCONFIG(TAG, "Setting up pulse counter '%s'...", this->name_.c_str());
155  if (!this->storage_.pulse_counter_setup(this->pin_)) {
156  this->mark_failed();
157  return;
158  }
159 }
160 
162  this->current_total_ = pulses;
163  this->total_sensor_->publish_state(pulses);
164 }
165 
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);
173 }
174 
176  pulse_counter_t raw = this->storage_.read_raw_value();
177  uint32_t now = millis();
178  if (this->last_time_ != 0) {
179  uint32_t interval = now - this->last_time_;
180  float value = (60000.0f * raw) / float(interval); // per minute
181  ESP_LOGD(TAG, "'%s': Retrieved counter: %0.2f pulses/min", this->get_name().c_str(), value);
182  this->publish_state(value);
183  }
184 
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_);
189  }
190  this->last_time_ = now;
191 }
192 
193 } // namespace pulse_counter
194 } // namespace esphome
void setup() override
Unit of measurement is "pulses/min".
uint8_t raw[35]
Definition: bl0939.h:19
const char *const EDGE_MODE_TO_STRING[]
PulseCounterStorageBase * get_storage(bool hw_pcnt)
virtual void setup()=0
uint32_t IRAM_ATTR HOT micros()
Definition: core.cpp:27
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:25
bool pulse_counter_setup(InternalGPIOPin *pin) override
virtual uint8_t get_pin() const =0
BedjetMode mode
BedJet operating mode.
Definition: bedjet_codec.h:183
bool pulse_counter_setup(InternalGPIOPin *pin) override
virtual ISRInternalGPIOPin to_isr() const =0
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
static void gpio_intr(BasicPulseCounterStorage *arg)
void attach_interrupt(void(*func)(T *), T *arg, gpio::InterruptType type) const
Definition: gpio.h:81