RuiViana

Freq_pnct_V20.ino

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