5#if ESP_ARDUINO_VERSION_MAJOR < 3
6#warning "The Pulse Counter API is only available in ESP32 Arduino Core 3.0.0 and later"
8#include "driver/pulse_cnt.h"
12DigitalInputPcntCounter::DigitalInputPcntCounter(uint8_t pin,
int pin_mode,
14 unsigned int read_delay,
18 read_delay_(read_delay),
19 interrupt_type_(interrupt_type) {
22 ESP_ERROR_CHECK(configurePcnt(interrupt_type));
29 ESP_ERROR_CHECK(pcnt_unit_get_count(pcnt_unit_, &count));
30 ESP_ERROR_CHECK(pcnt_unit_clear_count(pcnt_unit_));
36DigitalInputPcntCounter::~DigitalInputPcntCounter() {
39 err = pcnt_del_channel(pcnt_channel_);
41 ESP_LOGE(
"PCNT",
"Failed to delete PCNT channel: %s", esp_err_to_name(err));
45 err = pcnt_unit_stop(pcnt_unit_);
47 ESP_LOGE(
"PCNT",
"Failed to stop PCNT unit: %s", esp_err_to_name(err));
49 err = pcnt_unit_disable(pcnt_unit_);
51 ESP_LOGE(
"PCNT",
"Failed to disable PCNT unit: %s", esp_err_to_name(err));
53 err = pcnt_del_unit(pcnt_unit_);
55 ESP_LOGE(
"PCNT",
"Failed to delete PCNT unit: %s", esp_err_to_name(err));
60esp_err_t DigitalInputPcntCounter::configurePcnt(
int interrupt_mode) {
61 pcnt_unit_config_t unit_config = {
63 .high_limit = INT16_MAX,
66 ESP_ERROR_CHECK(pcnt_new_unit(&unit_config, &pcnt_unit_));
68 pcnt_chan_config_t chan_config = {.edge_gpio_num = pin_,
70 .flags = {.invert_edge_input =
false,
71 .invert_level_input =
false,
72 .virt_edge_io_level = 0,
73 .virt_level_io_level = 0,
74 .io_loop_back =
false}};
76 ESP_ERROR_CHECK(pcnt_new_channel(pcnt_unit_, &chan_config, &pcnt_channel_));
78 pcnt_channel_edge_action_t edge_action_pos =
79 (interrupt_mode == RISING || interrupt_mode == CHANGE)
80 ? PCNT_CHANNEL_EDGE_ACTION_INCREASE
81 : PCNT_CHANNEL_EDGE_ACTION_HOLD;
82 pcnt_channel_edge_action_t edge_action_neg =
83 (interrupt_mode == FALLING || interrupt_mode == CHANGE)
84 ? PCNT_CHANNEL_EDGE_ACTION_INCREASE
85 : PCNT_CHANNEL_EDGE_ACTION_HOLD;
86 ESP_ERROR_CHECK(pcnt_channel_set_edge_action(pcnt_channel_, edge_action_pos,
89 ESP_ERROR_CHECK(pcnt_unit_enable(pcnt_unit_));
90 ESP_ERROR_CHECK(pcnt_unit_clear_count(pcnt_unit_));
92 return pcnt_unit_start(pcnt_unit_);
95bool DigitalInputPcntCounter::to_json(JsonObject& root) {
96 root[
"read_delay"] = read_delay_;
100bool DigitalInputPcntCounter::from_json(
const JsonObject& config) {
101 String
const expected[] = {
"read_delay"};
102 for (
auto str : expected) {
103 if (!config[str].is<JsonVariant>()) {
107 read_delay_ = config[
"read_delay"];
111const String
ConfigSchema(
const DigitalInputPcntCounter& obj) {
112 return R
"###({"type":"object","properties":{"read_delay":{"title":"Read delay","type":"number","description":"The time, in milliseconds, between each read of the input"}} })###";
Sensor template class for any sensor producing actual values.
const String ConfigSchema(const SmartSwitchController &obj)
std::shared_ptr< reactesp::EventLoop > event_loop()
bool ConfigRequiresRestart(const HTTPServer &obj)