Índice:
- Etapa 1: contagem de frequência da velha escola
- Etapa 2: o caminho recíproco
- Etapa 3: Hardware e seu esquema
- Etapa 4: O Código
- Etapa 5: Exatidão e precisão
Vídeo: Contador de frequência de alta resolução: 5 etapas (com imagens)
2024 Autor: John Day | [email protected]. Última modificação: 2024-01-30 11:34
Este instrutível mostra um contador de frequência recíproco capaz de medir frequências rapidamente e com precisão razoável. É feito com componentes padrão e pode ser feito em um fim de semana (demorei um pouco mais:-))
EDITAR: O código já está disponível no GitLab:
gitlab.com/WilkoL/high-resolution-frequency-counter
Etapa 1: contagem de frequência da velha escola
A maneira tradicional de medir a frequência de um sinal é usar uma porta lógica AND, alimentar o sinal a ser medido em uma porta e um sinal com exatamente 1 segundo de tempo na outra porta e contar a saída. Isso funciona muito bem para sinais de alguns kHz até o GHz. Mas e se você quiser medir um sinal de baixa frequência com boa resolução? Digamos que você queira medir a frequência da rede elétrica (aqui 50 Hz). Com o método da velha escola, você verá 50 constantes em sua tela se tiver sorte, mas é mais provável que veja a tela alternar de 49 para 50 ou 50 para 51. A resolução é de 1 Hz e é isso. Você nunca verá 50,002 Hz a menos que esteja disposto a aumentar o tempo de porta para 1000 segundos. Isso é mais de 16 minutos, para uma única medição!
A melhor maneira de medir sinais de baixa frequência é medir o período deles. Tomando a rede elétrica como exemplo novamente, tem um período de 20 milissegundos. Pegue a mesma porta lógica AND, alimente-a com, digamos, 10 MHz (pulsos de 0,1 us) e seu sinal na outra porta e saia 200.000 pulsos, então o período de tempo é 20000,0 uS e isso se traduz em 50 Hz. Quando você mede apenas 1.9650 pulsos, a frequência é 50.087 Hz, que é muito melhor, e ocorre em apenas um segundo de medição. Infelizmente, isso não funciona bem com frequências mais altas. Por exemplo, agora queremos medir 40 kHz. Com a mesma frequência de entrada de 10 MHz como referência, medimos agora apenas 250 pulsos. Quando contamos apenas 249 pulsos, o cálculo dá 40161 Hz e com 251 o resultado é 39840 Hz. Essa não é uma resolução aceitável. É claro que aumentar a frequência de referência melhora os resultados, mas há um limite para o que você pode usar em um microcontrolador.
Etapa 2: o caminho recíproco
Uma solução que funciona para frequências baixas e altas é um contador de frequência recíproco. Tentarei explicar seu princípio. Você começa com um tempo de medição que é de aproximadamente 1 segundo, não precisa ser muito preciso, mas é um tempo razoável para uma medição. Alimente este sinal de 1 Hz em um flipflop D na entrada D. Nada acontece ainda na (s) saída (s). Conecte o sinal que deseja medir à entrada CLOCK do D-flipflop.
Assim que este sinal vai de LOW para HIGH, a saída do flipflop D transfere o estado da entrada D para a saída (Q). Este sinal RISING é usado para iniciar a contagem do sinal de entrada, bem como um sinal de relógio de referência.
Portanto, você está contando DOIS sinais exatamente ao mesmo tempo, o sinal que deseja medir e um relógio de referência. Este relógio de referência deve ter um valor preciso e ser estável, um oscilador de cristal normal é adequado. O valor não é muito importante, desde que seja uma frequência alta e seu valor seja bem conhecido.
Depois de algum tempo, digamos alguns milissegundos, você torna a entrada D do flipflop D baixa novamente. Na próxima entrada de CLOCK a saída Q segue o estado da entrada, mas nada mais acontece porque o microcontrolador está configurado para reagir apenas a um sinal de RISING. Então, após o tempo de medição terminar (aproximadamente 1 segundo), você torna a entrada D ALTA.
Novamente na próxima entrada CLOCK a saída Q segue e este sinal RISING aciona o microcontrolador, desta vez para encerrar a contagem de ambos os contadores.
O resultado são dois números. O primeiro número é o número de pulsos contados a partir da referência. Como conhecemos a frequência de referência, também sabemos quanto tempo levou para contar esses pulsos.
O segundo número é o número de pulsos do sinal de entrada que estamos medindo. Como começamos exatamente nas bordas RISING deste sinal, estamos muito confiantes sobre o número de pulsos deste sinal de entrada.
Agora é apenas um cálculo para determinar a frequência do sinal de entrada.
Um exemplo, digamos que temos esses sinais e queremos medir a entrada f. A referência é 10 MHz, gerado por um oscilador de cristal de quartzo. f_input = 31,416 Hz f_reference = 10000000 Hz (10 MHz), o tempo de medição é de aprox. 1 segundo
Nesse tempo, contamos 32 pulsos. Agora, um período desse sinal leva 1 / 31,416 = 31830,9 uS. Portanto, 32 períodos levaram 1,0185892 segundos, o que é pouco mais de 1 segundo.
Neste 1,0186 segundo, também teremos contado 10185892 pulsos do sinal de referência.
Isso nos dá as seguintes informações: input_count = 32 reference_count = 10185892 f_reference = 10000000 Hz
A fórmula para calcular a frequência resultante é esta: freq = (input_count * f_reference) / ref_count
Em nosso exemplo, isto é: f-input = (32 * 10000000) / 10185892 = 31,416 Hz
E isso funciona bem tanto para baixas frequências quanto para altas frequências, apenas quando o sinal de entrada se aproxima (ou até mesmo mais alto) da frequência de referência, é melhor usar a forma padrão de medição "controlada". Mas então também poderíamos simplesmente adicionar um divisor de frequência ao sinal de entrada, pois esse método recíproco tem a mesma resolução para qualquer frequência (até a referência novamente). Portanto, se você medir 100 kHz diretamente ou dividido por um divisor externo de 1000x, a resolução é a mesma.
Etapa 3: Hardware e seu esquema
Eu fiz alguns deste tipo de contadores de frequência. Há muito tempo fiz um com um ATMEGA328 (o mesmo controlador que existe em um Arduino), depois com micro controladores ARM da ST. O mais recente foi feito com um STM32F407 com clock de 168 MHz. Mas agora eu me perguntei o que aconteceria se eu fizesse o mesmo com um * muito * menor. Eu escolhi um ATTINY2313, que tem apenas 2kbyte de memória FLASH e 128 bytes de RAM. O display que tenho é um MAX7219 com 8 displays de sete segmentos, esses displays estão disponíveis no Ebay por apenas 2 euros. Um ATTINY2313 pode ser comprado por cerca de 1,5 euros e o resto das peças que usei custam apenas centavos a peça. O mais caro provavelmente foi a caixa de plástico do projeto. Mais tarde, decidi fazê-lo funcionar com uma bateria de íon de lítio, então precisei adicionar um estabilizador de voltagem (LDO) de 3,3 V, um módulo de carregamento de bateria e a própria bateria. Isso aumenta um pouco o preço, mas acho que pode ser construído por menos de 20 euros.
Etapa 4: O Código
O código foi escrito em C com Atmel (Microchip) Studio 7 e programado no ATTINY2313 usando um OLIMEX AVR_ISP (clone?). Abra o (main.c) no arquivo zip abaixo se desejar seguir a descrição aqui.
INICIALIZAÇÃO
Primeiro, o ATTINY2313 foi configurado para usar um cristal externo, pois o oscilador RC interno é inútil para medir qualquer coisa. Eu uso um cristal de 10 MHz que sintonizo na frequência correta de 10.000.000 Hz com um pequeno capacitor variável. A inicialização cuida de definir portas para entradas e saídas, configurar os temporizadores e habilitar interrupções e inicialização do MAX7219. TIMER0 está configurado para contar um relógio externo, TIMER1, o relógio interno e também para capturar o valor do contador na borda de subida do ICP, vindo do D-flipflop.
Discutirei o programa principal por último, então a seguir estão as rotinas de interrupção.
TIMER0_OVF
Como TIMER0 conta até 255 (8 bits) e depois passa para 0, precisamos de uma interrupção para contar o número de overflows. Isso é tudo que TIMER0_OVF faz, basta contar o número de estouro. Posteriormente, esse número é combinado com o valor do próprio contador.
TIMER1_OVF
TIMER1 pode contar até 65536 (16 bits), então a interrupção TIMER1_OVF também conta o número de overflows. Mas faz mais. Ele também diminui de 152 para 0, o que leva cerca de 1 segundo e, em seguida, define um pino de saída, indo para a entrada D do flipflop. E a última coisa que é feita nesta rotina de interrupção é diminuir o contador de tempo de espera, indo de 765 para 0, o que leva cerca de 5 segundos.
TIMER1_CAPT
Esta é a interrupção TIMER1_CAPT que é disparada toda vez que o D-flipflop envia um sinal, na borda ascendente do sinal de entrada (conforme explicado acima). A lógica de captura cuida de salvar o valor do contador TIMER1 no momento da captura, ele é salvo assim como o contador de estouro. Infelizmente, TIMER0 não tem uma função de captura de entrada, então aqui seu valor atual e seu valor atual do contador de estouro são lidos. Uma variável de mensagem é definida como um para o programa principal para informá-lo que esses dados são novos.
A seguir estão duas funções para controlar o MAX7219
SPI
Embora haja uma interface serial universal (USI) disponível no chip, optei por não usá-la. O display do MAX7219 precisa ser controlado via SPI e isso é possível com o USI. Mas bitbanging SPI é tão simples que não perdi tempo fazendo isso com o USI.
MAX7219
O protocolo de configuração do MAX7219 também é bastante simples, uma vez que você tenha lido o manual do mesmo. Ele precisa de um valor de 16 bits para cada dígito, que consiste em 8 bits para o número do dígito (1 a 8), seguidos por 8 bits para o número que precisa ser exibido.
PRINCIPAL-PROG
A última coisa é explicar o programa principal. Ele é executado em um loop infinito (while (1)), mas apenas realmente faz algo quando há uma mensagem (1) da rotina de interrupção ou quando o contador de tempo limite é reduzido a zero (sem sinal de entrada).
A primeira coisa a fazer quando a variável mensagem passa para um, é zerar o contador de timeout, afinal sabemos que existe um sinal presente. O flipflop D é reiniciado para deixá-lo pronto para o próximo disparo que virá após o tempo de medição (espere um segundo).
Os números registrados na interrupção de captura são adicionados para fornecer a contagem de referência e a contagem de frequência de entrada. (temos que ter certeza de que a referência nunca pode ser zero, pois vamos dividir por ela mais tarde)
Em seguida, é o cálculo da frequência real. Eu certamente não quero usar números flutuantes em um microcontrolador com apenas 2kbytes de flash e apenas 128 bytes de RAM. Eu uso inteiros. Mas as frequências podem ser 314,159 Hz, com vários decimais. Portanto, multiplico a frequência de entrada não apenas pela frequência de referência, mas também por um multiplicador e, em seguida, adiciono um número onde o ponto decimal deve ficar. Esses números ficarão muito grandes quando você fizer isso. Por exemplo. com uma entrada de 500 kHz, uma referência de 10 MHz e um multiplicador de 100, isso dá 5 x 10 ^ 14, isso é muito grande! Eles não vão caber mais em um número de 32 bits, então eu uso números de 64 bits que vão até 1,8 x 10 ^ 19 (que funciona bem em um ATTINY2313)
E a última coisa a fazer é enviar o resultado para o display do MAX7219.
O código é compilado em cerca de 1600 bytes, portanto, ele se ajusta ao flash de 2048 bytes disponível no ATTINY2313.
Os registradores de fusíveis devem ser lidos assim:
EXTENDED 0xFF
HIGH 0xDF
LOW 0xBF
Etapa 5: Exatidão e precisão
Exatidão e precisão são duas bestas separadas. A precisão aqui é de sete dígitos, a precisão real depende do hardware e da calibração. Calibrei 10 MHz (5 MHz no ponto de teste) com um outro contador de frequência que possui um oscilador disciplinado GPS.
E funciona muito bem, a frequência mais baixa que tentei é de 0,2 Hz, a mais alta de 2 MHz. Ele está no local. Acima de 2 MHz o controlador começa a perder interrupções, o que não é surpreendente quando você sabe que na entrada de 2 MHz o sinal TIMER0 gera mais de 7.800 interrupções por segundo. E o ATTINY2313 tem que fazer outras coisas também, as interrupções do TIMER1, em outras 150 interrupções por segundo e claro fazer os cálculos, controlando o display e o D-flipflop. Quando você olha para o dispositivo real, você verá que uso apenas sete dos oito dígitos do visor. Eu faço isso por vários motivos.
A primeira é que o cálculo da frequência de entrada é uma divisão, quase sempre terá um resto, que você não vê porque é uma divisão inteira. Em segundo lugar, o oscilador de cristal de quartzo não tem temperatura estabilizada.
Os capacitores que ajustam nos 10 MHz corretos são de cerâmica, muito sensíveis às mudanças de temperatura. Depois, há o fato de que TIMER0 não tem lógica de captura incorporada e todas as funções de interrupção levam algum tempo para fazer seu trabalho. Acho que sete dígitos é bom o suficiente de qualquer maneira.
Recomendado:
Contador de frequência com Arduino: 8 etapas (com imagens)
Contador de frequência com Arduino: Este é um contador de frequência simples e barato baseado em arduino, que custa menos de 4 $ e tem sido muito útil para medir pequenos circuitos
Webcam de alta resolução: 9 etapas (com imagens)
Webcam de alta resolução: Por alguns anos usei uma webcam baseada em RPi (com o módulo PiCam). As imagens produzidas estavam boas mas aí, chegou o momento em que já não estava satisfeito com a qualidade. Decidi fazer uma webcam de alta resolução. As seguintes partes w
OpenLogger: um registrador de dados portátil de alta resolução, Wi-Fi habilitado, código aberto: 7 etapas
OpenLogger: um registrador de dados portátil de alta resolução, Wi-Fi habilitado, código aberto: o OpenLogger é um registrador de dados portátil, de código aberto, de baixo custo e alta resolução projetado para fornecer medições de alta qualidade sem exigir software caro ou software de gravação do princípio. Se você é um engenheiro, cientista ou entusiasta que
Geração de sinal PWM de alta resolução para servos RC com dispositivos STM32: 3 etapas
Geração de sinal PWM de alta resolução para servos RC com dispositivos STM32: Atualmente, estou construindo um transmissor / receptor RC baseado no chip RF SX1280. Um dos objetivos do projeto é que eu quero uma resolução de servo de 12 bits desde os bastões até os servos. Em parte porque os servos digitais modernos têm resolução de 12 bits
Como obter imagens de alta resolução fora dos instrutíveis: 4 etapas
Como obter imagens de alta resolução fora dos instrutíveis: Você realmente gostou daquela imagem instrutível e deseja salvar uma cópia em alta resolução dela? Este ótimo pequeno recurso é facilmente esquecido