Go Down

Topic: Frecuencímetro con Arduino de 1Hz a 3Khz (Read 12 times) previous topic - next topic

lm386

Jun 13, 2012, 09:20 pm Last Edit: Jun 14, 2012, 03:33 pm by lm386 Reason: 1
Aquí os dejo un programa que hace del arduino un frecuencímetro de 1Hz a 3Khz.

Con este programa se puede hacer también un detector de tono, un tacómetro óptico, cuenta revoluciones y lo que la imaginación os de.

Puede trabajar con tensiones analógicas o digitales. Con señales analógicas puede trabajar con tensiones de entrada alterna de entre 0,0097v a 2,5v o digitales de entre 0v a 5v.

Tiene un filtro que discrimina las amplitudes de señal menores, esto sirve para evitar que el frecuencímetro detecte frecuencias de fondo, producidas por ejemplo en proyectos donde hay ruido eléctrico, como por ejemplo, sistemas en los que se empleen motores, que generan ruido eléctrico. También es útil para detectar tonos en señales de audio, en las que estén presentes otros sonidos de fondo, siempre de menos amplitud que el tono a detectar.

Saludos.


Code: [Select]
/*
FRECUENCIMETRO

 Este frecuencímetro puede leer frecuencias de 1Hz a 3Khz.
 
 El error puede rondar el +/- 1Hz.

 Muestra las lecturas a través del puerto serie a intervalos de 1 segundo.
 
 Este frecuencímetro dispone de un ajuste automático de ganancia, que le permite ajustarse a la mayor señal y eliminar así, lecturas correspondientes a ruidos de fondo de algún tipo.

PLATAFORMA

Este programa a sido probado en un arduino duemilanove y a sido comprobado su correcto funcionamiento.

CONEXIONADO

 El pin analógico CERO, es el pin de entrada de frecuencias.
 
Si se quieren medir corrientes alternas, será necesario poner dos resistencias de entorno a 1000 ohmios en serie y conectar un extremo de las resistencias en serie a masa y el otro extremo al polo positivo. De entre las dos resistencias puestas en serie, se conectaría al pin cero analógico y del pin cero analógico sacaríamos un terminal, que sería por el que entraría la señal a medir. Las resistencias se conectan de este modo para hacer un divisor de tensión, que haga que la entrada analógica del arduino esté a un voltaje intermedio entre masa y el positivo. También se podría poner en serie un condensador entre el pin cero analógico y el terminal por el que va a entrar la señal alterna, para separar el arduino de las corrientes continuas.

NOTA IMPORTANTE:

 La entrada analógica solo puede entrar una señal de como mucho 5v, de lo contrario, podríamos romper el arduino. Se podría poner un diodo zener de algo menos de 5v, para cortocircuitar los picos te tensión superiores a 5V, entre el terminal cero analógico y masa.

AUTOR: Mario R.P - mariorp@terra.es - 13-6-2012

*/

long rango=2; // este es el rongo por el que se disparará la salida 2 y pasa a estado lógico 1
long ultimamedicion; // contiene el valor de la última medición que disparó a lógico 1, la salida 2
int ciclo=0; // 1=alto 0=bajo
int cambiodeciclo=0;
int picodetension;
int valledetension=1023;
long contadorvisualizacion;
long contadorciclo;

void setup() {

 Serial.begin(9600);
 pinMode(A0, INPUT); // Se establece el pin analógico 0 como pin de lectura de datos.
}

void loop() {
 
 long sensorValue = analogRead(A0); // Se vuelca a la varibla sensorValue el valor de la tensión medida por el pin 0 analógico
 
   if (micros()>contadorvisualizacion+1000000) // Muestra por el puerto serie los resultados, transcurrido un segundo
   
   {
     
        // AQUÍ SE IMPRIME EN EL PUERTO SERIE LOS RESULTADOS

        Serial.print(" Hz=");
        Serial.println(contadorciclo);
       
        rango=(2+((picodetension-valledetension)/5)); // SE CALCULA EL GANGO MÁS ADECUADO PARA LA SEÑAL, CON EL FIN, DE REDUCIR ERRORES EN SEÑALES CON RUIDO DE FONDO
        contadorvisualizacion=micros();//SE ASIGNA A LA VARIABLE CONTADORVISUALIZACIÓN EL TIEMPO EN MICROSENGUNDOS QUE LLEVA EL PROGRAMA EN EJECUCIÓN
        picodetension=sensorValue;//SE ASIGNA A LA VARIABLE PICODETENSIÓN EL VALOR DE LA TENSIÒN LEIDA POR EL PUERTO ANALÓGICO CERO
        valledetension=sensorValue;//SE ASIGNA A LA VALLEDETENSION EL VALOR DE LA TENSIÒN LEIDA POR EL PUERTO ANALÓGICO CERO
        contadorciclo=0; // SE PONE A CERO LOS CICLOS CONTADOS O HERCIOS.
   }  
   



 if (sensorValue >= ( ultimamedicion+rango) ) // La salida 2 pasa a 1 logico si la tensión medida en la entrada analógica 0 es mayor que la anterior lectura + latensión de RANGO

 {

   ultimamedicion = sensorValue;  // SE ASIGANA A LA VARIABLE ULTIMAMEDICION EL VALOR LEIDO POR LA ENTRADA ANALÓGICA CERO
   ciclo=1;
   
   if (sensorValue>picodetension) // SI LA TENSIÓN MEDIDA POR LA ENTRADA CERO, ES LA MAYOR DETECTADA, SE ASIGNA A LA VARIABLE PICODETENSIÓN EL VALOR LEYDO POR AL ENTRADA CERO ANALÓGICA
   
   {
   picodetension=sensorValue; // SE ASIGNA EL VALOR LEYDO POR LA ENTRADA CERO ANALÓGICA A LA VARIABLE PICODETENSIÓN.
   }
   
 }
   

 
 if (sensorValue <= ( ultimamedicion-rango))  // La salida 2 pasa a 1 lógico si la tensión medida en la entrada analógica 0 es menor que la anterior lectura - la tensión de RANGO

 {

   ultimamedicion = sensorValue; // SE ASIGNA A LA VARIABLE ULTIMAMEDICIÓN LA LECTURA MEDIDA POR EL PUERTO ANALÓGICO CERO
   ciclo=0; // EL CICLO SE PONE A CERO, ES DECIR, QUE EL VOLTAJE EMPIEZA A BAJAR DESDE EL PICO DE TENSIÓN MÁS ALTA
   
   if (sensorValue<valledetension) // SE CUMPLE LA CONDICIÓN SI LA TENSIÓN DETECTADA POR EL PUERTO ANALÓGICO CERO ES MENOR QUE LA CONTENIDA EN LA VARIABLE VALLEDETENSIÓN
   {
   valledetension=sensorValue; //Se asigna a la variable valledetensión el valor medido por la entrada analógica cero
   }
   
 }
   
 
if (ciclo==1 && cambiodeciclo==0)
   
   {
     cambiodeciclo=1;
     contadorciclo++;
   }
   
if (ciclo==0 && cambiodeciclo==1)
   
   {
     cambiodeciclo=0;
   }
     
}


Igor R

#1
Jun 14, 2012, 02:18 am Last Edit: Jun 14, 2012, 02:51 am by Igor R Reason: 1
4 MHz?? con analogRead ?

Pero si la conversión del ADC son unos 13 ciclos, y como viene configurado en Arduino, creo recordar que tiene el prescaler de 128... si haces las cuentas, estamos hablando de khz..... luego que si Nyquist más todo el código que tienes....
Diría que el ADC como máximo puede ir a una frecuencia de 1 Mhz... es decir, el mínimo tiempo serían unos 13 microsegundos en hacer una conversión.

¿estás seguro de la frecuencia que pones?

Saludos


Igor R.




lm386


4 MHz?? con analogRead ?

Pero si la conversión del ADC son unos 13 ciclos, y como viene configurado en Arduino, creo recordar que tiene el prescaler de 128... si haces las cuentas, estamos hablando de khz..... luego que si Nyquist más todo el código que tienes....
Diría que el ADC como máximo puede ir a una frecuencia de 1 Mhz... es decir, el mínimo tiempo serían unos 13 microsegundos en hacer una conversión.

¿estás seguro de la frecuencia que pones? Veo díficil hasta medir 4MHz con Arduino en una entrada digital....

Saludos


Igor R.






Pues seguramente tienes razón, como no tengo una fuente de señal para comprobarlo, puse 4 Mhz un poco por aproximación, así que seguramente como mucho tendrá 1 Mhz como bien dices.

Igor R

#3
Jun 14, 2012, 02:58 am Last Edit: Jun 14, 2012, 03:05 am by Igor R Reason: 1
Ese código mide muchísimo menos de 1 MHz.... como te he puesto, sin cambiar los registros del micro, sólo la conversión ya le cuesta un rato (16Mhz/128 y 13 ciclos)....
Luego cuenta con el teorema de Nyquist para saber cual es el máximo que puedes capturar.... Por no decir, que si es una onda cuadrada lo que quieres medir, será menor la frecuencia ...

Lo mejor para hacer un frecuencímetro sería usar timer y/o interrupciones (con una entrada digital).


Saludos


Igor R.

lm386

Pues nuevamente tienes razón, desconozco el funcionamiento interno del arduino. Solo llevo unos días trasteando con el arduino y de programación se un poco, pero a nivel hardware y concretamente del arduino se bastante poco. Como dije, es muy posible que tengas razón y este programa solo pueda medir como mucho 100Khz y como mucho digo, pero como te comenté, no dispongo de generador de señal de AF y me resulta imposible a ciencia cierta saber hasta donde llega la frecuencia máxima de lectura de este programa.


Go Up