Frecuenciometro con pic16f874?
| Frecuenciometro con pic16f874? |
|
SigmaOrion
|
Alberth, cuál es la precisión que necesitás en la medición de la frecuencia? Acordate siempre que para medir con una precisión de X Hz necesitás contar ciclos durante 1/X segundos. Por ejemplo, si necesitás un resolución de 0.1Hz vas a tener que contar ciclos de entrada durante 10s.
Por qué decís que el error es muy alto? con qué fijás la frecuencia del PIC, con un cristal? Con esos datos te voy a poder dar una mejor mano. Slds... |
||||||||||||
|
|
|||||||||||||
|
_Eduardo_
|
Como usas mcu , en bajas frecuencias te conviene medir periodo y hacer la division.
Ojo, si no sincronizas el contador local con el primer pulso vas a seguir teniendo demasiado error. |
||||||||||||
|
|
|||||||||||||
|
Alberth
|
hOLA gracias por escribir, lo que estoy haciendo es conabilizar pulsos con un TMR1 durante un determinado tiempo (30mseg). El tiempo lo divido entre el numero total de pulsos obtenidos y eso me da el periodo, solo que tengo un error de 2 a 3 Hz.. A q te refieres con sincronizar el contador local con el primer pulso? Saludos
|
||||||||||||
|
|
|||||||||||||
|
Meta
|
Si te hace falta 600 Hz. Utiliza un oscilador externo con el 555.
|
||||||||||||
|
|
|||||||||||||
|
macraig
|
? 600KHz +-3Hz, no esta mal. es un error de apenas 0,0005%! A q t refieres con demasiado error? Si te fijas, la tolerancia de un cristal tipico es aproximadamente el mismo error q estas obteniendo: 0,0005%. Salu2. |
||||||||||||||
|
|
|||||||||||||||
|
SigmaOrion
|
macraiq, 600Hz, no 600kHz, jejeje. O sea que el error es del 0.5%.
Alberth, qué frecuencia de reloj usás en el PIC? Te aconsejo que lo hagas andar a la mayor frecuencia posible (20MHz) por medio de un cristal. Por otro lado, si contás pulsos de una señal de 600Hz durante 30ms sólo vas a contar 18 ciclos, lo que te va a dar una precisión de 33.3Hz como máximo, el error debería ser mucho mayor. Contá pulsos durante 1/precisión en Hz que necesites. Como te dije arriba en otro post, si querés tener una precisión de 1Hz tenés que contar pulsos durante 1 segundo inevitablemente. La otra es medir período como dice Eduardo, que a bajas frecuencias te va a andar mejor. Slds... |
||||||||||||
|
|
|||||||||||||
|
Alberth
|
Gracias a todos. SigmaOrion, modifique mi programa a un tiempo de muestreo de 0.5seg lo que me da una resolucion de 2Hz, estoy trabajando con un XT de 4MHz. y efectivamente introdusco 100 Hz de señales digitales y el pic mide de 100 a 101 Hz invariadamente, como puedo hacer para que sea super exacto? Obviamente si quiero mayor presicion debo de aumentar mi tiempo de muestreo: 10 seg. Pero eso ya no seria tiempo real.
Saludos. |
||||||||||||
|
|
|||||||||||||
|
f_point
|
Tal como lo miro tu problema radica en que necesitas gran precision pero al mismo tiempo necesitas periodos de muestreo cortos. No es asi Alberth?
De entrada se me ocurre que lo que puedes hacer es un pequeño analisis estadistico de las lecturas de frecuencia. La idea seria tomar lecturas de frecuencias individuales a intervalos cortos, pero en vez de descartar cada lectura medida la envias por el puerto, te quedas con digamos, las ultimas 5 lecturas. Asi, la salida del frecuencimetro podria ser el promedio de las 5 ultimas lecturas, lo que te daria gran precision y al mismo tiempo te permitiria agilizar la tasa de actualizacion. Con tomar varias lecturas y promediarlas estarias elevando indirectamente el tiempo de muestreo, pero al enviar el promedio de las ultimas lecturas a medida que se generan elevas la tasa de actualizacion. Adicionalmente la tecnica estadistica de promediado tiende a elevar la precision al minimizar el error por desviacion de cada lectura. Esta tecnica te funcionaria muy bien siempre y cuando la frecuencia medida sea MUY estable, es decir, que varie muy poco con el tiempo. Otra tecnica que puedes utilizar es la de medicion del periodo de cada pulso y luego calcular el reciproco. Con esto tendrias lecturas tan rapidas como lo que dura cada ciclo de la señal medida, y si usas una fuente precisa de referencia (como un cristal) puedes tener lecturas bastante aceptables. Lo malo de este metodo es que para altas frecuencias (y con altas me refiero a "comparables a las de tu contador de referencia") el error simplemente se elevaria mucho. Necesitaras un contador de referencia de gran velocidad para compensar, y junto con ello una precision numerica bastante elevada, que podria provocar que el PIC se tome su pequeño tiempo para hacer los calculos de reciproco. Imagino que con respecto a este ultimo metodo (sugerido por _Eduardo_ por cierto), el mayor problema seria el de "sincronizarte" a la señal de entrada, es decir, iniciar la cuenta de tiempo del periodo tan rapidamente como sea posible en cuanto el flanco inicial se presente. Usualmente los microcontroladores tienen un tiempo de retardo para reaccionar a eventos externos (una interrupcion por ejemplo), pero esa problematica puede arreglarse con un pequeño truco: Digamos que al generarse el flanco se interrumpe el MCU, digamos ademas que el MCU tarda 20 clocks (por inventarme un numero) desde que se genera la interrupcion hasta que el mismo hecha a andar el contador. Esto te pondria en plena desventaja, puesto que has perdido parte del periodo de la señal al iniciar la lectura y naturalmente te generara un error sustancial. Que hacer? La solucion es simple: La siguiente interrupcion determinara que el ciclo de la señal se ha terminado, por lo que simplemente se vuelve a interrumpir al MCU y hace un proceso similar con la leve diferencia que ahora detiene el contador en vez de iniciarlo... pero para ajustar las cosas, deliberadamente provocamos que se tarde EXACTAMENTE la misma cantidad de tiempo que al principio (es decir, los 20 clocks). Lo que ocurriria es mas o menos algo asi: Señal -----|Inicio----------------------------------------------|Fin-------------------------- MCU ----------|Contador arranca-------------------------------|Contador para----- Espero que el diagrama simplificado no se deforme con tu fuente. La idea basica es que aunque el MCU se atrasa, el periodo medido es siempre el mismo, porque se atrasa la misma cantidad de tiempo con cada interrupcion. Yo use este metodo alguna vez cuando hice un proyecto muy similar al tuyo, y debo agregar que produjo una precision impresionante (+/- 1 LSB de 4 digitos que habia disponibles). Sin embargo usaba la tecnica de medidion de pulsos a un intervalo fijo, pero el concepto es el mismo. En cuanto al "baile" de +/- un conteo en las lecturas sucesivas, creo que se puede hacer algo al respecto. Pero primero que nada, a que se debe? Bueno, ese mas o menos 1 con cada lectura se origina precisamente porque cuando se interrumpe la "medicion" para enviar el dato, inevitablemente parte del ciclo en curso de la señal de entrada queda inconcluso, y cuando se inicia la lectura nuevamente, el resto del ciclo inconcluso se mete a la siguiente medicion y agrega uno mas a la cuenta cuando no ha ocurrido en su totalidad desde el inicio de la medicon... digamos que es una especie de residuo (o puedes verlo tambien como un corrimiento de fase entre tu periodo de medicion y la señal de entrada al no ser de frecuencias con multiplos exactos). Lo mismo podria ocurrir en un siguiente ciclo de medicion pero en sentido inverso, con lo que ahora perderiamos una cuenta de la señal de entrada. Se puede solventar? Claro que si: Eliminando los "residuos variables" por medio de esperar a que ocurra el siguiente flanco de la señal de entrada (positivo o negativo, no importa), y a continuacion echa a andar el contador. Uno pensaria que eso podria agregar cierto error en la lectura ya que el MCU tiene que responder a un evento externo... pero en realidad, eso no importa, ya que aunque existe retardo, el corrimiento de fase sera constante asi como el periodo de medicion, y tus lecturas seran casi tan estables como la frecuencia de entrada. Eso seria todo, espero mis comentarios te sean utiles ^_^ Suerte con tu proyecto. |
||||||||||||
|
|
|||||||||||||
|
_Eduardo_
|
Tenes que iniciar el intervalo de conteo junto con el flanco ascendente (o descendente) de la señal, si no siempre vas a tener una incertidumbre de una cuenta (como ya dijo f_point).
Eso vale tanto para la medicion de frecuencia clasica (intervalo de conteo fijo) como para la de periodo clasica (intervalo de conteo variable) Con PIC, podes usar TMR0 para conteo y TMR1 para medir el intervalo. * La sincronizacion de inicio la haces cargando TMR0 con FF, cuando llegue el primer pulso pasa a 00 y te genera una interrupcion -> ahi reseteas TMR1. * A TMR1 lo tenes programado con el valor de prescaler apropiado de manera que te de Overflow en un tiempo razonable (por ejemplo entre 100ms y 500ms) , ahi te va a generar otra interrupcion. * Generada la interrupcion, lees la cuenta de TMR0 (nro de pulsos que han entrado) y le escribis FF, de manera que ahora se produzca otra interrupcion en el siguiente pulso. * En esta interrupcion final, lees la cuenta de TMR1 y todo lo que queda es hacer la cuenta: Frec = k*(nTMR0+1)/(nTMR1+65536) (con los recaudos numericos apropiados) Tambien, si el valor va a ser leido por una PC, puedo mandar solamente el valor de los contadores (8+16 bits en total) y que la division se haga afuera. Comentarios. * Fijate que la secuencia puede modificarse para que sea un bucle continuo sin necesidad de cargar dos veces FF en TMR0. * Hay que tomar precauciones de soft para el caso frecuencias estremadamente bajas o cero (continua) porque si no te vas a morir esperando un flanco ascendente. * En el codigo hay que tratar que los retardos del PIC entre el evento y la lectura de los contadores sean lo mas iguales (o bajos) posibles para disminuir el error. En caso de necesitar mas precision se puede agregar algunas compuertas y dos flipflop D para habilitar/inhibir los contadores (TMR1 pasa a contar de un reloj externo). * Este metodo tambien sirve en frecuencias altas, con la salvedad que como TMR0 (8 bits) dara overflow a cada rato, hay que ir incrementando por soft un registro y refinar el manejo de la interrupcion. |
||||||||||||
|
|
|||||||||||||
|
| Temas de interés | |
|---|---|
| Sensor para contar monedas | |
| Contar pulsos en determinado tiempo | |
| contador des(192) cuando llegue a cero no vuelva a contar | |
| Comenzar a contar desde 0 | |
| Como conectar la 7490 para contar hasta 9 | |
| Foros de Electronica |
|
||
Cuestiones Elementales de Electrónica
||
Fuentes de alimentacion
||
Circuitos de radio
||
Diseño de circuitos en general
|| || Sistemas de Audio: Preamplificadores, Ecualizadores || Amplificadores || Reparación || Discusión || || Microcontroladores y sistemas embebidos || Circuitos logicos combinacionales y secuenciales || Interfases y Programacion || Dudas en general || Sistemas de Video || PC Hardware || Telematica y comunicaciones || Tecnologias moviles || Software Electronico || Robotica, Domotica y Mecatronica || Autotrónica || Automatizacion, Electronica industrial y de Potencia || Documentacion, circuitos y esquemas || Donde Las Ideas Convergen... || Tutoriales y Manuales || Proyectos Prácticos || |
Site Map
© Foros de Electrónica
Comunidad Internacional de Electrónicos
Powered by phpBB © 2001, 2005 phpBB Group
Acerca de || Política de privacidad
Generada en = 0.32302 segundos, Consultas = 13
© Foros de Electrónica
Comunidad Internacional de Electrónicos
Powered by phpBB © 2001, 2005 phpBB Group
Acerca de || Política de privacidad
Generada en = 0.32302 segundos, Consultas = 13

