How to use "Pulse Counter" module usage under Arduino framework

Zyv_vz
Posts: 1
Joined: Tue Mar 10, 2020 3:49 pm

How to use "Pulse Counter" module usage under Arduino framework

Postby Zyv_vz » Tue Mar 10, 2020 3:58 pm

Hello,

I am using the Arduino framework in PlatformIO and wanted to use the Pulse Counter module.

How do I configure and use this module using the Arduino framework?

I have seen the reference https://docs.espressif.com/projects/esp ... t_config_t but as far as I'm concerned it is used some kind of structure.

technerdchris
Posts: 3
Joined: Thu May 28, 2020 4:11 pm

Re: How to use "Pulse Counter" module usage under Arduino framework

Postby technerdchris » Mon Jun 01, 2020 8:17 pm

Yes, that is a structure for initializing the PCNT hardware. I have made more steps than you in Arduino, however I have not yet been able to make it work. I am normally very good at taking code snippets and getting a solution. For example, to initialize the struct with the declaration, you must provide all members in the proper order for it to compile in Arduino IDE.

Below is some code I believe required. On my computer, I was able to open the pcnt.h file for reading in the following folder:
C: \ Users \ yourusername \ Documents \ ArduinoData \ packages \ esp32 \ hardware \ esp32 \ 1.0.2 \ tools \ sdk \ include \ driver \ driver

At this point, I am beginning to believe esp-idf is required to make PCNT module operational. When I started on ESP32 last year, I was not able to successfully install the tool chain to operate in windows 10, so I use Arduino IDE. At this point, I am disappointed in my project because of failure to make PCNT work, so I will watch the milli()s pass for my test and also the m5stack UI code is not sufficiently ready for me to employ it for my program. It is elaborate, however seemingly impossible to have it continuously display a status on the screen. So now I have to build x,y and program the entire UI also.
  1. #include "driver/pcnt.h"
  2. #define COUNT_PIN       17  // the gpio I output pulses on which I want to count
  3. pcnt_config_t pcnt_config = {
  4.         .pulse_gpio_num = COUNT_PIN,    // set gpio for pulse input gpio
  5.         .ctrl_gpio_num = -1,            // no gpio for control
  6.         .lctrl_mode = PCNT_MODE_KEEP,   // when control signal is low, keep the primary counter mode
  7.         .hctrl_mode = PCNT_MODE_KEEP,   // when control signal is high, keep the primary counter mode
  8.         .pos_mode = PCNT_COUNT_INC,     // increment the counter on positive edge
  9.         .neg_mode = PCNT_COUNT_DIS,     // do nothing on falling edge
  10.         .counter_h_lim = 2500,
  11.         .counter_l_lim = 0,
  12.         .unit = PCNT_UNIT_0,               /*!< PCNT unit number */
  13.         .channel = PCNT_CHANNEL_0
  14.     };
  15. // https://esp32.com/viewtopic.php?t=6737
  16. pcnt_isr_handle_t user_isr_handle = NULL; //user's ISR service handle
  17. unsigned int test_count = 2500;
  18. void setup() {
  19.     // possible problem, esp_idf mentions pin mode IN_OUT but that is not in arduino. So I tried shorting
  20.     // my pulse output pin to adjacent gpio and look at this input. Still didn't work for me.
  21.     pinMode(COUNT_PIN,INPUT);
  22.     pcnt_unit_config(&pcnt_config);        //init unit
  23.     pcnt_set_filter_value(PCNT_UNIT_0, test_count);
  24.     pcnt_filter_enable(PCNT_UNIT_0);
  25.     /* Register ISR handler and enable interrupts for PCNT unit */
  26.     pcnt_isr_register(pcnt_intr_handler, NULL, 0, &user_isr_handle);
  27.     pcnt_intr_enable(PCNT_UNIT_0);
  28.  
  29.     /* Everything is set up, now go to counting */
  30.     pcnt_counter_resume(PCNT_UNIT_0);
  31. }
  32.  
  33. static void pcnt_intr_handler(void *arg) {
  34.     test = false;
  35.     if(user_isr_handle) {
  36.         //Free the ISR service handle.
  37.         esp_intr_free(user_isr_handle);
  38.         user_isr_handle = NULL;
  39.     }
  40. }

User avatar
jgustavoam
Posts: 88
Joined: Thu Feb 01, 2018 2:43 pm
Location: Belo Horizonte , Brazil
Contact:

Re: How to use "Pulse Counter" module usage under Arduino framework

Postby jgustavoam » Wed Jun 17, 2020 2:28 am

Hi,
This code (part of sketch) was tested and running OK. Comments in portuguese.

Code: Select all

#include "driver/pcnt.h"                                  // Biblioteca de pulse count

#define PCNT_FREQ_UNIT      PCNT_UNIT_0                   // Unidade de Pulse Count 0 
#define PCNT_H_LIM_VAL      10000                        // Limite superior de contagem 32767 
#define PCNT_INPUT_SIG_IO   4                             // Pulse Input GPIO 4 

int16_t contador = 0;                                     // Contador de pulsos - valor max 65536
int contadorOverflow;                                     // Contador de overflow do Contador de Pulsos
float frequencia = 0;                                     // Frequencia medida
String unidade;                                           // Unidade de medida da escala
unsigned long tempo;                                      // base de tempo da medida dos pulsos
int prescaler;                                            // Divisor de frequencia do Timer
bool contadorOK = false;

pcnt_isr_handle_t user_isr_handle = NULL;                 // handler da interrupção - não usado
hw_timer_t * timer = NULL;                                // Instancia do timer

//------------------------------------------------------------------------------------
void IRAM_ATTR overflowContador(void *arg)                // Rotina de interrupção de overflow do Contador
{
  contadorOverflow = contadorOverflow + 1;                // soma contador de overflow
  PCNT.int_clr.val = BIT(PCNT_FREQ_UNIT);                 // Limpa flag de overflow
  pcnt_counter_clear(PCNT_FREQ_UNIT);                     // Zera e reseta o Contador de Pulsos
}

//------------------------------------------------------------
void iniciaContadorPulsos ()
{
  pcnt_config_t pcntFreqConfig = { };                        // Instancia do Contador de Pulsos
  pcntFreqConfig.pulse_gpio_num = PCNT_INPUT_SIG_IO;         // Port de entrada dos pulsos  = GPIO 4
  pcntFreqConfig.pos_mode = PCNT_COUNT_INC;                  // Conta na subida do pulso
  pcntFreqConfig.counter_h_lim = PCNT_H_LIM_VAL;             // Limite maximo de contagem
  pcntFreqConfig.unit = PCNT_FREQ_UNIT;                      // Unidade 0 do Contador de Pulsos
  pcntFreqConfig.channel = PCNT_CHANNEL_0;                   // Canal 0 da Unidade 0 Contador de Pulsos
  pcnt_unit_config(&pcntFreqConfig);                         // configura os registradores do Contador de Pulsos

  pcnt_counter_pause(PCNT_FREQ_UNIT);                        // pausa o Contador de Pulsos
  pcnt_counter_clear(PCNT_FREQ_UNIT);                        // Zera e reseta o Contador de Pulsos

  pcnt_event_enable(PCNT_FREQ_UNIT, PCNT_EVT_H_LIM);         // Ativa evento - interrupção no limite maximo de contagem
  pcnt_isr_register(overflowContador, NULL, 0, &user_isr_handle);  // configura registrador da interrupção
  pcnt_intr_enable(PCNT_FREQ_UNIT);                          // habilita as interrupções do Contador de Pulsos

  pcnt_counter_resume(PCNT_FREQ_UNIT);                       // reinicia o Contador de Pulsos
}

//------------------------------------------------------------
void baseTempo()                                            // Rotina de leitura do contador de pulsos (Base de tempo)
{
  pcnt_get_counter_value(PCNT_FREQ_UNIT, &contador);        // obtem o valor do contador de pulsos - valor max 16 bits
  contadorOverflow = 0;                                     // zera o contador de overflow
  pcnt_counter_clear(PCNT_FREQ_UNIT);                       // Zera e reseta o Contador de Pulsos
  contadorOK = true;
}
Retired IBM Brasil
Electronic hobbyist since 1976.

Who is online

Users browsing this forum: SO_yeah and 15 guests