4 votos

Identificación del desplazamiento de frecuencia de 40 Hz

Tengo una señal que está a 4 kHz. Esta señal se desplaza 40 Hz dependiendo de alguna entrada del usuario. Me gusta detectar este cambio en el software tan rápido como pueda. ¿Cuál debería ser la frecuencia del ADC que debo utilizar?

Actualmente planeo muestrear a 40 kHz y utilizar una ventana de 10 ms para hacer una FFT para averiguar este desplazamiento. Pero antes de construir el sistema, me gustaría tener una segunda opinión.

0 votos

Una FFT es una exageración y no te dará una resolución razonable sin muchos ciclos.

12voto

RelaXNow Puntos 1164

Para replantear tu problema, tienes una señal de entrada en el rango de frecuencia de 3960-4040 Hz, y quieres determinar esta frecuencia sobre la marcha. Muchos microcontroladores pueden hacer esto de forma bastante sencilla.

La frecuencia más alta de interés es 4,04 kHz, que tiene un periodo de 248 µs. Es un tiempo "largo" incluso para un micro pequeño y barato. En el otro extremo, 1/3,96kHz = 253 µs, así que quieres determinar el periodo de la señal en un rango de 5 µs. No has dicho qué resolución quieres, así que digamos 1 parte en 50, lo que significa que puedes conseguir lo que quieres si puedes medir el periodo hasta 100 ns.

Todo esto es bastante factible en muchos microcontroladores, que tienen la capacidad de tomar una instantánea de un temporizador de funcionamiento libre en un borde particular de una señal de entrada. En los PICs de 8 bits, esta es una de las cosas que puede hacer el módulo CCP (Compare, Capture, Pulse-width modulation). En los PICs de 16 bits se llama módulo "Input Capture". De cualquier manera, terminas con una instantánea del temporizador de 16 bits cada ciclo de tu señal entrante.

Para determinar el periodo del ciclo anterior, basta con hacer una resta sin signo del nuevo valor de captura menos el anterior. Esto funciona tanto si el temporizador se envolvió durante ese ciclo como si no, siempre que el periodo no exceda el tiempo de envoltura del temporizador. Si usted reloj el temporizador a 10 MHz, entonces usted obtendrá los valores de 2475 a 2525, con la resta de rendimiento el período en unidades de 100 ns.

No dices para qué quieres la frecuencia, pero quizás puedas usar este periodo directamente. Si realmente necesitas la frecuencia (piénsalo bien, puede que no), entonces haces la división. Incluso con el micro funcionando sólo a 10 MHz, tienes más de 2000 ciclos de instrucción por ciclo de entrada, que es mucho para una división. En un PIC de 16 bits, puedes hacer la división en hardware en sólo 18 ciclos.

En cualquier caso, yo haría un pequeño filtrado de paso bajo en los períodos medidos antes de hacer cualquier otro procesamiento. Esto hará que tu sistema sea menos susceptible al jitter e incluso puede reducir un poco el ruido de cuantificación. Ten en cuenta que una señal de banda limitada de 3960-4040 Hz no puede cambiar su frecuencia tan rápido. Los cambios aparentes en la frecuencia por encima de algún límite están garantizados como ruido.

3voto

Bernd Puntos 61

¡¡¡Yo pensaría que la forma más fácil y rápida de notar el desplazamiento de frecuencia de la señal de entrada es simplemente medirla directamente!!! Esto es lo que yo haría.

Proporcionar una versión de los niveles de señal digital de su señal. Si la señal es alguna sinusoide de bajo nivel o similar, esto puede requerir alguna amplificación y luego la cuadratura de la señal a las oscilaciones de la señal digital.

Consigue un microcontrolador sencillo que tenga algunos temporizadores de 16 bits que puedan ser activados para contar el periodo de tu señal de entrada desde el flanco de subida hasta el flanco de subida. Hay una plétora de microcontroladores que pueden soportar este requisito.

Con una señal que tiene una frecuencia básica de 4KHz estás tratando con un periodo de 0,25 mseg. Si configuras tu microcontrolador con un temporizador de 16 bits con una frecuencia de 8 MHz, puedes contar 2.000 ticks en un periodo de la señal de entrada. Cuando la frecuencia de la señal de entrada se desplaza hasta 4,04KHz entonces estarías contando ~1980 ticks de contador en un periodo de la señal de entrada. Digamos que la señal de entrada baja a 3.96KHz, entonces un periodo de la señal de entrada haría que el temporizador contara ~2020 cuentas.

Esta es realmente la forma más rápida de detectar el cambio de frecuencia dentro de un ciclo de la señal de entrada. También es extremadamente fácil de lograr incluso con algunos de los componentes MCU más simples y de menor costo.

En el pasado he utilizado esta misma técnica para decodificar una señal FSK de baja frecuencia que enviaba datos modulados a frecuencias similares por cables extremadamente largos sin utilizar ninguna portadora de RF. En ese momento, un MCU 8051 general que funcionaba a 8 o 16 MHz hizo el truco muy bien. En mi caso, con el decodificador FSK era necesario vigilar el tiempo de cada período de señal que bajaba por el cable. Por ello, configuré el MCU con dos temporizadores para medir el periodo de la señal en ciclos alternativos de la señal de entrada. Esto permitía analizar y calcular la medición de un periodo mientras se medía el siguiente. (En los procesadores más antiguos se podía perder un número de cuentas en el temporizador si se intentaba rearmar el uso del mismo temporizador para cada período y cuando se trata de sólo 20 cuentas de 2000 eso puede ser bastante serio).

Una buena ventaja de este enfoque es que se puede detectar un rango de recuentos capturados por período como un rango de entrada válido en lugar de buscar un valor de recuento distinto. Esto permitirá que una pequeña deriva de frecuencia no altere la decodificación de la entrada. Además, con la medición ciclo a ciclo es posible medir la anchura de la envolvente de modulación FSK para verificar que está dentro del rango apropiado para cualquier protocolo que se utilice para enviar información por el cable.

Todo ello sin PLLs, ni FFTs, ni filtros. Simplemente.

1 votos

Es una buena sugerencia, pero depende de la naturaleza de la señal que tenga. La detección de paso por cero modulará el ruido fuera de banda en la señal FSK, lo que degradará significativamente el rendimiento incluso a niveles de ruido moderados.

2voto

El espectro de la señal sólo se extiende hasta 4,04kHz, por lo que 40kHz será más que suficiente como explica el Teorema de Nyquist . Tenga en cuenta que la resolución del intervalo de muestreo no limita la resolución de frecuencia que puede detectar en la señal, a menos que la cuantifique a 1 bit. Mientras los errores de cuantificación no inunden la señal, el doble de la componente de frecuencia más alta más un margen de filtro antialiasing es todo lo que se necesita. Todo lo que sea más alto no añade ninguna información útil.

En cuanto a tu algoritmo, parece bastante excesivo hacer una FFT simplemente para extraer un desplazamiento de frecuencia de banda estrecha. Si la frecuencia de la señal es lo suficientemente estable, yo miraría de tener un par de filtros notch a 4,04kHz y 4,00kHz, calculando la magnitud de salida de los mismos, y utilizando el más grande para determinar dónde está la señal. Puedes utilizar un filtro multivelocidad para producir un algoritmo extremadamente eficiente.

Tenga en cuenta que esto es matemáticamente equivalente a hacer una DFT con un muestreo ascendente y una ventana para obtener la discriminación de frecuencia requerida, y luego descartar todos los coeficientes excepto los dos que corresponden a las ubicaciones del filtro de corte. Este es el algoritmo que se trata de hacer, pero como se tiene tanto espectro en blanco no tiene mucho sentido calcular todos los demás coeficientes, por lo que una solución en el dominio del tiempo debería ser más eficiente.

1voto

FakeMoustache Puntos 6645

Dado que quieres una resolución de frecuencia de al menos 40 Hz, creo que necesitas una ventana de al menos 1/40 Hz = 25 ms

¿Está familiarizado con Matlab (o con Octave, un clon gratuito de Matlab) o está dispuesto a aprenderlo? Entonces podrías probarlo fácilmente y ver qué consigues.

1voto

JRE Puntos 4167

10 milisegundos no son suficientes. Una simple FFT a 40kHz con un tamaño de bloque equivalente a 10 milisegundos le dará una resolución de frecuencia de 100Hz.

50 milisegundos le darán una resolución de 40 Hz, que apenas le permitirá "ver" la diferencia. A esa resolución, habrá un "bin" entre 4040 y 4000 - es decir, 4000, 4020, 4040.

Para calcular la resolución, haz lo siguiente:

  1. Calcular el número de bins: (longitud del bloque en segundos)*(frecuencia de muestreo)/2
  2. Calcular la resolución: ((frecuencia de muestreo)/2)/(número de bins)

Sin embargo, una FFT puede no ser la opción correcta. Una FFT sólo puede utilizar tamaños de bloque que sean potencias de 2 (512, 1024, etc.) Los bins no se alinearán con las frecuencias deseadas en los tamaños de bloque necesarios, lo que te llevará a tener que interpolar entre bins y otras cosas divertidas.

Una DFT no está limitada a determinados tamaños de bloque, pero suele ser mucho más lenta. Se pueden modificar los tamaños de los bloques para obtener exactamente los intervalos deseados, pero el cálculo puede ser mucho más lento (más pasos, más ciclos de CPU).

Podría ser más rápido (desde el punto de vista de la CPU) utilizar una FFT de mayor resolución en lugar de una DFT con los bins exactos que desea. Entonces, podrías utilizar las sumas de los bins seleccionados para aproximar el valor real de 4000 y 4040.

Si está restringido en los ciclos de la CPU, es posible que desee buscar en el Algoritmo Goertzel. Un simple microprocesador puede hacerlo funcionar y realizar la detección en tiempo real de las frecuencias seleccionadas. Puede ser fácilmente sintonizado para dar la separación necesaria. En el código enlazado, utilice el método tandemRTgoertzelFilter. La variable "RESETSAMPLES" se puede utilizar para controlar la selectividad - un número más alto separará mejor, pero tomará más muestras para calcular.

0 votos

Un malentendido común: Se puede hacer una FFT con cualquier tamaño de bloque. Las potencias de dos son las más rápidas y sencillas de implementar. Sin embargo, estoy de acuerdo con tus otras conclusiones :-)

0 votos

La mayoría de las implementaciones de FFT sólo utilizan potencias de 2. Algunas de las bibliotecas de FFT que he visto aceptan cualquier tamaño de bloque, pero pueden cambiar a una DFT internamente o utilizar algún otro método para lograr el tamaño de bloque dado. No soy lo suficientemente matemático como para discutir si la FFT puede o no utilizar otros tamaños de bloque, sólo sé que generalmente no se hace.

3 votos

Existen algoritmos rápidos para todas las potencias de dos y para todos los números primos. Cada tamaño de bloque N se puede manejar haciendo una cadena FFT basada en los factores primos de N. La mayoría de las librerías de FFT que existen sólo tratan con pow2, como has dicho, y eso hace que la gente piense que pow2 es necesario. Si quieres un tamaño de bloque de 1280, por ejemplo, puedes empezar con FFTs de tamaño 5 seguidas de FFTs con tamaño de bloque 256. Eso será más rápido que redondear a la siguiente potencia de dos.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X