Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Frequencimetro com ESP32
- O frequencimetro é dividido em 4 partes:
- 1. Contador de pulsos;
- 2. Controle de tempo de contagem;
- 3. Impressão do resultado;
- 4. Espaco para outra funcoes.
- 1. O contador de pulso usa o pcnt do ESP32. O pcnt tem variaos parametros:
- port de entrada;
- port de controle;
- contagem na subida do´pulso;
- contagem na descida do pulso;
- contagem so com o controle em nivel elevado;
- limite maximo de contagem.
- Com o port de contagem em nivel alto, libera o contador para contar os pulsos que chegam no port de entrada.
- Os pulsos sao contado tanto na subida quanto na descida do pulso, para melhorar a media de contagem
- Teste usando esp_timer ao invés de ledc para ter controle de disparo
- */
- unsigned long overun = 20000;
- #include "driver/pcnt.h" // Pulse count library
- #include "driver/gpio.h" // Biblioteca de gpios
- #include "esp_timer.h" // Biblioteca do esp_timer
- #define PCNT_COUNT_UNIT PCNT_UNIT_0 // Unidade de pcnt
- #define PCNT_COUNT_CHANNEL PCNT_CHANNEL_0 // Canal pcnt
- #define PCNT_INPUT_SIG_IO 23 // Pulse Input GPIO
- #define PCNT_INPUT_CTRL_IO 25 // Control GPIO HIGH=count up, LOW=count down
- #define OUTPUT_CONTROL_GPIO GPIO_NUM_2 // Saida de controle
- #define PCNT_H_LIM_VAL overun // Limite superior de contagem
- esp_timer_create_args_t create_args; // Argumentos do timer
- esp_timer_handle_t timer_handle; // Instancia de timer
- bool flag = true; // Indicador de fim de contagem libera impressao
- int16_t pulses = 0; // Contador de pulsos de entrada
- unsigned long multPulses = 0; // Contador de overflows de pcnt
- unsigned long janela = 1000000; // Janela de contagem de pulsos
- portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
- //----------------------------------------------------------------------------------
- void tempo_controle(void *p) // Fim de tempo de leitura de puslos
- {
- gpio_set_level(OUTPUT_CONTROL_GPIO, 0); // Desliga o controle do pcnt
- }
- //----------------------------------------------------------------------------------
- static void IRAM_ATTR pcnt_intr_handler(void *arg) // Overflow de contagem de pulsos
- {
- PCNT.int_clr.val = BIT(PCNT_COUNT_UNIT); // Limpa indicador de interrupt
- portENTER_CRITICAL_ISR(&timerMux); // Bloqueia novo interrupt
- multPulses++; // Incrementa contador de overflow
- portEXIT_CRITICAL_ISR(&timerMux); // Libera novo interrupt
- }
- //----------------------------------------------------------------------------------
- void IRAM_ATTR detectsCount() // Interrupt de fim de tempo contagem
- {
- pcnt_get_counter_value(PCNT_COUNT_UNIT, &pulses); // Obtem o valor contado
- flag = true; // Informa que ocorreu interrupt de controle
- }
- //----------------------------------------------------------------------------------
- void pcnt_init(void) // Rotina de inicializacao do pulse count
- {
- pcnt_config_t pcnt_config = { }; // Instancia pulse config
- pcnt_config.pulse_gpio_num = PCNT_INPUT_SIG_IO; // Port de entrada dos pulsos
- pcnt_config.ctrl_gpio_num = PCNT_INPUT_CTRL_IO; // Controle da contagem
- pcnt_config.unit = PCNT_COUNT_UNIT; // Unidade de contagem
- pcnt_config.channel = PCNT_COUNT_CHANNEL; // Canal de contagem
- pcnt_config.counter_h_lim = PCNT_H_LIM_VAL; // Limite maximo de contagem
- pcnt_config.pos_mode = PCNT_COUNT_INC; // Conta na subida do pulso
- pcnt_config.neg_mode = PCNT_COUNT_INC; // Conta na descida do pulso
- pcnt_config.lctrl_mode = PCNT_MODE_DISABLE; // Nao usado
- pcnt_config.hctrl_mode = PCNT_MODE_KEEP; // Se HIGH conta incrementando
- pcnt_unit_config(&pcnt_config); // Inicializa PCNT
- pcnt_counter_pause(PCNT_COUNT_UNIT); // Inicializa o contador PCNT
- pcnt_counter_clear(PCNT_COUNT_UNIT); // Zera o contador PCNT
- pcnt_counter_resume(PCNT_COUNT_UNIT); // inicia a contagem
- pcnt_event_enable(PCNT_COUNT_UNIT, PCNT_EVT_H_LIM); // Limite superior de contagem
- pcnt_isr_register(pcnt_intr_handler, NULL, 0, NULL); // Rotina de Interrupt de pcnt
- pcnt_intr_enable(PCNT_COUNT_UNIT); // Habilita interrup de pcnt
- }
- //----------------------------------------------------------------------------------
- void setup()
- {
- Serial.begin(115200); // Inicializa a serial
- pcnt_init(); // Inicializa o pulse count
- gpio_pad_select_gpio(OUTPUT_CONTROL_GPIO); // Define o port decontrole
- gpio_set_direction(OUTPUT_CONTROL_GPIO, GPIO_MODE_OUTPUT); // Define como saida
- create_args.callback = tempo_controle; // Instancia o tempo de controel
- esp_timer_create(&create_args, &timer_handle); // Cria parametros do timer
- attachInterrupt(digitalPinToInterrupt(PCNT_INPUT_CTRL_IO), detectsCount, FALLING); // Habilita interrupt de fim de contagem
- }
- //---------------------------------------------------------------------------------
- void loop()
- {
- if (flag == true) // Se impressa estiver liberada
- {
- flag = false; // Impede nova impresao
- float frequencia = 0; // Variavel para calculo de frequencia
- // Serial.print(" pulses: "); Serial.print (pulses); // Print
- // Serial.print(" multPulses: "); Serial.print (multPulses ); // Print
- frequencia = (pulses + (multPulses * overun)) ; // Calcula qtos pulsos ocorram
- Serial.print(" Frequencia: "); Serial.println ((frequencia / 2), 0 ); // Print
- multPulses = 0; // Zera contador de overflow
- // Aqui pode rodar qq funcao // Espaco para qualquer função
- delay(50); // Espaco para qualquer função
- // Aqui pode rodar qq funcao // Espaco para qualquer função
- pcnt_counter_clear(PCNT_COUNT_UNIT); // Zera o contador PCNT
- esp_timer_start_once(timer_handle, janela); // Disparo unico de tempo de finido na variavel Janela
- gpio_set_level(OUTPUT_CONTROL_GPIO, 1); // Libera port de contagem
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement