Hi,
I have a project that uses two Pulse Counters from the ESP32 Espressif library: Pulse Counter (PCNT) - ESP32 - — ESP-IDF Programming Guide v5.0 documentation
Both counters should have a high limit of e.g. 125 counts/pulses which should trigger the corresponding interrupt, problem is that it does not trigger my events with an output and it overwrites the values with 0 instead of keeping it stored.
Below is an excerpt of my code and serial output.
Code:
#include <driver/adc.h>
#include <driver/pcnt.h>
// ESP32 Pulse Counter
#define PCNT_UNIT_01 PCNT_UNIT_0 // Select the Pulse Count 0
#define PCNT_UNIT_02 PCNT_UNIT_1 // Select the Pulse Count 1
#define PCNT_H_LIM_VAL 125 // Set the high limit count to trigger the interrupt
#define PCNT_L_LIM_VAL 0 // Set the low limit count to trigger the interrupt
#define PCNT_FILTER_VAL 256 // Set the filter value in nanoseconds, 1 second = 1 000 000 000 nanoseconds
#define PCNT_INPUT_SIG_IO_01 13 // Pulse Input selected as GPIO14
#define PCNT_INPUT_SIG_IO_02 14 // Pulse Input selected as GPIO12
pcnt_isr_handle_t user_isr_handle1 = NULL; // User ISR handler for Interrupt
pcnt_isr_handle_t user_isr_handle2 = NULL; // User ISR handler for Interrupt
...
void setup()
{
pinMode(13, INPUT_PULLUP); // Set pin13 (GPIO14) input for capturing GM Tube 01 events (pulses)
pinMode(14, INPUT_PULLUP); // Set pin14 (GPIO12) input for capturing GM Tube 02 events (pulses)
Init_PulseCounter_01();
Init_PulseCounter_02();
...
}
void loop()
{
if(event1)
{
Serial.println(F("--- ISR ---"));
Serial.println("| Counter of tube 1 exceeded the value of " + String(PCNT_H_LIM_VAL));
Serial.println(F("--- ISR ---"));
event1 = false;
}
if(event2)
{
Serial.println(F("--- ISR ---"));
Serial.println("| Counter of tube 2 exceeded the value of " + String(PCNT_H_LIM_VAL));
Serial.println(F("--- ISR ---"));
event2 = false;
}
// If reached 01 seconds with a total of 60 seconds
if (((millis() - previousMillis_1) >= 1000UL) && (increaseSecCount <= 60))
{
//int16_t count_01 = 0;
pcnt_get_counter_value(PCNT_UNIT_01, &cps_1);
pcnt_get_counter_value(PCNT_UNIT_02, &cps_2);
// Recalute with tube dead time accounted for actual CPS of both tubes
actual_cps_1 = (cps_1 / (1 - (cps_1 * tubeDeadTime)));
actual_cps_2 = (cps_2 / (1 - (cps_2 * tubeDeadTime)));
// Add a new datapoint entry for both tubes to the moving average array
sensorMovingAvg = cps_sensor.reading(actual_cps_1);
sensorMovingAvg = cps_sensor.reading(actual_cps_2);
....
// If 61 seconds have been reached do uploads and reset vars
if (((millis() - previousMillis_3) >= 61000UL) && (increaseSecCount >= 61))
{
...
Clean_Counters();
}
}
// ISR Function for counter 1
void IRAM_ATTR Counter1_ISR(void *arg)
{
cps_1 = pcnt_get_counter_value(PCNT_UNIT_01, &cps_1);
event1 = true;
Serial.println("Counter1_ISR triggered");
if(user_isr_handle1)
{
//Free the ISR service handle.
esp_intr_free(user_isr_handle1);
user_isr_handle1 = NULL;
}
}
// ISR Function for counter 2
void IRAM_ATTR Counter2_ISR(void *arg)
{
cps_2 = pcnt_get_counter_value(PCNT_UNIT_02, &cps_2);
event2 = true;
Serial.println("Counter2_ISR triggered");
if(user_isr_handle2)
{
//Free the ISR service handle.
esp_intr_free(user_isr_handle2);
user_isr_handle2 = NULL;
}
}
void Init_PulseCounter_01(void)
{
pcnt_config_t pcnt_config_01 = { };
pcnt_config_01.pulse_gpio_num = PCNT_INPUT_SIG_IO_01; // Set pulse input GPIO member
pcnt_config_01.pos_mode = PCNT_COUNT_INC; // Set Counter mode: pos_mode – Counter mode when detecting positive edge
pcnt_config_01.counter_h_lim = PCNT_H_LIM_VAL; // Set maximum counter value = triggers event
pcnt_config_01.unit = PCNT_UNIT_01; // Select pulse unit
pcnt_config_01.channel = PCNT_CHANNEL_0; // Select PCNT channel
pcnt_unit_config(&pcnt_config_01); // Configure PCNT
pcnt_set_filter_value(PCNT_UNIT_01, PCNT_FILTER_VAL); // Set filter value
pcnt_filter_enable(PCNT_UNIT_01); // Enable filter
pcnt_event_enable(PCNT_UNIT_01, PCNT_EVT_H_LIM); // Enable event for when PCNT watch point event: Maximum counter value
pcnt_event_enable(PCNT_UNIT_01, PCNT_EVT_L_LIM);
pcnt_isr_register(Counter1_ISR, NULL, 0, &user_isr_handle1); // Set call back function for the Event
pcnt_intr_enable(PCNT_UNIT_01); // Enable Pulse Counter (PCNT)
pcnt_counter_pause(PCNT_UNIT_01); // Pause PCNT counter
pcnt_counter_clear(PCNT_UNIT_01); // Clear PCNT counter
pcnt_counter_resume(PCNT_UNIT_01);
Serial.println(F("PCNT_01 Init Completed"));
}
void Init_PulseCounter_02(void)
{
pcnt_config_t pcnt_config_02 = { };
pcnt_config_02.pulse_gpio_num = PCNT_INPUT_SIG_IO_02; // Set pulse input GPIO member
pcnt_config_02.pos_mode = PCNT_COUNT_INC; // Set Counter mode: pos_mode – Counter mode when detecting positive edge
pcnt_config_02.counter_h_lim = PCNT_H_LIM_VAL; // Set maximum counter value = triggers event
pcnt_config_02.unit = PCNT_UNIT_02; // Select pulse unit
pcnt_config_02.channel = PCNT_CHANNEL_0; // Select PCNT channel
pcnt_unit_config(&pcnt_config_02); // Configure PCNT
pcnt_set_filter_value(PCNT_UNIT_02, PCNT_FILTER_VAL); // Set filter value
pcnt_filter_enable(PCNT_UNIT_02); // Enable filter
pcnt_event_enable(PCNT_UNIT_01, PCNT_EVT_H_LIM); // Enable event for when PCNT watch point event: Maximum counter value
pcnt_event_enable(PCNT_UNIT_01, PCNT_EVT_L_LIM);
pcnt_isr_register(Counter2_ISR, NULL, 0, &user_isr_handle2); // Set call back function for the Event
pcnt_intr_enable(PCNT_UNIT_02); // Enable Pulse Counter (PCNT)
pcnt_counter_pause(PCNT_UNIT_02); // Pause PCNT counter
pcnt_counter_clear(PCNT_UNIT_02); // Clear PCNT counter
pcnt_counter_resume(PCNT_UNIT_02);
Serial.println(F("PCNT_02 Init Completed"));
}
// Function to clean the Counter and its variables
void Clean_Counters()
{
pcnt_counter_pause(PCNT_UNIT_01); // Pause Pulse counters such that we can set event
pcnt_counter_pause(PCNT_UNIT_02);
pcnt_counter_clear(PCNT_UNIT_01); // Clean Pulse Counters
pcnt_counter_clear(PCNT_UNIT_02);
pcnt_counter_resume(PCNT_UNIT_01); // Resume Pulse Counters
pcnt_counter_resume(PCNT_UNIT_02);
}
Serial output except:
Event 1:
19:39:03.928 -> --- 01 sec ---
19:39:03.928 -> | Tube 1 33 sec current count (cps_1) = 123
19:39:03.928 -> | Tube 2 33 sec current count (cps_2) = 44
19:39:03.928 -> | Tubes current total mavg 33 sec current count = 60
19:39:03.968 -> | Voltage tubes = 436.745
19:39:03.968 -> --- 01 sec ---
19:39:03.968 -> 33 of 60
--- THERE SHOULD BE AN OUTPUT HERE FROM EVENT1 ---
19:39:04.934 -> --- 01 sec ---
19:39:04.934 -> | Tube 1 34 sec current count (cps_1) = 2
19:39:04.934 -> | Tube 2 34 sec current count (cps_2) = 50
19:39:04.934 -> | Tubes current total mavg 34 sec current count = 59
19:39:04.981 -> | Voltage tubes = 435.981
19:39:04.981 -> --- 01 sec ---
Event 2:
19:37:16.041 -> --- 01 sec ---
19:37:16.041 -> | Tube 1 54 sec current count (cps_1) = 76
19:37:16.041 -> | Tube 2 54 sec current count (cps_2) = 125
19:37:16.041 -> | Tubes current total mavg 54 sec current count = 58
19:37:16.041 -> | Voltage tubes = 435.675
19:37:16.041 -> --- 01 sec ---
19:37:16.041 -> 54 of 60
--- THERE SHOULD BE AN OUTPUT HERE FROM EVENT2 ---
19:37:17.054 -> --- 01 sec ---
19:37:17.054 -> | Tube 1 55 sec current count (cps_1) = 78
19:37:17.054 -> | Tube 2 55 sec current count (cps_2) = 3
19:37:17.054 -> | Tubes current total mavg 55 sec current count = 58
19:37:17.054 -> | Voltage tubes = 433.536
19:37:17.054 -> --- 01 sec ---
Probably its something small I'm overlooking.
Thanks!