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.
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
Ö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
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
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
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.
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
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