RuiViana

Freq_pnct_V19.ino

Jul 8th, 2020
1,132
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.       Frequencimetro com ESP32
  3.       O frequencimetro é dividido em 4 partes:
  4.       1. Contador de pulsos;
  5.       2. Controle de tempo de contagem;
  6.       3. Impressão do resultado;
  7.       4. Espaco para outra funcoes.
  8.  
  9.       1. O contador de pulso usa o pcnt do ESP32. O pcnt tem variaos  parametros:
  10.           port de entrada;
  11.           port de controle;
  12.           contagem na subida do´pulso;
  13.           contagem na descida do pulso;
  14.           contagem so com o controle em nivel elevado;
  15.           limite maximo de contagem.
  16.  
  17.       Com o port de contagem em nivel alto, libera o contador para contar os pulsos que chegam no port de entrada.
  18.       Os pulsos sao contado tanto na subida quanto na descida do pulso, para melhorar a media de contagem
  19.  
  20.  
  21.      
  22.       Teste usando esp_timer ao invés de ledc para ter controle de disparo
  23. */
  24. unsigned long overun = 20000;
  25. #include "driver/pcnt.h"                                                  // Pulse count library
  26. #include "driver/gpio.h"                                                  // Biblioteca de gpios
  27. #include "esp_timer.h"                                                    // Biblioteca do esp_timer
  28.  
  29. #define PCNT_COUNT_UNIT       PCNT_UNIT_0                                 // Unidade de pcnt
  30. #define PCNT_COUNT_CHANNEL    PCNT_CHANNEL_0                              // Canal pcnt
  31. #define PCNT_INPUT_SIG_IO     23                                          // Pulse Input GPIO
  32. #define PCNT_INPUT_CTRL_IO    25                                          // Control GPIO HIGH=count up, LOW=count down
  33. #define OUTPUT_CONTROL_GPIO   GPIO_NUM_2                                  // Saida de controle
  34.  
  35. #define PCNT_H_LIM_VAL      overun                                        // Limite superior de contagem
  36.  
  37. esp_timer_create_args_t create_args;                                      // Argumentos do timer
  38. esp_timer_handle_t timer_handle;                                          // Instancia de timer
  39.  
  40. bool flag = true;                                                         // Indicador de fim de contagem libera impressao
  41. int16_t pulses = 0;                                                       // Contador de pulsos de entrada
  42. unsigned long multPulses = 0;                                             // Contador de overflows de pcnt
  43. unsigned long  janela = 1000000;                                          // Janela de contagem de pulsos
  44. portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
  45. //----------------------------------------------------------------------------------
  46. void tempo_controle(void *p)                                              // Fim de tempo de leitura de puslos
  47. {
  48.   gpio_set_level(OUTPUT_CONTROL_GPIO, 0);                                 // Desliga o controle do pcnt
  49. }
  50. //----------------------------------------------------------------------------------
  51. static void IRAM_ATTR pcnt_intr_handler(void *arg)                        // Overflow de contagem de pulsos
  52. {
  53.   PCNT.int_clr.val = BIT(PCNT_COUNT_UNIT);                                // Limpa indicador de interrupt
  54.   portENTER_CRITICAL_ISR(&timerMux);                                      // Bloqueia novo interrupt
  55.   multPulses++;                                                           // Incrementa contador de overflow
  56.   portEXIT_CRITICAL_ISR(&timerMux);                                       // Libera novo interrupt
  57. }
  58. //----------------------------------------------------------------------------------
  59. void IRAM_ATTR detectsCount()                                             // Interrupt de fim de tempo contagem
  60. {
  61.   pcnt_get_counter_value(PCNT_COUNT_UNIT, &pulses);                       // Obtem o valor contado
  62.   flag = true;                                                            // Informa que ocorreu interrupt de controle
  63. }
  64. //----------------------------------------------------------------------------------
  65. void pcnt_init(void)                                                      // Rotina de inicializacao do pulse count
  66. {
  67.   pcnt_config_t pcnt_config = { };                                        // Instancia pulse config
  68.   pcnt_config.pulse_gpio_num = PCNT_INPUT_SIG_IO;                         // Port de entrada dos pulsos
  69.   pcnt_config.ctrl_gpio_num = PCNT_INPUT_CTRL_IO;                         // Controle da contagem
  70.   pcnt_config.unit = PCNT_COUNT_UNIT;                                     // Unidade de contagem
  71.   pcnt_config.channel = PCNT_COUNT_CHANNEL;                               // Canal de contagem
  72.   pcnt_config.counter_h_lim = PCNT_H_LIM_VAL;                             // Limite maximo de contagem
  73.   pcnt_config.pos_mode = PCNT_COUNT_INC;                                  // Conta na subida do pulso
  74.   pcnt_config.neg_mode = PCNT_COUNT_INC;                                  // Conta na descida do pulso
  75.   pcnt_config.lctrl_mode = PCNT_MODE_DISABLE;                             // Nao usado
  76.   pcnt_config.hctrl_mode = PCNT_MODE_KEEP;                                // Se HIGH conta incrementando
  77.   pcnt_unit_config(&pcnt_config);                                         // Inicializa PCNT
  78.  
  79.   pcnt_counter_pause(PCNT_COUNT_UNIT);                                    // Inicializa o contador PCNT
  80.   pcnt_counter_clear(PCNT_COUNT_UNIT);                                    // Zera o contador PCNT
  81.   pcnt_counter_resume(PCNT_COUNT_UNIT);                                   // inicia a contagem
  82.  
  83.   pcnt_event_enable(PCNT_COUNT_UNIT, PCNT_EVT_H_LIM);                     // Limite superior de contagem
  84.   pcnt_isr_register(pcnt_intr_handler, NULL, 0, NULL);                    // Rotina de Interrupt de pcnt
  85.   pcnt_intr_enable(PCNT_COUNT_UNIT);                                      // Habilita interrup de pcnt
  86. }
  87. //----------------------------------------------------------------------------------
  88. void setup()
  89. {
  90.   Serial.begin(115200);                                                   // Inicializa a serial
  91.   pcnt_init();                                                            // Inicializa o pulse count
  92.   gpio_pad_select_gpio(OUTPUT_CONTROL_GPIO);                              // Define o port decontrole
  93.   gpio_set_direction(OUTPUT_CONTROL_GPIO, GPIO_MODE_OUTPUT);              // Define como saida
  94.  
  95.   create_args.callback = tempo_controle;                                  // Instancia o tempo de controel
  96.   esp_timer_create(&create_args, &timer_handle);                          // Cria parametros do timer
  97.  
  98.   attachInterrupt(digitalPinToInterrupt(PCNT_INPUT_CTRL_IO), detectsCount, FALLING);  // Habilita interrupt de fim de contagem
  99. }
  100. //---------------------------------------------------------------------------------
  101. void loop()
  102. {
  103.   if (flag == true)                                                       // Se impressa estiver liberada
  104.   {
  105.     flag = false;                                                         // Impede nova impresao
  106.     float frequencia = 0;                                                 // Variavel para calculo de frequencia
  107.     //  Serial.print("  pulses: ");  Serial.print (pulses);               // Print
  108.     //  Serial.print("  multPulses: ");  Serial.print (multPulses );      // Print
  109.     frequencia = (pulses + (multPulses * overun))  ;                      // Calcula qtos pulsos ocorram
  110.     Serial.print("  Frequencia: ");  Serial.println ((frequencia / 2), 0 );  // Print
  111.     multPulses = 0;                                                       // Zera contador de overflow
  112.  
  113.     // Aqui pode rodar qq funcao                                          // Espaco para qualquer função
  114.     delay(50);                                                            // Espaco para qualquer função
  115.     // Aqui pode rodar qq funcao                                          // Espaco para qualquer função
  116.  
  117.     pcnt_counter_clear(PCNT_COUNT_UNIT);                                  // Zera o contador PCNT
  118.     esp_timer_start_once(timer_handle, janela);                           // Disparo unico de tempo de finido na variavel Janela
  119.     gpio_set_level(OUTPUT_CONTROL_GPIO, 1);                               // Libera port de contagem
  120.   }
  121. }
RAW Paste Data