Frage

Diese Frage basiert auf einer vorhergehenden Frage.

I habe die folgende Gleichung und ein bereinigtes (einige zufälligen Daten): 0,44 * sin (N * 2 * PI / 30)

Ich versuche, die FFT zu verwenden, um die Frequenz aus den Daten erzeugt zu bekommen. Jedoch ist die Frequenz endet nahe zu sein, aber nicht gleich die Frequenz (die den macht etwas größer als beabsichtigt Welle)

Die Frequenzen, die bei der maximal für die FFT sind 7Hz ist jedoch die erwartete Frequenz (30 / 2PI) 4.77hz.

Ich habe ein Diagramm der FFT und zeichneten Werte enthalten.

alt text

Der Code ich verwende ist:

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

können Positive FFT sein gefunden hier . Im Grunde ist es die Mitte der FFT Graph und schneidet die negativen Signale.

Meine Frage ist, wie kann ich die FFT erhalten genauer zu sein, ohne dass nur die Frequenz der kleinsten Quadrate zu müssen?

War es hilfreich?

Lösung

Ich glaube nicht, FFT ist gut für eine Feinauflösung Frequenzmessung für (quasi-) periodische Signale - siehe unten.

Jede diskrete FFT hat dich auf nicht-ganzzahlige sind Frequenzen Spreiz (die auf jeder Frequenz ist, die nicht genau mit einem des Frequenzschritt des jeweiligen FFT entsprechen); Diese „intermediate“ Frequenzen um die nächste ganze Zahl ist verschmiert / verteilt werden. Die Form dieses Spreiz ( „Ausbreitungsfunktion“) hängt von der Fensterbildungsfunktion für die FFT verwendet. Diese Ausbreitungsfunktion - zu vereinfachen und zu verallgemeinern Dinge - entweder sehr schmal, aber sehr, sehr zackig (sehr hohe Gipfel / sehr niedrige Täler) oder breite, aber weniger zackig. Theoretisch könnte man einen sehr feinen Frequenz-Sweep von Sinuswellen tun und berechnen FFT für jeden von ihnen, und dann könnte man „eichen“ die Form der Funktion und Verhalten von Ausgaben aller FFTs zusammen mit der Frequenz speichern, die in dieser Ausgabe zur Folge, und dann durch die FFT-Ausgabe des Signals im Vergleich zu vermessenden zu den zuvor gespeicherten Ergebnisse und die Suche nach der „nächsten“ man sich eine genaue Frequenz finden.

Viel Aufwand.

Aber nicht dies tun, wenn Sie nur die Frequenz eines einzigen Signals müssen gemessen werden.

Stattdessen versuchen Wellenlänge zu messen. Dies kann so einfach sein wie der Abstand zwischen Nulldurch Messung (vielleicht für mehrere Zyklen mehr Präzision erhalten - Heck, messen 1000 Zyklen, wenn Sie, dass viele von ihnen haben) in den Proben, und teilen, indem er, dass die Abtastrate bei der Frequenz zu gelangen. Viel einfacher, schneller und viel präziser.

Beispiel: 48000 Hz Abtastrate, 4,77 Hz-Signal ergibt ~ 0,0005 Hz Auflösung nur durch die Länge von Messen von einem Zyklus mit dem gröbsten Ansatz. (Wenn Sie n Zyklen, die Frequenzauflösung vervielfacht durch n als auch.)

Andere Tipps

Wie bereits von anderen erwähnt, wird falsch interpretiert man die Frequenz des Signals. Lassen Sie mich ein Beispiel geben, ein paar Dinge zu löschen:

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

Jetzt können Sie sehen, dass die Spitze in dem FFT entspricht die ursprüngliche Frequenz des Signals bei 6 Hz

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

Wir prüfen auch, dass Parseval-Theorem gilt:

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

Option 2

Alternativ können wir die Signalverarbeitung Toolbox-Funktionen verwenden:

%# 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)

periodogram

Beachten Sie, dass diese Funktion verwendet eine logarithmische Skala: plot(fr,10*log10(Pxx)) statt plot(fr,Pxx)

Angenommen N ist die Zeit in Sekunden, Ihre Frequenz ist 1 / 30Hz (y=A * sin( 2* PI * f * t))

Frequenzauflösung = Sample Rate / FFT Punkte

Die Abtastrate wird durch das Nyquist-Kriterium, die Abtastrate (Abtastungen / Sekunde) bestimmt, müssen mindestens zwei mal die maximale Frequenz analysiert werden, z.B. 48kHz bis 24kHz für die Analyse auf. (Für „real life“ Daten, es ist gut, ein bisschen ein Puffer zu haben).

So, müssen Sie möglicherweise die Größe der FFT erhöhen.

Was Sie suchen ist ein Frequenzschätzverfahren, und es gibt viele. Eine FFT ist eine Komponente von mehreren Schätzverfahren. Nur mit Hilfe der Spitzengröße ist, wie in Ihrem Beispiel gibt Ihnen die schlechteste Auflösung (aber die größte Störsicherheit zu anderen genau periodischen Sinusoide). In geringem Rauschen Situationen können Sie interpolieren. Parabolische Interpolation der logarithmischen Größe ein gemeinsamer Schätzer, aber Sync Interpolation der FFT-Ergebnisse kann für ein rechteckiges Fenster besser sein. Zero-Padding und eine längere FFT tut, ist im Grunde äquivalent zu Interpolation.

Für eine genaue Sinuskurve in Lautlos, vergessen die FFT und löst nur die Gleichung in drei Unbekannten, die so wenig wie 3 oder 4 Nicht-aliased Abtastpunkte, Algorithmen, dies zu tun? hier und hier .

ich Liste einige andere Frequenzschätzmethoden auf meinem DSP Webseite .

Wenn Sie von einer Funktion generieren, im Vergleich mit Proben arbeiten, können Sie eine Menge Punkte generieren und ein BIG fft laufen, so dass der Frequenz-Bins für hohe Präzision sehr klein ist. Aber es wird das Grundproblem nicht lösen.

Als erstes wird eine Korrektur auf Ihre Frage: (30 / 2PI) nicht die Frequenz. Die Frequenz des Signals ist 30.01 * was Abtastrate Sie verwendet haben. Zweitens können Sie mir sagen, was die Länge der Sample Vektor ist? Wenn ein FFT-Vektor von Werten zurückkehrt, wird der i-te Wert entspricht f_i i = / N, wobei N Länge des Vektors und i \ in [0, N-1] Sie wollen i / N genau 30.01 für eine ganze Zahl i gleich. Mit anderen Worten, sollte N 30 gleich * i, dh, sollte N ein Vielfaches von 30 sein Nun wird die Länge des Vektors war sie verwendet, ein Vielfaches von 30? Wenn nicht versuchen, es zu machen, und das sollte das Problem lösen.

Versuchen Sie, eine Windowing-Funktion ?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top