Frecuencimetro Hasta 30kHz

En este post, les mostrare una forma muy sencilla de realizar un frecuencímetro de uso general, aunque de bajas prestaciones.
Un frecuencímetro es un instrumento de medición que debe realizar una cuenta en un determinado tiempo.
La frecuencia en Hertz es la cantidad de veces que se repite un pulso durante el transcurso de 1s.
Por ejemplo: Si durante 1s contamos 30 pulsos, la frecuencia será de 30Hz. Si durante 1s contamos 1000 pulsos, la frecuencia será de 1kHz, y así sucesivamente para cualquier valor.
En este programa extremadamente sencillo aplicaremos esta misma lógica, utilizaremos el Timer1 para crear un temporizador de 1s (el cual genera el lapso de tiempo para contar pulsos) y durante este lapso de 1s se contaran los pulsos que ingresan en la entrada T1CKI (Timer 1 External Clock Input).
La forma de pensar esta lógica será la siguiente:

1) Encendemos el Timer
2) Demoramos 1s (el lapso de cuenta)
3) Apagamos el Timer
4) Mostramos cuantos pulsos ingresaron por T1CKI durante ese segundo.

Como pueden ver en el programa la demora no es de 1000ms (1s) sino que es de 250ms, esto es porque en la configuración del Timer1 tenemos el divisor (preescaler) por 1, si quieren poner la demora de 1000ms tienen que configurar el preescaler como divisor por 4, esto quedaría: T1_DIV_BY_4, pero el refresco del LCD en mostrar la cuenta seria de 1s por ende es un poco lento y perdemos muestras, entonces al configurar el preescaler por 1 y esperar 250ms obtenemos el mismo resultado pero el LCD y las muestras se actualizan cada 1/4s entonces el funcionamiento será más eficiente.

Claramente no es un instrumento de precisión ni mucho menos, solamente trata de explicar, mediante el uso del timer1 como temporizador, el funcionamiento básico de un frecuencímetro. El mismo está limitado en frecuencia, pero hasta los 30kHz nos mostrara una cuenta estable.
Si quieren que este frecuencímetro acepte mayor frecuencia pueden poner un preescaler externo, que podría ser un circuito con FF (donde cada FF realizara una división por 2). Si utilizamos un 4017, tendremos un divisor programable de 1 a 10, donde la máxima entrada serian 300kHz que al pasar por el divisor /10 nos dará 30kHz y no tendríamos problemas en el MCU, (dentro del MCU en el printf tendremos que compensar esta división con una multiplicación por el mismo valor para que la lectura sea correcta), esto quedaría: printf(lcd_putc,"%lu Hz",pulsos*10); entonces de este modo ingresamos 300kHz al 4017, salimos con 30kHz del 4017 que ingresaran al MCU y la lectura será de 30kHz*10=300kHz.




#include <16F628A.h>
#FUSES NOWDT
#FUSES HS
#FUSES NOPUT
#FUSES NOPROTECT
#FUSES NOBROWNOUT
#FUSES NOMCLR
#FUSES NOLVP
#FUSES NOCPD
#use delay(clock=4000000)
#define LCD_ENABLE_PIN  PIN_B7
#define LCD_RS_PIN      PIN_B4
#define LCD_RW_PIN      PIN_B5
#define LCD_DATA4       PIN_B0
#define LCD_DATA5       PIN_B1
#define LCD_DATA6       PIN_B2
#define LCD_DATA7       PIN_B3
#include <LCD.C>
void main(){
   lcd_init();
   int16 pulsos;
   while(true){
      set_timer1(0);                          //HAB Timer1
      setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1); //ON Timer1 2kHz
      delay_ms(250);                          //Demora 1/4s
      setup_timer_1(T1_DISABLED);             //INHAB Timer1
      pulsos=get_timer1();                    //CONT Pulsos
      lcd_gotoxy(1,1);                        //Renglon (1,1)
      printf(lcd_putc,"%lu Hz",pulsos);       //Muestra f
   }
}



NOTA: la redefinición de pines del display LCD se ha realizado porque se necesitaba el pin T1CKI que se encontraba dentro de los pines del LCD por defecto.

12 comentarios:

  1. hola amigo puedo usar un prescaler interno para hacer un amplio rango de Frecuencia quiero llegar 1 hz a 1 Mhz pero sin usar prescaler esterno digame si es posible que funciones tendria que usar en CCs y como se haria el desvordamiento del timer

    ResponderBorrar
    Respuestas
    1. Hola, lo que se esta realizando aqui es la cuenta de pulsos que ingresan por la entrada de captura, durante 1/4 de segundo, luego se multiplica por 4 aprovechando la velocidad del bus y preescaler para saber en 1 segundo cuantos pulsos se contaron, asi se sabe la frecuencia.
      Si queres un frecuencimetro de mayor rango te recomiendo este post.
      http://electgpl.blogspot.com.ar/2013/04/frecuencimetro-hasta-50mhz.html
      Podes ingresarle tranquilamente 1MHz.
      Saludos.

      Borrar
    2. ok gracias por la respuesta ya habia visto ese otro circuito pero no entiendo la programacion DX y uso un pic difrerente el 16f876a ya que de ese dispongo y quisiera haverlo hecho con este de 30Khz ya que entiendo mas las funciones que en este usas.
      Muchas gracias nuevamente saludos

      Borrar
    3. Hola podes usar el 16F876A, el problema es que para frecuencias de 1MHz de muestreo, vas a necesitar realizar un programa mas elavorado que el de este post ya que se aproxima mucho a la velocidad del bus y requiere una optimizacion de codigo alta.
      Habria que probar, ya que con un Xtal de 20MHz tendrias el bus corriendo a 5MHz y podria funcionar pero es algo que hay que probar.
      Saludos.

      Borrar
  2. Si pero como mido el duty y la cantidad de pulsos aquí solo mido la cantidad de pulsos

    ResponderBorrar
    Respuestas
    1. Tendrías que usar la interrupción externa midiendo flanco, y contas el tiempo entre flanco ascendente y descendente, de ahi podes saber el ciclo de trabajo.
      Saludos!

      Borrar
  3. sebatian no entiendo por que no me funciona su programa

    ResponderBorrar
    Respuestas
    1. Hola, que error te da?, firmware o hardware? que MCU estas usando, lo esta compilando con CCS?
      Saludos

      Borrar
  4. me podrian poner el codigo de ese circuito para utilizarlo en MPLAB

    ResponderBorrar
  5. Este comentario ha sido eliminado por el autor.

    ResponderBorrar
  6. Hola, creo que este método es bastante impreciso a bajas frecuencias. Por ejemplo, cada 1/4 de segundo no puedo medir 1,2, o 3 hz. ¿Y como mide frecuencias con decimales (6.7hz por ejemplo) ?

    ResponderBorrar