Using the “Pulse Count Controller” (PCNT)

CMakeLists.txt REQUIRES

Ensure the following is added to the REQUIRES section of your CMakeLists.txt file in the \main folder:

	REQUIRES

			driver

Configuring

#include "driver/pulse_cnt.h"

#define PCNT_UNIT1_COUNTER_MAX				1000

	//-----------------------------------------------
	//----- SETUP PCNT (Pulse Count Controller) -----
	//-----------------------------------------------

	//pcnt_unit_handle_t PcntUnit1 = NULL;				//Create the PCNT handle for our counter

	//INSTALL PCNT UNIT
	pcnt_unit_config_t unit_config = {
		.high_limit = PCNT_UNIT1_COUNTER_MAX,				//High limitation of the count unit, should be higher than 0 (int, max 16bit-depends on hardware) The counter will reset to zero automatically when it crosses either the high or low limit.
		.low_limit = -100,				//Low limitation of the count unit, should be lower than 0 (int, max 16bit-depends on hardware) The counter will reset to zero automatically when it crosses either the high or low limit.
		//Other options also available
	};
	ESP_ERROR_CHECK(pcnt_new_unit(&unit_config, &PcntUnit1));

	//SET GLITCH FILTER
	pcnt_glitch_filter_config_t filter_config = {
		.max_glitch_ns = 10000,			//Pulse width smaller than this threshold will be treated as glitch and ignored, in the unit of ns (uint32_t, but seems you can't actually use a massive value)
	};
	ESP_ERROR_CHECK(pcnt_unit_set_glitch_filter(PcntUnit1, &filter_config));

	//INSTALL PCNT CHANNELS
	pcnt_chan_config_t chan_a_config = {
		.edge_gpio_num = 21,			//GPIO number used by the edge signal, input mode with pull up enabled. Set to -1 if unused
		.level_gpio_num = -1			//GPIO number used by the level signal, input mode with pull up enabled. Set to -1 if unused
		//Other options also available
	};
	pcnt_channel_handle_t pcnt_chan_a = NULL;
	ESP_ERROR_CHECK(pcnt_new_channel(PcntUnit1, &chan_a_config, &pcnt_chan_a));

	//SET EDGE AND LEVEL ACTIONS FOR PCNT CHANNELS
	//Configure for falling edge increments count
	ESP_ERROR_CHECK(pcnt_channel_set_edge_action(pcnt_chan_a, PCNT_CHANNEL_EDGE_ACTION_HOLD, PCNT_CHANNEL_EDGE_ACTION_INCREASE));		//PCNT_CHANNEL_EDGE_ACTION_HOLD, PCNT_CHANNEL_EDGE_ACTION_INCREASE, PCNT_CHANNEL_EDGE_ACTION_DECREASE

	//ADD WATCH POINTS AND REGISTER CALLBACKS
	//You can use this to trigger a callback when a certain value is reached

	//ENABLE PCNT UNIT
	ESP_ERROR_CHECK(pcnt_unit_enable(PcntUnit1));

	//CLEAR PCNT UNIT
	ESP_ERROR_CHECK(pcnt_unit_clear_count(PcntUnit1));

	//START PCNT UNIT
	ESP_ERROR_CHECK(pcnt_unit_start(PcntUnit1));

Reading value

	int PulseCount = 0;
	ESP_ERROR_CHECK(pcnt_unit_get_count(PcntUnit1, &PulseCount));		//Returned count value is a signed integer
	ESP_LOGI(TAG, "Pulse count: %d", PulseCount);
More useful version
	static int PulseCountLast = 0;
	int PulseCount;
	int PulsesSinceLastTime;
	
	PulseCount = 0;
	ESP_ERROR_CHECK(pcnt_unit_get_count(PcntUnit1, &PulseCount));		//Returned count value is a signed integer

	if (PulseCount >= PulseCountLast)
		PulsesSinceLastTime = PulseCount - PulseCountLast;
	else
		PulsesSinceLastTime = PulseCount - PulseCountLast + PCNT_UNIT1_COUNTER_MAX;

	PulseCountLast = PulseCount;

	ESP_LOGI(TAG, "New pulses: %d", PulsesSinceLastTime);