ESP32 – Frequencímetro de precisão

Definição de um Frequencímetro:

Para quem não sabe o que é um frequencímetro, é um instrumento eletrônico utilizado para medição da frequência de um sinal elétrico periódico. A unidade de medida de frequência é o Hertz (Hz) ou pulsos por segundo.

Definição de frequencímetro

Mas ainda pode ficar a dúvida! Qual é a utilidade de um frequencímetro?  Como a faixa de frequência é bem ampla no caso do nosso frequencímetro, esse instrumento pode ter inúmeras aplicações! E com algumas alterações no projeto pode-se medir RPM, pulsação cardíaca e muitas outras variáveis cíclicas. Além de possibilitar o desenvolvimento de aparelhos de medição de capacitância, indutância, etc. Veja abaixo um moderno (e muito caro) frequencímetro do fabricante Keysight:

Frequencímetro Keysight 53220A 

Algumas aplicações do ESP32 frequencímetro:

O ESP32 frequencímetro pode medir frequências entre 1 Hertz e 40.000.000 Hertz (40 MHz). A resolução, isto é, a menor unidade entre duas medições é de 1 Hertz também. Ele possui até 8 dígitos no mostrador do Display, o que é bem incomum nos projetos encontrados na WEB e o torna bem útil! Veja algumas aplicações abaixo:

  • medições de frequências de rádios transmissores (até 40 MHz),
  • medições da frequência da rede elétrica,
  • medições de sinais de áudio,
  • medições de osciladores a cristal,
  • etc.

Eu e meu amigo Rui Viana, temos estudado bastante o ESP32. Admiramos muito esse microcontrolador, pela grande quantidade de recursos que ele possui e pela rapidez de processamento. Para quem ainda não conhece o ESP32 pode dar uma olhada nos meus tutoriais:

Conhecendo o ESP32 – Introdução (1)

Conhecendo o ESP32 – Usando Arduino IDE (2)

O manual técnico de referência desse microcontrolador é o ESP32 Technical reference. Esse manual tem atualmente mais de 680 páginas, devido aos inúmeros recursos do chip. Esse manual é frequentemente atualizado pela ESPRESSIF, fabricante do ESP32. Ás vezes eu brinco com o Rui, e comento com ele, que esse manual deveria ter umas 2000 páginas para abranger todas as informações, com todos os detalhes!

Alguns dispositivos internos do ESP32, são chamados de periféricos, como as interfaces serial, I2C, SPI, I2S e muitos outros. Temporizadores e contadores são também periféricos bem interessantes e úteis. Esses tipos de periféricos nos chamaram a atenção, pois alguns Timers e contadores possuem 32 bits e até 64 bits, isto é, podem ser usados para fazer a contagem de um número muito grande de pulsos. E para brilhar os nossos olhos, esses contadores podem fazer contagem muito rápida de pulsos com a “velocidade” de até 80 MHz. É uma frequência bem mais rápida do que as disponíveis nos microcontroladores atuais e mais usados, como o ATMega328 do Arduino.

O Rui foi o responsável pelo desenvolvimento do frequencímetro e eu fui um colaborador desenvolvendo outros recursos e testando o programa. O interessante desse projeto é que inclui também um gerador de pulsos desenvolvido inicialmente por mim, um oscilador programável que pode ser usado para testar o frequencímetro. E esse oscilador pode gerar pulsos de 1 Hz a 40 MHz, inclusive.

O projeto foi todo desenvolvido com a IDE Arduino  para o ESP32 , mas como o Rui gosta de um desafio, elaborou também uma versão para a Plataforma IDF (plataforma oficial da ESPRESSIF). Não posso deixar de citar o nome de mais um amigo nosso, o Celso Ito, que nos ajudou na programação IDF. Nesse tutorial disponibilizamos somente o código Arduino, pois é o mais comum e mais fácil de ser interpretado e compreendido.

Nosso Frequencímetro utiliza esses seguintes periféricos internos do ESP32 (clique nos links, se quiser saber mais):

Pulse Count Controller

O módulo de Contador de pulsos PCNT foi projetado para contar o número de bordas ascendentes e / ou descendentes de um sinal de entrada. Ele possui oito unidades independentes!  Cada unidade de PCNT tem um contador de 16 bits e dois canais que podem habilitar contagens crescentes ou decrescentes. Cada canal tem uma entrada para os pulsos a serem contados e uma porta de controle que serve para ativar ou desativar a contagem.   Cada unidade PCNT possui também registradores que são usados para a configuração dos contadores. Esses contadores podem ser programados para gerar interrupções de acordo com alguns parâmetros selecionados, como máximo valor do contador, mínimo valor do contador e um determinado valor do contador. No nosso caso, usamos o valor máximo do contador para gerar interrupções no ESP32.

Timer

Existem quatro temporizadores de uso geral incorporados no ESP32. Todos eles são temporizadores genéricos de 64 bits baseados em prescalers (divisores de frequência) de 16 bits e contadores de 64 bits.
O ESP32 contém dois módulos de timer, cada um contendo dois timers. Os Timers apresentam essas características:
• Um prescaler de 16 bits, de 2 a 65536,
• Um contador de base de tempo de 64 bits,
• Contador de base de tempo configurável para cima / para baixo: aumentando ou diminuindo a contagem,
• Parada e resumo do contador da base de tempo,
• Recarga automática em alarme,
• Recarga instantânea controlada por software,
• Geração de interrupção por nível e  por borda de pulso.

Cada timer usa o clock APB (APB_CLK, normalmente 80 MHz) como o relógio básico. Este relógio é então dividido por um prescaler de 16 bits que gera o pulso de base de tempo. Esse pulso pode ser usado para incrementar ou diminuir o contador da base de tempo, dependendo da configuração.

Temporizador de alta resolução (High Resolution Timer)

A ESPRESSIF criou um conjunto de APIs (Interface de Programação de Aplicativos) para os temporizadores do ESP32, para permitir um controle mais preciso e mais rápido dos Timers de hardware. O conjunto de APIs esp_timer fornece temporizadores únicos e periódicos, resolução de microssegundos e intervalo de 64 bits. Internamente, o esp_timer usa um timer de hardware de 64 bits. No nosso projeto, o esp_timer é usado para temporizar a contagem de pulsos do PCNT. Como a unidade de medida de frequência é o Hertz, que traduz se por pulsos por segundos, a cada um segundo é realizada a contagem dos pulsos que entram no contador PCNT.

LEDC

O controlador LEDC ou LED_PWM foi projetado principalmente para controlar a intensidade dos LEDs, embora possa ser usado para gerar sinais PWM para outros fins também. Possui 16 canais que podem gerar pulsos independentes para acionar dispositivos LED RGB coloridos. O controlador LED_PWM possui oito canais de alta velocidade e oito de baixa velocidade PWM. Esses canais  podem usar o clock APB_CLK de 80 Mhz, e com a aplicação de divisores de frequência, de contadores e comparadores, permitem a geração de pulsos com ajuste da frequência e do ciclo de trabalho (Duty Cycle). Toda a configuração desse controlador LED PWM é feita através de vários registradores internos. 

Teoria de operação do ESP32 Frequencímetro

O frequencímetro é dividido em 5 partes

  1. Contador de pulsos;
  2.  Controle de tempo de contagem;
  3.  Gerador de sinais programável (1 Hz a 40 Mhz);
  4.  Espaço para outras funções;
  5.  Impressão do resultado.

1. O contador de pulso usa o módulo de Contador PCNT. Na configuração do PCNT são usados os seguintes parâmetros:

  • porta de entrada;
  • canal de entrada;
  • porta de controle;
  • contagem na subida do pulso;
  • contagem na descida do pulso;
  • contagem só com o controle em nível elevado;
  •  limite máximo de contagem.

2. O Controle de tempo de contagem usa o esp-timer. O esp-timer tem o seguinte parâmetro:

  • controle do tempo;

3. Gerador de frequências para testes do frequencímetro usa o ledc. O ledc tem os seguintes parâmetros:

  • porta de saída;
  • canal de lcd;
  • frequência;
  • resolução do ledc;
  • ciclo de trabalho (duty cycle).

Funcionamento do Frequencímetro:

O frequencímetro baseia-se na contagem de pulsos durante o tempo de um segundo.

Primeiramente o oscilador LEDC e o contador PCNT são configurados e inicializados.  Depois são configurados o esp-timer, a porta de controle do contador como saída e a porta de entrada do contador é conectada ao Led da placa ESP32.

O oscilador LEDC começa a gerar a frequência de 12,543 KHz, definida na variável oscilador.  Escolhi essa frequência, para que vocês percebam quão preciso é o frequencímetro. Nessa função de inicialização do oscilador, a resolução e o ciclo de trabalho (Duty Cycle) já são calculados automaticamente, dependendo do valor da frequência.  Ciclo de trabalho é a proporção entre a parte HIGH e a parte LOW do pulso gerado. Por exemplo, no nosso programa esse Duty é de 50%, isto é, a largura da parte HIGH é a metade do ciclo total do pulso.

Para a contagem dos pulsos, foi usado o contador PCNT. Como ele tem o valor limite para 32.768 pulsos, foi definido um valor de 20.000 como máximo nesse programa. Se a contagem for maior que 20.000 pulsos durante o tempo de contagem, ocorre um registro de overflow (transborda).  Para cada overflow que ocorre, ele é contabilizado na variável multPulses.

A porta de controle de contagem (GPIO 35) quando em nível alto, libera o contador para contar os pulsos que chegam na porta de entrada de pulsos (GPIO 34). Os pulsos são contados tanto na subida quanto na descida do pulso de controle, para melhorar a média de contagem. Essas duas contagens são posteriormente divididas por 2, para o cálculo da frequência.

O tempo de contagem é definido pelo esp-timer, e é configurado para um segundo através variável janela. Como cada pulso do Timer corresponde à um micro segundo, a contagem de um milhão de pulsos completa um segundo para a amostragem da frequência.

Duas funções que trabalham com as interrupções foram definidas no programa. A primeira função IRAM_ATTR pcnt incrementa o contador de overflow, sempre que o contador PCNT estiver cheio. A outra função tempo_controle obtém o valor contido nos registradores do contador PCNT, após o tempo do esp-timer expirar.

Após expirar o tempo de um segundo do esp-timer, os registradores do Contador PCNT são lidos e um Flag é alterado para verdadeiro, indicando o fim da contagem. No loop do programa, ao se constatar que o Flag é verdadeiro, o valor da frequência é calculado.  O número de overflows é multiplicado por 20.000 e somado ao número de pulsos restantes. Essa soma é dividida por dois, já que a contagem é realizada duas vezes (os pulsos são contados na subida e na descida do pulso de controle).
Para facilitar a leitura da frequência no display, pontos são inseridos a cada 3 dígitos, usando as funções ultos e ltos. Essa frequência, além de ser mostrada no display LCD e é enviada também para a console serial da Arduino IDE. Após a amostragem da frequência, os registradores são zerados e as contagens de tempo e dos pulsos são reiniciadas.

Usando também a console serial da Arduino IDE é possível alterar a frequência do Oscilador, para efeito de testes. Digite um valor entre 1 Hz e 40 MHz no campo de entrada e pressione ENTER. Como a saída pulsos do Oscilador foi definida no pino GPIO 33, é necessário que conecte essa saída de pulsos na entrada do frequencímetro GPIO 34, para realizar os testes. Mas para medições de frequências de sinais externos, retire essa conexão. Como o ESP32 trabalha com sinais de tensão de 3,3 Volts, se for medir sinais com outros níveis de tensão, é recomendável que use um conversor de nível lógico  na porta de entrada. Internamente usando GPIO matrix, o pulso de entrada do frequencímetro foi direcionado para o LED nativo do ESP32, assim o LED piscará de acordo com a frequência.

Bibliotecas utilizadas:

A versão da IDE Arduino usada nesse projeto foi a V 1.8.12. Atualize a sua versão se estiver desatualizada, para evitar alguma incompatibilidade de códigos.

Arduino Software

Se você ainda não configurou a Arduino IDE para ser usada com o Placa ESP32, siga o procedimento do tutorial no link abaixo. Essa configuração é essencial para que o projeto funcione adequadamente.  Se a sua Placa ESP32 for diferente do Tutorial, altere as configurações na Arduino IDE.

Conhecendo o ESP32 – Usando Arduino IDE (2)

 

A Versão do firmware do ESP32 para a Arduino IDE usada nesse projeto foi a V 1.0.4. Se estiver desatualizada, atualize-a antes de compilar o seu programa, para evitar algum tipo de problema. Use o Gerenciador de placas para atualizar, se necessário.

 

Para usar o Display LCD com a interface I2C (PCF8574) é necessário que você instale a Biblioteca LiquidCrystal_PCF8574. Use o Gerenciador de Bibliotecas da Arduino IDE para instalá-la.

 

E se for usar o display LCD paralelo(com 4 bits), instale a Biblioteca LiquidCrystal também com o Gerenciador de Bibliotecas da Arduino IDE.

 

Diagramas dos circuitos:

Abaixo estão os dois diagramas dos circuitos do ESP32 Frequencímetro. Você poderá optar pelo Display com interface I2C (PCF8574), muito mais fácil para montar ou pelo Display LCD com a interface paralela de 4 bits. Para facilitar a compreensão, fiz os dois diagramas separados. Sobre a alimentação do projeto, poderá usar o cabo USB conectado ao seu PC. Ou então conecte o cabo USB em um carregador de celular que tem saída USB 5 Volts. E mais uma alternativa, se quiser mobilidade, conecte o cabo USB à um Battery Pack com saída USB 5 V.

Se quiser aprender mais sobre o uso dos Displays LCD, sugiro a leitura desse meu outro tutorial :

Guia completo do Display LCD – Arduino

 

Diagrama para Display com interface I2C (PCF8574) (Para ampliar a imagem, abra-a em outra aba)

Não se esqueça de ajustar o brilho do display, no potenciômetro na placa de Interface I2C (PCF8574) – conectada atrás do display. Mantenha o jumper conectado.

 

Diagrama para Display com interface paralela (Para ampliar a imagem, abra-a em outra aba).

O potenciômetro de 10 K ohms é essencial nesse circuito, para o ajuste do brilho do Led de backlight.  A tensão no pino central do POT deverá ser ajustada para aproximadamente 1 V em relação ao terra (GND).

 

Programa ESP32 Frequencímetro:

Diretivas para seleção do Display

O compilador da Arduino IDE pode usar as diretivas de compilação do programa para habilitar e selecionar o tipo de display LCD:

  • Uso de LCD paralelo – altere para LCD_ON ou LCD_OFF:

           #define LCD_OFF     ou     #define LCD_ON       // ON se for usar esse display 

  • Uso de LCD I2C – altere para LCD_I2C_ON ou LCD_I2C_OFF.

           #define LCD_I2C_ON     ou      #define LCD_I2C_OFF  // ON se for usar esse display

OBs: se não souber o endereço da interface I2C do seu LCD, use o ESP32 I2C Scanner para descobrir: (o endereço da minha placa é 0x3F):

ESP32 – I2C scanner

Mas se não quiser usar nenhum display LCD, poderá visualizar as medições de frequências na Console Serial da Arduino IDE. E através dessa mesma console, poderá digitar a frequência de teste desejada entre um valor de 1 Hz a 40 MHz. Muito legal isso! Dessa forma poderá confirmar se fez a montagem correta do projeto e testar o frequencímetro.

Calibração do Frequencimetro:

Mais uma vantagem desse projeto, é que ele permite uma calibração na medição da frequência. Os valores de medição, normalmente apresentados com o ESP32 são muito satisfatórios. Com o uso de um frequencímetro de precisão, usado como referência, pode-se ajustar o valor da variável janela no programa. Alterando esse valor, poderá conseguir uma precisão ainda maior do que a obtida. Nos meus testes do frequencímetro, usando a função de medição de frequência do meu osciloscópio, alterei o valor da janela e consegui obter os mesmos valores do osciloscópio!

 

ESP32_Frequencimetro.ino

 

Se você optou em não montar nenhum dos dois tipos de display LCD, poderá verificar as medições de frequência na Console Serial da Arduino IDE. A velocidade da console deverá ser configurada para 115200 Bps. Para alterar a frequência de teste do frequencímetro, digite um valor de 1 Hz a 40 MHz no campo de entrada e pressione enter. Não é preciso entrar com a unidade de Hertz (Hz). Mas para fazer esse teste, lembre-se que a Entrada do Frequencímetro (GPIO34) precisa estar conectada na saída do Oscilador (GPIO33).

 

 

Referências:

Serial monitoring and writing

Gerador de sinais com ESP32 

Bibliotecas LCD e I2C LCD

Formatação de números em C++

 

Se gostar ou tiver alguma dúvida,  deixe um comentário!

 

Rui Viana
Apaixonado por eletrônica desde o início do “ginásio”. Técnico em eletrônica, formado pelo curso Monitor de rádio e televisão em 1966. Possui curso de engenharia Incompleto.
Trabalhou como técnico em eletrônica, na RCA Victor, fábrica de válvulas e em uma fábrica de embalagens. Trabalhou por muitos anos na IBM, na área de manutenção de computadores de grande porte.
Empresário por 20 anos na área de projetos de fibra óptica para grandes Data Centers e plataformas de Petróleo. Aposentou-se, mas continua enfrentando os desafios da tecnologia, principalmente na eletrônica digital e na programação. Aprendendo e ensinando às novas gerações, transferindo conhecimento adquirido e aprendido. Sonhador nas horas vagas

 

Avaliação: 5.0/5. De 3 votos.
Espere por favor...
Gustavo Murta
Gustavo Murta
Consultor e Projetista de Sistemas Embarcados. Técnico em eletrônica, formado em Curso superior de TPD, pós-graduado em Marketing. Trabalhou por muitos anos na IBM na área de manutenção de computadores de grande porte. Aposentou-se, podendo curtir o que mais gosta : estudar e ensinar Tecnologia. Hobista em eletrônica desde 1976. Gosta muito de Fotografia e Observação de aves.
Acesse nossa loja