Pregunta

Esta pregunta se basa en una pregunta similar anterior .

Tengo la siguiente ecuación y un (algunos datos aleatorios) ajustado: 0,44 pecado * (N * 2 * pi / 30)

Estoy tratando de utilizar la FFT para obtener la frecuencia a partir de los datos generados. Sin embargo, los extremos de frecuencia hasta estar cerca pero no igual a la frecuencia (lo que hace que la onda un poco más grande que la intención)

Las frecuencias que están en el máximo de la FFT es 7 Hz, sin embargo la frecuencia esperada es de (30 / 2PI) 4.77hz.

He incluido un gráfico de la FFT y valores trazados.

text alt

El código que estoy utilizando es:

[sampleFFTValues sFreq] = positiveFFT(sampledata, 1);
sampleFFTValues = abs(sampleFFTValues);
[v sFFTV]= max(sampleFFTValues)

Positivo FFT puede ser encontrado aquí . Básicamente se centra el gráfico FFT y corta las señales negativas.

Mi pregunta es ¿cómo puedo obtener la FFT para ser más exactos, sin tener que recurrir a los mínimos cuadrados para ajustar la frecuencia?

¿Fue útil?

Solución

No creo FFT es bueno para una medición de frecuencia resolución fina de (cuasi) - señales periódicas. Ver más abajo

Cada FFT discreta ha propagación en frecuencias bin no enteros (que es en cualquier frecuencia que no corresponde exactamente a uno de los pasos de frecuencia de la FFT particular); estas frecuencias "intermedias" se untaron / hacia fuera alrededor de la bin número entero más cercano. La forma de este ( "función de expansión") la difusión depende de la función ventana utilizada para la FFT. Esta función de dispersión - para simplificar y generalizar las cosas - es o muy estrecha, pero muy, muy desigual (muy altos picos / valles muy bajos), o más amplia pero menos desigual. En teoría, se podría hacer un barrido de frecuencias muy fina de ondas sinusoidales y FFT calcular para cada uno de ellos, y entonces usted puede "calibrar" la forma y el comportamiento de la función de ahorro de salidas de todas las FFT junto con la frecuencia que dio lugar a que la producción, y luego comparando la salida FFT de la señal a medir a los resultados previamente guardados y encontrar el "más cercano" uno encuentra una frecuencia más exacta.

Un montón de esfuerzo.

Pero no haga esto si sólo se necesita para medir la frecuencia de una señal única.

En lugar de tratar de medir la longitud de onda. Esto puede ser tan simple como la medición de la distancia entre cero cruces (tal vez por varios ciclos para obtener una mayor precisión - diablos, medir 1.000 ciclos si tiene que muchos) en las muestras, y se dividen por la frecuencia de muestreo que para llegar a la frecuencia. Mucho más simple, más rápido y mucho más preciso.

Ejemplo: 48000 Hz de frecuencia de muestreo, 4,77 resultados de señal Hz en ~ 0,0005 resolución Hz simplemente mediante la medición de la longitud de uno ciclo con el enfoque más cruda. (Si se toma n ciclos, se multiplica la resolución de frecuencia de n también.)

Otros consejos

Como han mencionado otros, está malinterpretando la frecuencia de la señal. Déjenme darles un ejemplo para aclarar algunas cosas:

Fs = 200;                        %# sampling rate
t = 0:1/Fs:1-1/Fs;               %# time vector of 1 second 
f = 6;                           %# frequency of signal
x = 0.44*sin(2*pi*f*t);          %# sine wave

N = length(x);                   %# length of signal
nfft = N;                        %# n-point DFT, by default nfft=length(x)
                                 %# (Note: it is faster if nfft is a power of 2)
X = abs(fft(x,nfft)).^2 / nfft;  %# square of the magnitude of FFT

cutOff = ceil((nfft+1)/2);       %# nyquist frequency
X = X(1:cutOff);                 %# FFT is symmetric, take first half
X(2:end -1) = 2 * X(2:end -1);   %# compensate for the energy of the other half
fr = (0:cutOff-1)*Fs/nfft;       %# frequency vector

subplot(211), plot(t, x)
title('Signal (Time Domain)')
xlabel('Time (sec)'), ylabel('Amplitude')

subplot(212), stem(fr, X)
title('Power Spectrum (Frequency Domain)')
xlabel('Frequency (Hz)'), ylabel('Power')

time_frequency_domain

Ahora se puede ver que el pico en las FFT corresponde a la frecuencia original de la señal a 6 Hz

[v idx] = max(X);
fr(idx)
ans = 
      6

Incluso puede comprobar que de Parseval sostiene:

( sum(x.^2) - sum(X) )/nfft < 1e-6

Opción 2

Alternativamente, podemos utilizar las funciones de procesamiento de señales de la caja de herramientas:

%# estimate the power spectral density (PSD) using the periodogram
h = spectrum.periodogram;
hopts = psdopts(h);
set(hopts, 'Fs',Fs, 'NFFT',nfft, 'SpectrumType','onesided')

hpsd = psd(h, x, hopts);
figure, plot(hpsd)

Pxx = hpsd.Data;
fr = hpsd.Frequencies;
[v idx]= max(Pxx)
fr(idx)

avgpower(hpsd)

periodograma

Tenga en cuenta que esta función utiliza una escala logarítmica: plot(fr,10*log10(Pxx)) en lugar de plot(fr,Pxx)

Suponiendo N es el tiempo en segundos, su frecuencia es de 1 / 30Hz (y=A * sin( 2* PI * f * t))

Resolución Frecuencia = frecuencia de muestreo / Puntos de FFT

La frecuencia de muestreo se determina por el criterio de Nyquist, la frecuencia de muestreo (muestras / segundo) debe ser al menos dos veces la frecuencia máxima a analizar, por ejemplo, 48 kHz para el análisis de hasta 24 kHz. (Para los datos de la "vida real", es bueno tener un poco de una memoria intermedia).

Por lo tanto, es posible que tenga que aumentar el tamaño de su FFT.

Lo que se busca es un método de estimación de frecuencia, y hay muchos. Una FFT es un componente de varios métodos de estimación. Sólo mediante la bandeja de magnitud de pico, como en el ejemplo, le da la peor resolución (pero el mayor inmunidad al ruido a cualquier otro sinusoides exactamente periódicas). En situaciones de bajo ruido, se puede interpolar. interpolación parabólica de la magnitud logarítmica es una estimación común, pero Sinc interpolación de los resultados de FFT puede ser mejor para una ventana rectangular. Relleno con ceros y haciendo un FFT ya es básicamente equivalente a la interpolación.

Para una sinusoide exacta en cero ruido, se olvide de la FFT, y acaba de resolver la ecuación en 3 incógnitas, que pueden implicar tan poco como 3 o 4 puntos de muestreo no-alias, los algoritmos para hacer esto aquí y aquí .

Yo sólo mencionar algunos otros métodos de estimación de frecuencia en mi DSP página Web .

Si va a generar a partir de una función, en comparación con las muestras de trabajo, se puede generar una gran cantidad de puntos y ejecutar una FFT grande, así que los intervalos de frecuencia son muy pequeñas para alta precisión. Pero no va a resolver el problema de fondo.

En primer lugar, una corrección a su pregunta: (30 / 2PI) no es la frecuencia. La frecuencia de la señal es 1/30 * cualquiera que sea la frecuencia de muestreo que ha utilizado. En segundo lugar, ¿puede decirme cuál era la longitud del vector de SampleData? Cuando FFT devuelve un vector de valores, el valor i-ésimo se corresponderá con f_i = I / N donde N es la longitud de vector y i \ in [0, N-1] ¿Quieres i / N para igualar exactamente 1/30 para algún entero i. En otras palabras, debe ser igual a N 30 * i, es decir, N debe ser un múltiplo de 30. Ahora, era la longitud del vector que utilizó, un múltiplo de 30? Si no intentar hacer, y que debería resolver el problema.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top