Hallo, ich bastel gerade mittels CMSIS auf einem ARM Cortex-M3 eine FFT. Soweit ich es beurteilen kann, funktioniert sie auch soweit. Meine Fragen beziehen sich auf die korrekte Auswertung einer FFT, da mich die Testergebnisse etwas ins Schleudern bringen. Das Testsetup: der DAC generiert nacheinander Sinussignale mit Frequenzen von 1333Hz, 1000Hz, 500Hz, 333Hz, 250Hz, 125Hz, 9Hz und 4Hz. Die Ausgabe habe ich mit dem Oszi geprüft. Der ADC liest das Signal mit ca. 1kHz in einen 512 Wörter großen Buffer, wobei jedes zwei Wort für den Imaginäranteil auf 0 gesetzt ist, es werden also 256 Werte gelesen (Messdauer ca. 1/4s). Die FFT arbeitet mit 256 Werten. 1) Das erste "Bin" einer FFT gibt den DC-Anteil des Signals an, korrekt? Wenn ja, welchen Bereich decken dann die restlichen Bins jeweils ab: Wenn ich es richtig verstanden habe, ist die Bandbreite eines Bins die Dauer der Erfassung geteilt durch die FFT-Größe, ist das richtig? Oder geteilt durch die FFT-Größe minus eins? 2) Wenn die Berechnung aus #1 korrekt ist, arbeitet die FFT falsch, denn ich komme beim Testsetup auf 1Hz Breite, die FFT hat aber die größten Peaks jeweils beim halben Bin, also quasi 2Hz Bandbreite. Wo liegt mein Denkfehler? 3) Da ich nur reale Werte messe und der Imaginärteil immer 0 ist, deckt die FFT nur die Hälfte ab, da sie quasi in der oberen Hälfte gespiegelt ist, korrekt? Mit dem Testsetup kann ich demnach unter Beachtung der Nyquist-Frequenz nur bis 250Hz korrekt erfassen, richtig? 4) Ein paar der Testfrequenzen sind absichtlich über der Nyquistfrequenz gewählt. Soweit ich anhand der Testauswertung erkennen kann, ist es nicht möglich, solch einen Fehlerfall anhand der FFT-Daten festzustellen, korrekt? Danke für eure Hilfe. Ralf
Ralf schrieb: > 3) Da ich nur reale Werte messe und der Imaginärteil immer 0 ist, deckt > die FFT nur die Hälfte ab, da sie quasi in der oberen Hälfte gespiegelt > ist, korrekt? Mit dem Testsetup kann ich demnach unter Beachtung der > Nyquist-Frequenz nur bis 250Hz korrekt erfassen, richtig? Nö, du müsstest bis 500 Hz kommen, dafür aber nur mit ~2 Hz Auflösung, weil nur 256 Samples aufgezeichnet werden. Die 1 Hz Auflösung hättest Du bei 0,5 s Messzeit und 500 Samples.
:
Bearbeitet durch User
Ralf schrieb: > 1) Das erste "Bin" einer FFT gibt den DC-Anteil des Signals an, korrekt? Ja. > Wenn ja, welchen Bereich decken dann die restlichen Bins jeweils ab: > Wenn ich es richtig verstanden habe, ist die Bandbreite eines Bins die > Dauer der Erfassung geteilt durch die FFT-Größe, ist das richtig? Oder > geteilt durch die FFT-Größe minus eins? Geteilt durch die FFT-Größe, wenn ich mich nicht irre. > 2) Wenn die Berechnung aus #1 korrekt ist, arbeitet die FFT falsch, denn > ich komme beim Testsetup auf 1Hz Breite, die FFT hat aber die größten > Peaks jeweils beim halben Bin, also quasi 2Hz Bandbreite. Wo liegt mein > Denkfehler? Du machst eine complex-to-complex-Transformation. Die hat AFAIK doppelt so viel Bandbreite, also die Nyquist-Frequenz ist gleich der Samplerate. (real natürlich nicht, weil du den Imaginärteil nicht kennst ... du weißt was ich meine). > 3) Da ich nur reale Werte messe und der Imaginärteil immer 0 ist, deckt > die FFT nur die Hälfte ab, da sie quasi in der oberen Hälfte gespiegelt > ist, korrekt? Mit dem Testsetup kann ich demnach unter Beachtung der > Nyquist-Frequenz nur bis 250Hz korrekt erfassen, richtig? Nein, bis 500 Hz. Das ist die halbe Samplerate. > 4) Ein paar der Testfrequenzen sind absichtlich über der Nyquistfrequenz > gewählt. Soweit ich anhand der Testauswertung erkennen kann, ist es > nicht möglich, solch einen Fehlerfall anhand der FFT-Daten > festzustellen, korrekt? Nicht anhand der FFT-Daten und auch ansonsten nicht. Das geht nur mit einem Analogfilter vor dem ADC. Gruß, Sven
Signal 1333Hz vs. 1kHz Abtastrate, Nyquist (oder so). Und btw. nicht mindestens 2mal so hohe Abtasterate sondern mindestens mehr als 2mal so hoch. Aber das ist nur ein kleiner Einwurf.
Hallo, vielen Dank für die Antworten. @Jim: >> 3) Da ich nur reale Werte messe und der Imaginärteil immer 0 ist, deckt >> die FFT nur die Hälfte ab, da sie quasi in der oberen Hälfte gespiegelt >> ist, korrekt? Mit dem Testsetup kann ich demnach unter Beachtung der >> Nyquist-Frequenz nur bis 250Hz korrekt erfassen, richtig? > Nö, du müsstest bis 500 Hz kommen, dafür aber nur mit ~2 Hz Auflösung, > weil nur 256 Samples aufgezeichnet werden. Die 1 Hz Auflösung hättest Du > bei 0,5 s Messzeit und 500 Samples. Dann hab ich aber das falsche Verständnis bzw die falsche Formel für die Berechnung der Bandbreite. 0,5s / 500 = 1Hz (dein Beispiel) ist doch das gleiche wie mein Testsetup mit 0,256s / 256 = 1Hz. @Sven: >> 2) Wenn die Berechnung aus #1 korrekt ist, arbeitet die FFT falsch, denn >> ich komme beim Testsetup auf 1Hz Breite, die FFT hat aber die größten >> Peaks jeweils beim halben Bin, also quasi 2Hz Bandbreite. Wo liegt mein >> Denkfehler? > Du machst eine complex-to-complex-Transformation. Die hat AFAIK doppelt > so viel Bandbreite, also die Nyquist-Frequenz ist gleich der Samplerate. > (real natürlich nicht, weil du den Imaginärteil nicht kennst ... du > weißt was ich meine). Öhm... nein, ich weiss es nicht =D Ich hab ja so gesehen keinen Imaginäranteil. Aber dass man bei einer komplexen Transformation nicht die halbe Frequenz hat, wusste ich nicht. Wo kann ich mich da einlesen? >> 3) Da ich nur reale Werte messe und der Imaginärteil immer 0 ist, deckt >> die FFT nur die Hälfte ab, da sie quasi in der oberen Hälfte gespiegelt >> ist, korrekt? Mit dem Testsetup kann ich demnach unter Beachtung der >> Nyquist-Frequenz nur bis 250Hz korrekt erfassen, richtig? > Nein, bis 500 Hz. Das ist die halbe Samplerate. Das ist klar, weil Nyquist. Aber wenn ich nur reale Werte in die FFT eingebe, dann ist die Ausgabe doch gespiegelt, also kann ich nur bis zur Hälfte der Hälfte (also ein Viertel) erfassen. Oder versteh ich das auch falsch? Ralf
Ralf schrieb: >>> 3) Da ich nur reale Werte messe und der Imaginärteil immer 0 ist, deckt >>> die FFT nur die Hälfte ab, da sie quasi in der oberen Hälfte gespiegelt >>> ist, korrekt? Mit dem Testsetup kann ich demnach unter Beachtung der >>> Nyquist-Frequenz nur bis 250Hz korrekt erfassen, richtig? >> Nein, bis 500 Hz. Das ist die halbe Samplerate. > Das ist klar, weil Nyquist. Aber wenn ich nur reale Werte in die FFT > eingebe, dann ist die Ausgabe doch gespiegelt, also kann ich nur bis zur > Hälfte der Hälfte (also ein Viertel) erfassen. Oder versteh ich das auch > falsch? Ich glaub das verstehst du falsch, aus N reellen Eingabewerten bekommst du N/2 nutzbare komplexe Ausgabewerte. Weil du eine complex-to-complex-Transformation machst mit Realteil 0 im Input kriegst du N komplexe Ausgabewerte von denen du die Hälfte wegwerfen musst (das ist die 2 in Nyquist). Hättest du echt komplexe Eingabewerte, wäre die ganze Ausgabe nutzbar und die 2 im Nyquist weg. Das erreicht man in der Praxis zum Beispiel durch I/Q Sampling (wo man effektiv natürlich auch wieder doppelt so viele Samples aufnimmt um den Imaginärteil noch mit zu bestimmen). So zumindest mein Verständnis.
Hi Sven, danke für Antwort. Dann sind die Formeln, die ich zum Verständnis genutzt habe aber falsch. Du meintest, dass durch die Verwendung von rein reellen Werten und der Complex-to-Complex Transformation das Abtasttheorem schon mit drin ist. Also bleibt es dabei, dass die maximal erfassbare Frequenz die halbe Samplefrequenz ist. Soweit klar. Wo ich jetzt noch Verständnisschwierigkeiten habe ist die Bandbreite eines Bins. Die Formel, die ich verwende, ist Abtastdauer geteilt durch FFT-Größe. Also 256 Samples @ 1kHz = 256ms, geteilt durch 256. Damit komme ich auf 1Hz. Die Berechnung taucht zum Beispiel hier auf: http://www.sprut.de/electronic/pic/16bit/dsp/fft/fft.htm#fb Wie bereits erwähnt spuckt meine FFT aber die Bins mit Bandbreiten von 2Hz aus. Das heisst doch, dass das Beispiel aus o.g. Link falsch ist. Oder liegt es daran, dass die Formel davon ausgeht, dass der imaginäre Anteil ebenfalls erfasst wird? Ich verstehe den Zusammenhang noch nicht, woran es liegt, dass meine FFT 2Hz Bandbreite hat. Entweder liegt es daran, dass nur die halbe Samplefrequenz als Berechnungsgrundlage verwendet werden darf oder daran, dass in meinem Fall kein Imaginäranteil dabei ist. Ralf
Hmm. Ich denke bei deiner FFT müsste die Kanalbreite (so nennt man das glaube ich, nicht Bandbreite, die Bandbreite ist die Gesamtbreite) schon 1 Hz sein. Du kannst ja mal ein paar Rohdaten posten und welche Frequenz man darin sehen müsste ...
Außerdem empfehle ich hier mal wieder numpy, in np.fft.rfft, np.fft.fft, np.fft.rfftfreq, np.fft.fftfreq ist das alles auf jeden Fall korrekt implementiert und man kann sich das zum Vergleich anschauen (ffrfreq sagt übrigens auch für reell und nicht-reell eine Kanalbreite von 1 Hz, was sich mit den anderen Überlegungen deckt).
Hi Sven, anbei mal die Daten von 9Hz. Der Peak liegt in Kanal 4 (1. Kanal = Kanal 0). Hab es zusätzlich auch grafisch ausgegeben, grau ist das gemessene Eingangssignal, rot die FFT-Ausgabe. Ralf
Bei 9 Hz müsstest du in 256ms 2.3 Perioden sehen. Ich seh da nur etwas mehr als eine. Entweder deine ADC-Frequenz ist falsch oder das sind keine 9 Hz.
Außerdem würde ich dringend raten eine Windowing-Funktion (Hamming oder so) zu verwenden, der Peak ist wirklich sehr breit ;)
Öhm... das sind doch ca 2,3 Perioden - okay, eher 2,1 oder so, aber bitte beachten, ich habe nicht exakt 1kHz Samplerate, das muss ich noch tunen. Wie oben erwähnt, hatte ich die Eingangsfrequenzen mit dem Oszi geprüft, die sind soweit okay. Window-Funktion wollte ich einbauen, wenn die FFT soweit korrekt funktioniert. Was hältst du nun von den Daten? Hast du eine Idee, warum die Kanalbreite 2Hz ist? Ralf
Hups, hast natürlich recht, ich bin wohl blind. Hast du die Daten als CSV oder so, so ist das schwer zu sagen.
Hi Sven, anbei eine Textdatei mit den Werten vom ADC für die 9Hz, kodiert als Q1.15 und die FFT Ausgabe. Vielen Dank für deine Unterstützung =) Ralf
PS: Die Werte sind bereits in Dezimal gewandelt, sorry. Ralf
Ich hab mal deine Daten und die die ich mit numpy.fft.rfft gerechnet habe geplottet. Deine sind die grünen, und die sind zu weit rechts. Hmm. Ich weiß nicht genau, was du da falsch gemacht hast ... Aber ich würde sagen, das hängt dann eher an der FFT als an der Berechnung der Bingröße. Ich komme auf 4 Hz Kanalbreite ... <- ist ein bisschen verwirrt
Hi Sven, > Deine sind die grünen, und die sind zu weit rechts. Danke für's gegenprüfen. Deine Berechnung gibt die Daten tatsächlich zu weit rechts aus, aber in der Textdatei sieht man ja, dass es im Kanal fünf den höchsten Peak gibt. > Aber ich würde sagen, das hängt dann eher an der FFT als an der > Berechnung der Bingröße. Ich komme auf 4 Hz Kanalbreite ... Das wäre ja dann ein noch größeres "Problem" oO Bisher war ja "nur" von 1Hz vs 2Hz die Rede. Wie kommst du auf 4Hz? Ralf
Ergänzung:
> ...die ich mit numpy.fft.rfft gerechnet habe...
Kann es an der RFFT liegen? Ich verwende eine CFFT.
Ralf
Naja deine Aufnahmelänge ist 250ms, also ist die Kanalbreite 4 Hz (1/250ms). Ich glaube nicht dass das mit RFFT/CFFT zu tun hat, da komme ich bei beidem auf's gleiche Ergebnis...
Guten Morgen Sven, > Ich glaube nicht dass das mit RFFT/CFFT zu tun hat, da komme ich bei > beidem auf's gleiche Ergebnis... Ah, okay. > Naja deine Aufnahmelänge ist 250ms, also ist die Kanalbreite 4 Hz > (1/250ms). Das versteh ich nicht: Ich dachte die Kanalbreite ist Erfassungsdauer / FFT-Größe => 256ms / 256 = 1Hz. Deine Rechnung lässt die FFT-Größe komplett aussen vor. Ralf
Ich versteh's auch nicht, ich dachte, die Kanalbreite sei Abtastfrequenz/FFT_N, im vorliegenden Fall also 1 kHz/256 = 3.9 Hz.
Ne, die FFT-Größe geht da indirekt über die Anzahl aufgenommener Samples und die Samplerate mit ein. Aber die intuitivste Formel für die Binbreite ist finde ich 1/Aufnahmedauer. Aufnahmeauer/FFT-Größe ist m.E. falsch, das hieße ja dass du durch einfaches Erhöhen der Samplerate eine bessere Frequenzauflösung bekommen würdest. Und das ist nicht so. Dadurch erhöht sich nur die Bandbreite.
Hi Leute, mal um etwas Klarheit hier rein zu bringen: n = Anzahl der Eingangssamples = "Länge" des Signals fs = Abtastfrequenz des Signals N = Länge der FFT (kann != n sein, wenn zero padding verwendet wird.) df = fs/N = Frequenzauflösung = Abstand der bins Bei einer "normalen" komplexen fft bekommst du N komplexe Zahlen. Normalerweise guckt man sich den Betrag an (sqrt(Im(x)^2 + Re(x)^2)). Der Frequenzbereich geht von 0 Hz bis fs-df. Man muss etwas aufpassen, es gibt möglicherweise auch Implementationen, die von -fs/2 bis fs/2-df gehen, den DC Anteil also in der Mitte des Arrays haben! Um korrekte Amplituden für ein single sided Spektrum (also nur N/2 Punkte mit Frequenzen von 0 bis fs/2) zu erhalten muss das Ergebnis noch durch n geteilt und alles bis auf den DC Anteil (da dort sozusagen 2 bins drauf fallen) mit 2 multipliziert werden. Erhöhung der Frequenzauflösung geschieht durch Verlängerung der Abtastzeit oder durch Einführung von zeropadding.
:
Bearbeitet durch User
Zeropadding erhöht nicht wirklich die Frequenzauflösung. Das macht nur die Bins schmaler und verschmiert den Peak ...
Hallo Jan, > ...um etwas Klarheit hier rein zu bringen... Nach deiner Ausführung hätte ich dann: n = 256 fs = 1kHz N = 256 df = fs/N = 4Hz Das passt dann auch zum von Sven zur Verfügung gestellten Plot, er hat den Peak beim dritten Kanal, also 2x 4Hz. > Bei einer "normalen" komplexen fft bekommst du N komplexe Zahlen. > Normalerweise guckt man sich den Betrag an (sqrt(Im(x)^2 + Re(x)^2)). > Der Frequenzbereich geht von 0 Hz bis fs-df. > Man muss etwas aufpassen, es gibt möglicherweise auch Implementationen, > die von -fs/2 bis fs/2-df gehen, den DC Anteil also in der Mitte des > Arrays haben! Was heisst "normale" CFFT? Du meinst wenn ich in meinem Fall den Imaginärteil auch mit Phasendaten füttern könnte? Und für meine Implementierung wäre dann der Frequenzbereich (fs/2)-df, korrekt? > Um korrekte Amplituden für ein single sided Spektrum (also nur N/2 > Punkte mit Frequenzen von 0 bis fs/2) zu erhalten muss das Ergebnis noch > durch n geteilt und alles bis auf den DC Anteil (da dort sozusagen 2 > bins drauf fallen) mit 2 multipliziert werden. Das bedeutet, ich muss mein Ergebnis durch 256 teilen (inkl. DC Anteil) und alles außer dem DC Anteil verdoppeln? Ich habe die CMSIS-FFT-Variante mit der Q1.15 Notation gewählt, d.h. im Endeffekt ist die Ausgabe zwischen 0 und 1-(1/2^15). Ich muss dann schauen, wie ich das auf Q1.15 abbilde. Wenn das auf die CMSIS Implementation ebenfalls zutrifft, dann ist die Doku dazu aber verbesserungsfähig - aus dem Stehgreif müsste ich erstmal sagen, dass es nirgends beschrieben steht, dass das nötig ist, prüf ich aber nochmal nach. Das heisst im Endeffekt, dass a) ich von falschen Werten ausgegangen bin und b) die im Beitrag Beitrag "Re: FFT richtig verstanden bzw richtig auswerten?" verlinkte Seite die FFT eigentlich falsch beschreibt, korrekt? Ralf
Hm, wieso? Die rechnen Samplerate durch Anzahl an Samples, das ist dasselbe wie 1/Aufnahmedauer.
Hi Sven, hmmm... Ich kann's nicht bestreiten, du hast recht - Asche auf mein Haupt. Muss mir das morgen nochmal in Ruhe anschauen. Wirfst auch bitte nochmal n Blick drauf, du warst zuerst auch der Meinung dass die Kanalbreite 1Hz ist - nicht dass wir jetzt beide falsch abbiegen. Dann muss ich noch herausfinden warum die FFT den höchsten Peak im fünften Kanal hat - das wären dann ja 16Hz für das 9Hz-Signal. Wenn ich es grad richtig im Sinn hab sollte die FFT nur reelle Werte ausgeben, der Peak müsste demnach im dritten Kanal zu erwarten sein. Ralf
Ralf schrieb: > Wirfst auch bitte > nochmal n Blick drauf, du warst zuerst auch der Meinung dass die > Kanalbreite 1Hz ist - nicht dass wir jetzt beide falsch abbiegen. Sorry, das war einfach dumm von mir. Ich hab' einfach Unsinn gerechnet, frag mich nicht wie ich darauf kam damals. 1/Aufnahmedauer ist schon der korrekte Wert für die Kanalbreite, da bin ich mir absolut sicher, und das ist bei dir 4 Hz.
Hi Sven, > Sorry, das war einfach dumm von mir. Ich hab' einfach Unsinn gerechnet, > frag mich nicht wie ich darauf kam damals. Ist ja nicht schlimm, wir kommen ja vorwärts =) > 1/Aufnahmedauer ist schon der korrekte Wert für die Kanalbreite, da bin > ich mir absolut sicher, und das ist bei dir 4 Hz. Okay, das heisst, für 1Hz Auflösung müsste ich die Anzahl der Samples und die FFT-Größe auf 1024 erhöhen. Ich halte mal fest: Mit den aktuellen Werten habe ich also 4Hz, wobei ich bis 500Hz erfassen kann, weil bei rein reellen Eingangswerten die FFT-Ausgabe in der oberen Hälfte gespiegelt ist. Das heisst, dass ich noch rausfinden muss, warum der höchste Peak im "doppelten" Kanal landet (Kanal 4 anstatt Kanal 2) und dass ich wohl die ausgegebenen Werte noch multiplizieren muss, um die Amplituden korrekt darzustellen. Ralf
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.