Pcnt esp32 arduino

Просьба подсказать пример использования аппаратного счетчика pcnt для esp32 в arduino для счета. В интернете есть примеры но они работали на старой версии 2.0.

Пример ниже компилируется без ошибок но не считает. Всю голову сломал.

#include <Arduino.h>
#include "driver/pulse_cnt.h"
pcnt_unit_handle_t pcnt_unit;
void setup() {
  Serial.begin(115200);
  //Создаём PCNT unit счетчик
  pcnt_unit_config_t unit_config = {0};
  unit_config.high_limit = 30000;     // Максимальное значение счетчика
  unit_config.low_limit = -1;         // Минимальное значение счетчика
  pcnt_unit = NULL;
  pcnt_new_unit(&unit_config, &pcnt_unit);
  //Создаём PCNT channel счетчик
  pcnt_chan_config_t channel_config = {0};
  channel_config.edge_gpio_num = 16;   // GPIO, к которому подключён датчик 
  channel_config.level_gpio_num = -1;  // Не используется
  pcnt_channel_handle_t pcnt_channel = NULL;
  pcnt_new_channel(pcnt_unit, &channel_config, &pcnt_channel);
  //Включаем фильтр debounce счетчик
  pcnt_glitch_filter_config_t filter_config = {0};
  filter_config.max_glitch_ns = 1000;
  pcnt_unit_set_glitch_filter(pcnt_unit, &filter_config);
  //Включаем unit и запускаем счёт счетчик
  pcnt_unit_enable(pcnt_unit);
  pcnt_unit_start(pcnt_unit);
}
void loop() {
  delay(1000);
  int count = 0; 
  pcnt_unit_get_count(pcnt_unit, &count);  // Считываем значение счетчика
//  pcnt_unit_clear_count(pcnt_unit);  // Сбросить счётчик для следующего измерения
  Serial.println(String(count));
}

так пусть разрабы ядра сами правят сотни проектов, или вы хотите что бы другие правили ?))) и что в этой версии есть такого что ее используете ?

#include <Arduino.h>
#include "driver/pulse_cnt.h"

// Конфигурация
#define PULSE_GPIO 16      // Нога для подсчета импульсов
#define PCNT_HIGH_LIMIT 30000
#define PCNT_LOW_LIMIT  -1

pcnt_unit_handle_t pcnt_unit = NULL;
pcnt_channel_handle_t pcnt_channel = NULL;

void setup() {
    Serial.begin(115200);
    delay(1000); // Даем время на запуск монитора порта
    Serial.println("Starting PCNT...");

    // 1. Настройка UNIT (верхний/нижний лимит)
    pcnt_unit_config_t unit_config = {
        .high_limit = PCNT_HIGH_LIMIT,
        .low_limit = PCNT_LOW_LIMIT,
        .flags = {
            .accum_count = 1, // Накапливать счетчик (рекомендуется)
        }
    };
    ESP_ERROR_CHECK(pcnt_new_unit(&unit_config, &pcnt_unit));

    // 2. Настройка фильтра дребезга (опционально)
    pcnt_glitch_filter_config_t filter_config = {
        .max_glitch_ns = 1000 // 1 мкс
    };
    ESP_ERROR_CHECK(pcnt_unit_set_glitch_filter(pcnt_unit, &filter_config));

    // 3. Настройка CHANNEL (какой GPIO слушаем)
    pcnt_chan_config_t chan_config = {
        .edge_gpio_num = PULSE_GPIO,
        .level_gpio_num = -1, // Не используется
    };
    ESP_ERROR_CHECK(pcnt_new_channel(pcnt_unit, &chan_config, &pcnt_channel));

    // 4. *** КЛЮЧЕВОЙ МОМЕНТ ***
    // Говорим каналу, что делать при нарастающем и спадающем фронте
    ESP_ERROR_CHECK(pcnt_channel_set_edge_action(pcnt_channel,
                                                PCNT_CHANNEL_EDGE_ACTION_INCREASE, // По нарастающему фронту увеличиваем
                                                PCNT_CHANNEL_EDGE_ACTION_HOLD));   // По спадающему ничего не делаем

    // 5. Включаем и стартуем
    ESP_ERROR_CHECK(pcnt_unit_enable(pcnt_unit));
    ESP_ERROR_CHECK(pcnt_unit_clear_count(pcnt_unit)); // Обнуляем перед стартом
    ESP_ERROR_CHECK(pcnt_unit_start(pcnt_unit));

    Serial.println("PCNT started. Send pulses to GPIO 16");
}

void loop() {
    delay(1000);
    int count = 0;
    esp_err_t err = pcnt_unit_get_count(pcnt_unit, &count);
    if (err == ESP_OK) {
        Serial.printf("Count: %d\n", count);
    } else {
        Serial.printf("Error reading count: %d\n", err);
    }
    
    // Если нужен подсчет за интервал, а не накопление:
    // pcnt_unit_clear_count(pcnt_unit); // Раскомментируйте для сброса каждую секунду
}
1 лайк

Вот за что я люблю наш форум, это за способность удивлять и заряжать позитивом! :wink:

int count = 42;
Serial.println(String(count)); // Выведет “42”

Serial.println(count); // Выведет “42”

Serial.printf(“Count: %d\n”, count); // Выведет “Count: 42”

Serial.print("Count: ");
Serial.println(count); // Выведет “Count: 42”

а то видите ли камешки в огород мне кидают…
но я человек не злопамятный, отомщу раз 10 и забуду)))

Заработало Спасибо! 2 выходных убил на решение по счетчику.

Serial.println(String(count)) ну это у меня осталось от uint32_t Pr=0; lcd.print(String(Pr)); дисплей не понимает такое количество знаков цифры. наспех урезал код для форума.

Компилятор жаловался Порядок указания поля ‘pcnt_unit_config_t::low_limit’ не соответствует порядку объявления в ‘pcnt_unit_config_t’

    pcnt_unit_config_t unit_config = {
        .high_limit = PCNT_HIGH_LIMIT,
        .low_limit = PCNT_LOW_LIMIT,
        .flags = {
            .accum_count = 1, // Накапливать счетчик (рекомендуется)
        }
    };

Заменил на
pcnt_unit_config_t unit_config = {0};

unit_config.high_limit = PCNT_HIGH_LIMIT; // Максимальное значение счетчика

unit_config.low_limit = PCNT_LOW_LIMIT; // Минимальное значение счетчика

1 лайк

Не обращай внимания. Это паранойный варнинг, сейчас он вообще не актуален.

В конце кконцов, вы платите деньги за килобайты и мегагерцы для чего? Чтобы они простаивали? :slight_smile: