Hallo, ich habe da mal eine kleine Frage. Ich habe ein Mikro an meinem Atmega 8 angeschlossen, weil ich das Frequenzspektrum zu einem Geräusch feststellen möchte, mittels einer FFT. Den Quellcode in C (im Anhang) habe ich bereits gefunden und auch schon in den µc gebrannt. Ich nehme nun ein Feld mit [128] Werten (Realteil) auf und fülle das Imaginärfeld komplett mit Nullen. Mit diesen Werten lasse ich denn die FFT durchführen. Anschließend lasse ich mir das Real-Feld wieder ausgeben und es stehen auch Werte drin, aber jetzt meine Frage, weiß jemand wie diese Werte zu interprtieren sind? Ich wäre für eure Hilfe und Antwort sehr dankbar!
Es kommt darauf an was du genau wissen willst von dem Signal. Allgemein brauchst du aber erst mal den real und imaginär Teil. Interessiert dich der Frequenzgang, dann kannst du den Absolutwert nehmen, also
. Damit bekommst du ein Bild über die Amplitude der einzelnen Frequenzkomponenten, aber die Phasenbeziehung geht verloren.
x(t) ist reel, insofern ist es ok mit den Imagenärteil mit Nullen aufzufüllen. Nach FFT hast X(f). Über welche Eigenschaften X(f) verfügt kann man nichts aussagen. Das könnte man, wenn man über weitere Eigenschaften von x(t) verfügen würde. Wie zB x(t)=x(-t) usw. Das ist eher theoretisch und wahrscheinlich hat dein x(t) Signal keine Symmetrien. Deswegen muss man X(f) im allgemeinen als komplexwertig ansehen, ausser vielleicht X(0). X(0) ist Gleichanteil deines Zeitsignals und ist auch reelwertig (das erkennt man wenn man in Fouriertransformation f=0 direkt einsetzt) |X(f)| gibt dir den Überblick über die enthaltenen Frequenzen. Ist |X(f')| = 0, dann ist f' nicht im Signal enthalten. Vielleicht kannst du über uart die Werte übergeben und auf PC darstellen. Cool wäre auch Signalquellen mit bekannter Frequenz aufzuzeichen um das ganze am Ende zu überprüfen. Gruss, Daniel
Erst einmal vielen Dank für eure schnelle und gute Hilfe! ich habe mir das reelle Feld (die 128 Werte) vorhin auch schon mal auf einem Display nach der FFT wieder ausgeben lassen, es stehen dort positive und negative Werte drin, sind dies denn die Amplituden der jeweiligen Frequenzkomponenten? Wenn ja, woher weiß ich zu welchen Frequenzen die jeweiligen Amplituden gehören, wenn z.B. der erste Wert des Feldes 10dB ist, zu welcher Frequenz gehört diese Amplitude? Wenn ich die Werte im Imag-Feld "Null" setze vor der FFT, habe ich denn später meine Amplituden direkt im Real-Feld?
>ich habe mir das reelle Feld (die 128 Werte) vorhin auch schon mal auf >einem Display nach der FFT wieder ausgeben lassen, es stehen dort >positive und negative Werte drin, sind dies denn die Amplituden der >jeweiligen Frequenzkomponenten? Die Amplitude erhälst du wenn du rechnest (pseudocode):
1 | for i loop over N: |
2 | amplitude[i] = sqrt(real[i]^2 + imag[i]^2); |
Drucke das mal aus. >Wenn ja, woher weiß ich zu welchen >Frequenzen die jeweiligen Amplituden gehören, wenn z.B. der erste Wert >des Feldes 10dB ist, zu welcher Frequenz gehört diese Amplitude? Der Index im FFT Ergebnis hängt mit der Abtastfrequenz zusammen. Mit einer Abtastrate von Fs representiert jeder Wert im FFT Ergebnis eine Bandbreite von Fs/N. Also der Index 0 representiert den Gleichstromanteil, Index 1 von 0 bis Fs/N, Index 2 von Fs/N bis 2 * Fs/N usw. Jetzt ist es so, dass wenn ein Signal mit Fs abgetastet wird, dann ist die maximale Frequenz Fs/2, die mit den Samples representiert werden kann. D.h. nur die ersten N/2 Indizes im FFT Ergebnis sind eindeutig. Nach N/2+1 wiederholt sich das Spektrum spiegelverkehrt. Das solltest du sehen wenn du die Werte ausdruckst. >Wenn ich die Werte im Imag-Feld "Null" setze vor der FFT, habe ich denn >später meine Amplituden direkt im Real-Feld? Nein, siehe oben, du benötigst Real und Imaginär Daten und musst die Amplitude daraus erst errechen.
Hallo Alban, vielen Dank für deine Hilfe, du hast mir sehr geholfen! Dankeschön!
Hallo, ich habe nun ein Grafikdisplay am µC angeschlossen, um das Spektrum darstellen zu können. Leider sind die dort dargestllten Amplituden zu den jeweiligen Frequenzen überhaupt nicht konstant. Man merkt zwar, dass wenn man den Geräuschpegel anhebt, auch die Amplituden der Frequenzanteile größer werden, aber diese schwanken sehr stark. Ich habe auch bereits mit einem Tongenerator verschiedene Sinusfrequenzen dasrstellen lassen, aber auch in diesem Fall erhöhen sich sehr viele Frequenzanteile, und nicht nur ein bestimmter. Ich übergebe der FFT Funktion das Real Array mit den vom ADC Wandler gemessenen Werten und multipliziere diese denn mit 32,also mit maximal 32768 (1024 * 32) und das Imag Array fülle ich wie oben schon mal beschrieben mit Nullen. Liegt der Fehler vielleicht in der Übergabe des Real Feldes? Ich taste das Analogsignal mit 5 kHz ab. Hat schon mal jemand die von mir benutzte FFT erfolgreich auf einem µC getestet? Wenn mir noch mal jemand bei meinem Problem helfen könnte wäre ich sehr dankbar, schon einmal vielen Dank im voraus!
Hi, im Kommentar steht " For the forward FFT (time -> freq), fixed scaling is performed to prevent arithmetic overflow, and to map a 0dB sine/cosine wave (i.e. amplitude = 32767) to two -6dB freq coefficients; the one in the lower half is reported as 0dB by fix_loud(). The return value is always 0. " ich nehme an dein AD Wandler löst zu 10bit auf. Dann multiplizierst Du mit 32 mit dem Gedanken die fixpoint Range von -1.0 bis 1.0 auszufüllen. Allerdings bin ich mir nicht sicher, dass es nötig ist. Wie es im Kommentar steht, muss fix_fft Funktion sicher gehen, dass das Ergebnis wieder in range -1.0 bis 1.0 passt. Rein theoretisch sollte es für deine Zwecke egal sein, da Fouriertransformation linear ist. Also es gilt immer x(t) o-o X(f) a*x(t) o-o a*X(f) Man verändert theoretisch nur die Signalenergie. Die wird dann um den Faktor a^2 grösser als ursprunglich. Was mir noch in den Kopf gekommen ist ... Du tastest mit 5kHz, das heisst im Klartext, dass deine Signalquelle keine Signalanteile mit Frequenzen über 2.5kHz enthalten darf. Wenn sie es doch tut (zb Du sprichst in mikro), dann werden Signalanteile mit Frequenz grösser 2.5kHz sich für "falsche Frequenzen" ausgeben. Zb würde sich eine im Signal vorhandene Schwingung mit f0=5kHz für die Frequenz 0 ausgeben. Ergo wäre damit X(0) nicht mehr eindeutig. Und das weil die 5kHz Abtastung immer auf gleiche Phasenlage der 5kHZ Schwingung trifft. Diesen Effekt nennt man Aliasing. Um es loszuwerden am besten Tiefpass einbauen, der alle Anteile über 2.5kHz unterdrückt. Dann wirkt sich Aliasing nicht mehr so stark aus. Ich hab mal eine gute Anschauung für Aliasing im Netz gelesen. Man stelle sich ein Rad, dass 30 mal in der Sekunde sich dreht. Das ganze wird mit einer Kamera aufgezeichnet, die 30 Bilder in der Sekunde macht. Das Rad "steht" dann. Man kann nicht unterscheiden ob das Rad wirkllich steht oder sich mit 30,60,90... Umdrehungen pro Minute dreht. Genauso 1 und 31 Umdrehungen. Hier wird halt <die Welt> mit der Frequenz 30Hz abgetastet. Kannst du eventuell Foto oder kleines Video uploaden? Es würde mich interessieren wie das ganze dann aussieht. Gruss, Daniel
Hallo, ich habe jetzt mal ein kleines Video von der FFT Ausgabe auf dem Display gedreht bei einer am Tongenerator eingestellten Frequenz von 500Hz. Man kann gut erkennen dass die FFT wohl noch nicht richtig funktioniert. Es erhöhen sich zwar die Amplituden verschiedener Frequenzen wenn man einen Ton erzeugt, aber diese Amplituden sind total willkürlich und haben nichts mit der vom Tongenerator erzeugten Frequenz zu tun. Es ist auch egal welche Frequenz ich erzeuge, die auf dem Display dargestellten Frequenzen sehen immer sehr ähnlich aus wie in dem Video. Einen Tiefpass habe ich auch schon in der Schaltung eingebaut, er schneidet mir alle Frequenzen über 2,5 kHz weg, da die Frequenzen die ich aufnehmen möchte um einiges kleiner sind. Hat jemand vielleicht eine Idee was ich falsch machen könnte? Wenn ich die FFT mit einem Array füttere das ich selber mit Nullen gefüllt habe scheint die FFT korrekt zu funktionieren, sie zeigt zumindest keine Frequenzanteile an. Ich habe das Array auch schon mal mit einem konstanten Wert beschrieben, denn zeigte mit das Display nur einen Gleichanteil an, dies ist ja ebenfalls korrekt?! Hat jemand vielleicht eine Idee?
Das mit dem Hochladen vom Video hat wohl leider nicht funktioniert, aber wenn es jemand haben möchte kann er mir gerne seine emailadresse geben, denn schicke ich es per mail
meine addy ist ed.xmgATleinaday AT = @ und rückwärts geschrieben (wegen spambekämpfung) ich würde mir das Video gerne anschauen >Wenn ich die FFT mit einem Array füttere das ich selber mit Nullen >gefüllt habe scheint die FFT korrekt zu funktionieren, sie zeigt >zumindest keine Frequenzanteile an. Ich habe das Array auch schon mal >mit einem konstanten Wert beschrieben, denn zeigte mit das Display nur >einen Gleichanteil an, dies ist ja ebenfalls korrekt?! Richtig. Wenn beide real/imag Arrays mit Nullen gefüllt sind, dann sollte nichts angezeigt werden. Wenn real Array nur mit einem konstanten Wert gefüllt ist, dann müsste nur der Gleichanteil angezeigt werden. >Hat jemand vielleicht eine Idee? das mit Tiefpass hat sich erledigt. Interessenhalber wie hast du ihn implementiert? Bleiben dann meiner Meinung nach die fixpoint Zahlen und der Algorithmus selber. Den Algorithmus könnte man auf dem PC testen. Ich probiere das mal heute Abend. Achso was ich komplett vergessen habe :) Vielleicht ist das der Leckeffekt. Wenn man die Abtastfrequenz konstant hält und diese auch Nyquesttheorem erfüllt, dann bekommt man für ein Zeitsignal von 1 Minute in deinem Fall 5000 Samples. Wenn man diese auf einmal der FFT unterzieht, dann ergibt sich was anderes als wenn man 128 Samples stückchenweise der FFT unterzieht. N ist dann wie eine Fensterfunktion die durch 1 Minute Zeitsignal geschoben wird. 128/5e3 => 0.0256 0.0256 Sekunden Fenster sozusagen. Hmm, mein Buch sagt auflösungsFrequenz = 1/Beobachtzeit = 39.0625 Hz Wieviel Balken hat dein Display für die Darstellung der Frequenzklassen? Aber alles in allem 39 ist "fein" genüg. Wenn es 10 Balken sind, für Frequenzen 0 bis 500 dann dürften im worst case nur 2 von denen sich erheben. f_auflösung = 1/Beobachtzeit = f_abtast/N N grösser machen oder fabtast kleiner sollte f_auflösung feiner machen. Aber je feiner desto mehr Balken sollte Display bieten. Das ist im Moment alles was mir einfällt. Gruss, Daniel
Hallo, ich wollte mal fragen ob vielleicht jemand einen FFT Code hat den er selber schon erfolgreich getestet hat und mir empfehlen kann? Ich würde mich sehr über eine Antwort freuen.
> Wenn ich die FFT mit einem Array füttere das ich selber mit Nullen > gefüllt habe scheint die FFT korrekt zu funktionieren, sie zeigt > zumindest keine Frequenzanteile an. Ich habe das Array auch schon mal > mit einem konstanten Wert beschrieben, denn zeigte mit das Display nur > einen Gleichanteil an, dies ist ja ebenfalls korrekt?! > Hat jemand vielleicht eine Idee? Versuche doch mal das Array mit einer Wechselgröße zu belegen. Also fülle z.B. 1/4 mit dem Wert 5000, das nächste 1/4 mit -5000, dann wieder mit 5000, etc. Dann solltest du erst mal eine stehendes Bild auf deinem Display erhalten. Eine gute Sache währe auch mal den Code einfach auf dem PC zum laufen zu bringen, da du dann mehr Zugriffsmöglichkeiten hast. Auf jeden Fall solltest du kontrollieren wie groß deine Daten sind die in die FFT rein gehen. Wenn ich den Code richtig verstehe, dann müssen die im Bereich -32768...32767 sein. Kannst du vielleicht die Daten die in die FFT rein sollen mal auf dem Display ausgeben? Dass sollte dir zeigen ob das Signal überhaupt einen Sinn macht oder ob am FFT Eingang schon nur rauschen anliegt.
Ich habe mir den Code mal genauer angeschaut und meines Erarchtens ist das Problem die Skalierung die in jedem Rank durchgeführt wird um einen Überlauf zu vermeiden. Für kleinere Signale kann das ein Problem sein und sie werden praktisch weg skaliert, so das am Ausgang nur noch Rauschen ankommt. Da die Skalierung in der FFT fest ist und in jedem Rank durchgeführt wird, musst du also sicher stellen das dein Eingangssignal genug groß ist damit es nicht weg skaliert wird. Vielleicht würde es Sinn machen eine automatische Verstärkungskontrolle der FFT vor zu schalten. Also du misst die Energie von den letzten N Samples und passt dann jeden Sample der in die FFT geht entsprechend dem Wert an.
Hallo Kluntje, wenn Du Signale abtastest, deren Periode(n) nicht genau in Deinen Samplebuffer passen, bekommst Du immer Artefakte durch das Abschneiden des Signals. Um das zu umgehen, kann man das Signal mit einer "Windowing" Funktion multiplizieren. Sie dämpft Deine Samples am Anfang und am Ende etwas, so daß der Einfluß dieser Samples auf das Ergebnis geringer ist. Typische Windowing-Funktionen sind Hamming und Hanning. Ich probiere gerade die FFT von elm-chan aus (http://elm-chan.org/works/akilcd/report_e.html) und bin recht begeistert ob der Geschwindigkeit. Dort ist diese Windowing-Funktion bereits eingebaut, und Du solltest schnell zum Ziel kommen. Gruss Hans-Christian
Hallo, und noch mal vielen Dank für eure Hilfe! Ich habe jetzt auch den FFT Code von ELM-CHAN in meinem µC gebrannt, es funktioniert wirklich hervorragend! Viele Grüße Kluntje
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.