Forum: Mikrocontroller und Digitale Elektronik FFT richtig verstanden bzw richtig auswerten?


von Ralf (Gast)


Lesenswert?

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

von Jim M. (turboj)


Lesenswert?

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
von Sven B. (scummos)


Lesenswert?

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

von Nix OT (Gast)


Lesenswert?

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.

von Ralf (Gast)


Lesenswert?

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

von Sven B. (scummos)


Lesenswert?

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.

von Ralf (Gast)


Lesenswert?

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

von Sven B. (scummos)


Lesenswert?

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

von Sven B. (scummos)


Lesenswert?

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

von Ralf (Gast)


Angehängte Dateien:

Lesenswert?

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

von Sven B. (scummos)


Lesenswert?

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.

von Sven B. (scummos)


Lesenswert?

Außerdem würde ich dringend raten eine Windowing-Funktion (Hamming oder 
so) zu verwenden, der Peak ist wirklich sehr breit ;)

von Ralf (Gast)


Lesenswert?

Ö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

von Sven B. (scummos)


Lesenswert?

Hups, hast natürlich recht, ich bin wohl blind.

Hast du die Daten als CSV oder so, so ist das schwer zu sagen.

von Ralf (Gast)


Angehängte Dateien:

Lesenswert?

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

von Ralf (Gast)


Lesenswert?

PS: Die Werte sind bereits in Dezimal gewandelt, sorry.

Ralf

von Sven B. (scummos)


Angehängte Dateien:

Lesenswert?

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

von Ralf (Gast)


Lesenswert?

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

von Ralf (Gast)


Lesenswert?

Ergänzung:
> ...die ich mit numpy.fft.rfft gerechnet habe...
Kann es an der RFFT liegen? Ich verwende eine CFFT.

Ralf

von Sven B. (scummos)


Lesenswert?

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

von Ralf (Gast)


Lesenswert?

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

von S. Landolt (Gast)


Lesenswert?

Ich versteh's auch nicht, ich dachte, die Kanalbreite sei 
Abtastfrequenz/FFT_N, im vorliegenden Fall also 1 kHz/256 = 3.9 Hz.

von Sven B. (scummos)


Lesenswert?

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.

von Jan K. (jan_k)


Lesenswert?

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
von Sven B. (scummos)


Lesenswert?

Zeropadding erhöht nicht wirklich die Frequenzauflösung. Das macht nur 
die Bins schmaler und verschmiert den Peak ...

von Ralf (Gast)


Lesenswert?

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

von Sven B. (scummos)


Lesenswert?

Hm, wieso? Die rechnen Samplerate durch Anzahl an Samples, das ist 
dasselbe wie 1/Aufnahmedauer.

von Ralf (Gast)


Lesenswert?

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

von Sven B. (scummos)


Lesenswert?

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.

von Ralf (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.