quinta-feira, 10 de abril de 2025

Frequencímetro via usb com o ESP32 (com precisão de nanosegundos) - Arduino

     Olá pessoal depois de um bom tempo sem postar nada trago um exemplo de como usar o pino de interrupção do ESP32 para medir frequência com uma precisa até maior do que as de muitos osciloscópios comercias visto que a frequência interna no ESP está com 240MHZ(não precisei de mudar nada pois é padrão), só foi utilizada a biblioteca esp_timer.h.

       Não vou postar aqui o oscilador que foi conectado ao ESP32 pois ele foi apenas para demonstração não sendo o intuito do desse artigo. Só foi usado os pinos GPIO 14(para capturar a interrupção)  e GPIO 13( para o led), o restante já vem pronto na placa ESP32 DEV KIT.

  O código fonte é este:

#include <esp_timer.h>

#define INT1 14  
#define LED 13 
  // led de status

 
uint64_t tempo_anterior = 0;
uint64_t tempo_atual = 0;
uint64_t periodo1 = 0;
uint16_t  numero_amostras = 0;

//interrupção do pino1 
void IRAM_ATTR interrupt1() 
{  
   //tempo_atual = esp_timer_get_time();//micros(); //pega tempo em microsegundos
   tempo_atual = xthal_get_ccount();  // pegar tempo em nanosengundos
   if(tempo_atual>tempo_anterior)
   {
      periodo1 = periodo1 + (tempo_atual - tempo_anterior);
      numero_amostras++;
      if(numero_amostras > 4000)
      {
        // 13us estava dando 3160 aprox logo 243(ticks(clock)) ou seja cada clock = 0,243 ns  
    
        uint64_t periodo_buffer = periodo1/4000;
        Serial.print("periodo(ciclos)= ");
        Serial.print(periodo_buffer);
        Serial.print(" | periodo(us)= ");
        Serial.print(periodo_buffer/226);
        Serial.print(" | frequencia(hz) = ");
        Serial.println(240600000/periodo_buffer);
        periodo1 = 0;
        numero_amostras=0;
      }
   }
   /*else
   { //nem vai precisar e só descartar essa amostra 
      periodo1 = periodo1 + ((0XFFFFFFFFFFFFFFFF - tempo_anterior)+ tempo_atual); // como é de 64 bits fica grande
   }*/
   
  tempo_anterior = tempo_atual;
}

void setup() {
  Serial.begin(115200);  // Inicializa a comunicação serial que comunica com o arduino 
  pinMode(INT1, INPUT);  // Configura o primeiro pino de interrupção
  pinMode(LED, OUTPUT);  // Configura o primeiro pino de interrupção
  attachInterrupt(digitalPinToInterrupt(INT1), interrupt1, FALLING);  // Interrupção a cada  descida do sinal
  Serial.println("inicializado");
}

void loop() { 
   digitalWrite(LED, LOW);
   delay(300);
   digitalWrite(LED, HIGH);
   delay(300);
}

O vídeo de demonstração é este :

Veja a comparação com um multímetro comercial como ficou muito preciso.

formatado por : http://hilite.me/  acessando em 10/04/2025.