Hola muy buenas a todos!!, estoy haciendo un proyecto que consiste en calcular la frecuencia de una señal analógica. Miro el tiempo en un máximo y luego en el siguiente máximo (de la señal), luego resto uno con otro obteniendo el periodo y finalmente calculo la inversa obteniendo la frecuencia...peeeero, no me funciona. Aquí mando el código a ver si vosotros podeis ver donde esta mi fallo. Muchas gracias de antemano, Saluuuudos!
unsigned long v;
unsigned long valormayor = 0;
float tiempodeperiodo;
unsigned long frec;
float uno = 1000000;
unsigned long time1;
unsigned long time2;
void setup(){
Serial.begin(9600);
}
void loop(){
v = analogRead(2);
//Serial.println(v);
if (v==valormayor);
{
time2=micros();
tiempodeperiodo= time2-time1;
frec = uno/tiempodeperiodo;
Serial.println(time1);
Serial.println(time2);
Serial.print("Valor del tiempo: ");
Serial.println(tiempodeperiodo);
Serial.print("Valor de la frecuencia: ");
Serial.print(frec);
Serial.println(" HZ");
}
if (v > valormayor)
{
valormayor = v;
time1=micros();
}
}
Muchas gracias, pero sigue sin funcionar. El problema resumido seria: como calculo la frecuencia de una entrada analogica?
He buscado y hay un contador que cuenta cuantos ciclos hay en un segundo y va bien, pero necesito tambien enviar el valor del sensor para hacer una grafica en c# por tanto no puedo enviar la frecuencia cada segundo ya que necesito aumentar la frecuencia de muestreo. Algguna idea? Gracias.
int v; // Valor señal leida
int vmax=0; // Valor maximo leido
int h=0; // histeresis de la señal (no se cual sera apropiado)
unsigned long inicio=0;
unsigned long ciclo=0;
unsigned long frec;
void setup(){
Serial.begin(9600);
}
void loop()
{
v = analogRead(2); // Leer señal
if (v>vmax) // Si aparece un nuevo valor maximo
{
vmax=v; // Almacenamos nuevo valor maximo
inicio=micros(); // Inicio de ciclo
}
if (v>=vmax-h) // Cresta señal
{
ciclo=micros()-inicio; // Tiempo de ciclo
inicio=micros(); // Inicio siguiente ciclo
frec=1000000.0/ciclo;
Serial.print("Valor de la frecuencia: ");
Serial.print(frec);
Serial.println(" HZ");
}
}
Muchisimas gracias por la respuesta y el intento de ayuda, pero no funciona. He alimentado la entrada analogica con una señal creada por mi de 3 Hz y la solucion va variando constantemente... :(, he probado con diferentes frecuencias, 3, 30 o 300 HZ pero en todos los casos va variando la solución.
Hay que decir que cada 3 resultados 1 es bueno. Por ejemplo excito con una señal de 9Hz, el resultado en el monitor serie es:
Valor de la frecuencia: 125000 HZ
Valor de la frecuencia: 125000 HZ
Valor de la frecuencia: 9 HZ
Valor de la frecuencia: 125000 HZ
Valor de la frecuencia: 125000 HZ
Valor de la frecuencia: 9 HZ
Valor de la frecuencia: 1937 HZ
Valor de la frecuencia: 479 HZ
Valor de la frecuencia: 9 HZ
Valor de la frecuencia: 1923 HZ
Valor de la frecuencia: 1479 HZ
Valor de la frecuencia: 9 HZ
Valor de la frecuencia: 1908 HZ
Valor de la frecuencia: 1479 HZ
Valor de la frecuencia: 9 HZ
Valor de la frecuencia: 1908 HZ
Valor de la frecuencia: 1479 HZ
Valor de la frecuencia: 9 HZ
Valor de la frecuencia: 1879 HZ
Valor de la frecuencia: 1479 HZ
Valor de la frecuencia: 9 HZ
Valor de la frecuencia: 1879 HZ
Valor de la frecuencia: 1479 HZ
Valor de la frecuencia: 9 HZ
Lo simplifique un poco, prueba de nuevo, y ve metiendo valores en h entre 1 y 100, para dar un poco de histeresis a la señal
int v; // Valor señal leida
int vmax=0; // Valor maximo leido
int h=0; // histeresis de la señal (no se cual sera apropiado)
unsigned long inicio=0;
unsigned long ciclo=0;
unsigned long frec;
void setup(){
Serial.begin(9600);
}
void loop()
{
v = analogRead(2); // Leer señal
if (v>h && v>=vmax) // Cresta señal
{
vmax=v-h; // Almacenamos nuevo valor maximo
ciclo=micros()-inicio; // Tiempo de ciclo
inicio=micros(); // Inicio siguiente ciclo
frec=1000000.0/ciclo;
Serial.print("Valor de la frecuencia: ");
Serial.print(frec);
Serial.println(" HZ");
}
}
Gracias de nuevo. Lo he provado pero no funciona, a mas frecuencia mas velocidad muestra el resultado.
Estoy excitando el circuito con una señal sinosoidal de 2 Hz y me da el resultado de 30Hz.
Cuanto mas Histeresis ( al rededor de 30) ya siempre me da 30Hz y si aumento la frecuencia ( de 2Hz a mas) va aumentando la velocidad que muestra el resultado. Parece que el valor que muestra como frecuencia no tiene que ver con la que le estoy metiendo pero si con la velocidad de muestreo.Cuanto menos histeresis(1, 5, 10) algún resultado da bien y tres erroneos...
esta debidamente acondicionada la senal? una senoidal no es apta para ningun micro el valoe negativo romperia el puerto. deberias sumar el ciclo negativo al positivoy contar entre los dos picos.
existe una funcion creo pinIn o algo asi que hace uso de las funciones capture/compare.
Muchas gracias por el aporte. Yo estoy haciendo la prueba con un generador de señales para comprobar el correcto funcionamiento, excito la entrada analógica dos con una señal senosoidal (positivo/negativo) de 2 Hz. Pero el sistema es para calcular la frecuencia de parpadeo de una luz con un fototransistor. Lo que si leo los valores de la entrada A2 son los siguientes:
0
0
0
0
4
8
18
24
23
24
16
6
0
0
0
Y asi succesivamente...
pulseIn() Lee un pulso (ya sea HIGH —alto— o LOW —bajo—) en un pin. Por ejemplo, si value es HIGH, pulseIn() espera a que el pin sea HIGH, empieza a cronometrar, espera a que el pin sea LOW y entonces detiene la medida de tiempo. Devuelve la anchura del pulso en microsegundos. Interrumpe la medida y devuelve 0 si el pulso no ha comenzado en un tiempo especificado. La medida del tiempo en esta función ha sido determinada de forma empírica y está sujeta a errores en pulsos largos. Funciona correctamente en pulsos con una anchura de 10 microsegundos a tres minutos. Sintaxis pulseIn(pin, value) pulseIn(pin, value, timeout) Parámetros pin: el número del pin en el que se realiza la medida del pulso. (int) value: tipo de pulso. Puede ser HIGH o LOW. (int) timeout (opcional): el tiempo en microsegundos máximo a esperar antes de que se inicie el pulso. (unsigned long) Devuelve el ancho del pulso (en microsegundos) ó 0 si el pulso no ha empezado antes del timeout (unsigned long)
Esta es la función, lo que yo empleo una entrada analógica para recibir datos de un sensor esos datos siempre seria High, no?
maxid:
esta debidamente acondicionada la senal? una senoidal no es apta para ningun micro el valoe negativo romperia el puerto. deberias sumar el ciclo negativo al positivoy contar entre los dos picos.
existe una funcion creo pinIn o algo asi que hace uso de las funciones capture/compare.
Tienes razón, la señal que quiero medir y la que utilizo para pruebas no es la misma. Tengo que hacer un filtro antes de meterla en la entrada analógica. Creo recordar que es un filtro RC.
Muchas gracias, seguiré probando.
Muchas gracias amigos, el lunes a primera hora lo comprovaré, ya que no tengo el generador de funciones ni el osciloscopio en casa... están en la universidad y me meto como ''alumno'' y nadie se entera jajaja...
Lo que para el sensor que utilizare finalmente empleo la tensión de 5V del Arduino con una resistencia. El valor de esta, a veces empleo la de 1K 10K... es para no quemar el fototransistor.
0.3v es muy poco. simpre va a ser cero.
el filtro rc, no sirve. como piensas. si para bloquear frecuencias no deseadas
tienes que usar un operacional como rectificador de 1/2 onda. esto lo ideal es que sea una senal cuadrada. Pasando por otro operacional como comparador calibrado al pico de tension.
maxid:
0.3v es muy poco. simpre va a ser cero.
el filtro rc, no sirve. como piensas. si para bloquear frecuencias no deseadas
tienes que usar un operacional como rectificador de 1/2 onda. esto lo ideal es que sea una senal cuadrada. Pasando por otro operacional como comparador calibrado al pico de tension.
Ok gracias, pero cuando pongo en el código para ver el valor de la entrada si que me la lee, ademas da como resultado una onda poniendo a 0 la mitad (parte negativa de la onda), ademas tendria que calcular igualmente el tiempo que tarda en llegar el siguiente pico. Creo que el codigo esta mal ya que cuando aumento la frecuencia aumenta la velocidad de muestreo y el valor resultante siempre es el mismo... :S
Por cierto hablando de la onda cuadrada, yo utilizaré ese sensor que mide la luz para detectar parpadeos de luz en lamparas de como mucho 2/3 Hz, nose hasta que punto puedo transformar esa señal en cuadrada...
ninguna entrada del micro esta preparada para recibir tensiones negativas. n
NINGUNA NI UN RATITO.
en tu caso haces lecturas analogicas de una senal, lo que el conversor demora almenos 20us en darte el valor. el estoboscopico es un 1 prendido y 0 apagado. del ldr nunca vas a obtener una senoidal sino algo parecido a una cuadrada.
si usas un preset en serie con el ldr lo calibras para que de 1 a la intensidad deseada y mas preciso con oamp y filtros