MATLAB FFT xaxis begrenzt die Unordnung und die Verschiebung

8

Dies ist das erste Mal, dass ich die fft-Funktion nutze, und ich versuche, das Frequenzspektrum einer einfachen Kosinusfunktion darzustellen:

f = cos (2 * pi * 300 * t)

Die Abtastrate beträgt 220500. Ich zeichne eine Sekunde der Funktion f.

Hier ist mein Versuch:

%Vor%

Warum bekomme ich seltsame Ergebnisse, wenn ich die Frequenz auf 900Hz erhöhe? Diese ungeraden Ergebnisse können durch Erhöhen der X-Achsen-Grenzen von beispielsweise 500 Hz bis 1000 Hz festgelegt werden. Ist das auch der richtige Ansatz? Ich habe bemerkt, dass viele andere Leute fftshift(X) nicht benutzt haben (aber ich denke, dass sie nur eine einseitige Spektralanalyse gemacht haben).

Danke.

    
Jean-Luc 14.03.2012, 00:30
quelle

2 Antworten

12

Hier ist meine Antwort wie versprochen.

Die erste Frage, die sich darauf bezieht, warum Sie "seltsame Ergebnisse erhalten, wenn Sie die Frequenz auf 900 Hz erhöhen", hängt mit der Matlab-Funktion zum Skalieren von Plots zusammen, wie von @ Castilho beschrieben. Wenn Sie den Bereich der X-Achse ändern, wird Matlab versuchen, hilfreich zu sein und die Y-Achse neu zu skalieren. Wenn die Peaks außerhalb des angegebenen Bereichs liegen, vergrößert matlab die kleinen numerischen Fehler, die dabei generiert werden. Sie können dies mit dem 'Ylim' Befehl beheben, wenn es Sie stört.

Aber Ihre zweite, offenere Frage: "Ist das der richtige Ansatz?" erfordert eine tiefere Diskussion. Erlauben Sie mir, Ihnen zu sagen, wie ich eine flexiblere Lösung für Ihr Ziel, eine Kosinuswelle zu planen, machen würde.

Sie beginnen mit folgendem:

%Vor%

Das löst sofort einen Alarm in meinem Kopf aus. Mit Blick auf den Rest des Posts scheinen Sie an Frequenzen im Sub-kHz-Bereich interessiert zu sein. Wenn dies der Fall ist, ist diese Abtastrate übermäßig, da die Nyquist-Grenze (sr / 2) für diese Rate über 100 kHz liegt. Ich nehme an, Sie wollten die übliche Audioabtastrate von 22050 Hz verwenden (aber ich könnte mich hier irren)?

Wie auch immer, Ihre Analyse funktioniert am Ende numerisch OK. Sie helfen sich jedoch nicht dabei zu verstehen, wie die FFT am effektivsten für die Analyse in realen Situationen eingesetzt werden kann.

Gestatten Sie mir zu schreiben, wie ich das machen würde. Das folgende Skript macht fast genau das, was Ihr Skript tut, öffnet aber ein Potential, auf dem wir aufbauen können. .

%Vor%

Sie berechnen eine Zeitachse und berechnen aus der Länge der Zeitachse die Anzahl der FFT-Punkte. Das ist sehr merkwürdig. Das Problem bei diesem Ansatz ist, dass sich die Frequenzauflösung des fft ändert, wenn Sie die Dauer Ihres Eingangssignals ändern, weil N von Ihrer "Zeit" abhängt. Der Befehl matlab fft verwendet eine FFT-Größe, die der Größe des Eingangssignals entspricht.

In meinem Beispiel berechne ich die Frequenzachse direkt aus dem NFFT. Dies ist im Zusammenhang mit dem obigen Beispiel irrelevant, da ich die NFFT auf die Anzahl der Abtastwerte im Signal einstelle. Die Verwendung dieses Formats hilft jedoch, Ihr Denken zu entmystifizieren und es wird in meinem nächsten Beispiel sehr wichtig.

** SEITENHINWEIS: In Ihrem Beispiel verwenden Sie real (F). Wenn Sie nicht einen sehr guten Grund haben, nur den reellen Teil des FFT-Ergebnisses zu extrahieren, dann ist es viel üblicher, die Größe der FFT mit Hilfe von abs (F) zu extrahieren. Dies ist das Äquivalent von sqrt (real (F). ^ 2 + imag (F). ^ 2). **

In den meisten Fällen möchten Sie ein kürzeres NFFT verwenden. Dies liegt möglicherweise daran, dass Sie die Analyse möglicherweise in einem Echtzeitsystem ausführen oder weil Sie das Ergebnis vieler FFTs zusammen berechnen möchten, um eine Vorstellung vom durchschnittlichen Spektrum für ein zeitvariables Signal zu erhalten, oder weil Sie Spektren von Signale, die unterschiedliche Dauer haben, ohne Informationen zu verschwenden. Verwenden Sie einfach den Befehl fft mit einem Wert von NFFT & lt; Die Anzahl der Elemente in Ihrem Signal ergibt ein fft, das aus den letzten NFFT-Punkten des Signals berechnet wird. Dies ist ein wenig verschwenderisch.

Das folgende Beispiel ist für eine nützliche Anwendung viel relevanter. Es zeigt, wie Sie ein Signal in Blöcke aufteilen und dann jeden Block verarbeiten und das Ergebnis mitteln:

%Vor%

Ich benutze ein Hamming-Fenster im obigen Beispiel. Das ausgewählte Fenster sollte der Anwendung Ссылка

entsprechen

Der von Ihnen gewählte Überlappungsbetrag hängt etwas vom Typ des verwendeten Fensters ab. In dem obigen Beispiel gewichtet das Hamming-Fenster die Abtastungen in jedem Puffer gegen Null von der Mitte jedes Rahmens. Um alle Informationen im Eingangssignal zu verwenden, ist es wichtig, eine gewisse Überlappung zu verwenden. Wenn Sie jedoch nur ein einfaches rechteckiges Fenster verwenden, wird die Überlappung sinnlos, da alle Samples gleichmäßig gewichtet werden. Je mehr Überlappung Sie verwenden, desto mehr Verarbeitung ist erforderlich, um das mittlere Spektrum zu berechnen.

Hoffe, das hilft deinem Verständnis.

    
learnvst 14.03.2012, 10:20
quelle
2

Ihr Ergebnis ist vollkommen richtig. Ihre Berechnung der Frequenzachse ist ebenfalls richtig. Das Problem liegt auf der Y-Achse. Wenn Sie die Funktion xlims verwenden, berechnet Matlab automatisch die y-Skala neu, so dass Sie "aussagekräftige" Daten sehen können. Wenn die Kosinusspitzen außerhalb der von Ihnen gewählten Grenze liegen (wenn f & gt; 500 Hz), gibt es keine zu zeigenden Spitzen, daher wird die Skala basierend auf einem kleinen Rauschen berechnet (hier bei meinem Computer, mit matlab 2011a war die y-Skala 10) -16).

Das Ändern der Grenze ist in der Tat der richtige Ansatz, denn wenn Sie es nicht ändern, können Sie die Spitzen im Frequenzspektrum nicht sehen.

Eins ist mir jedoch aufgefallen. Gibt es einen Grund, den wahren Teil der Transformation zu zeichnen? Normalerweise wird abs(F) geplottet und nicht der reale Teil.

edit: Eigentlich bist du Frequenzachse nur richtig, da df, in diesem Fall, 1 ist. Die Faxzeile ist richtig, aber die df-Berechnung ist nicht.

Die FFT berechnet N Punkte von -Fs / 2 bis Fs / 2. Also ergeben N Punkte über einen Bereich von Fs ein df von Fs / N. Als N / Zeit = Fs = & gt; Zeit = N / Fs. Ersetzen Sie dies durch den Ausdruck von df, den Sie verwendet haben: your_df = Fs / N * (N / Fs) = (Fs / N) ^ 2. Als Fs / N = 1 war das Endergebnis richtig: P

    
Castilho 14.03.2012 03:11
quelle

Tags und Links