Hallo, ich beschäftige mich gerade mit der FFT-Implementierung auf einem ARM Cortex-M3. Dazu verwende ich die CMSIS-DSP Bibliothek und habe mich für die Festkomma-Implementierung entschieden (konkret das Q15-Format). Über einen 10-Bit-ADC lese ich ein Sinussignal ein. Das Ergebnis wird um fünf Stellen nach links geschoben, damit möchte ich erreichen, dass der Maximalwert des ADC dem Maximalwert des Q15-Formats entspricht (ist nicht ganz korrekt, weil Nullen nachgeschoben werden, aber zumindest nah dran). Die Implementierung an sich läuft soweit, ich bekomme plausible Ergebnisse (soweit ich das beurteilen kann). Ich will das ganze auch noch separat nachrechnen, damit ich das komplett nachvollziehen kann. Umgekehrt interessiert mich aber, ob ein FFT-Bin des Ergebnisses überhaupt den Maximalwert des Festkomma-Datentyps erreichen kann. Beim DC-Anteil (Bin 0) ist das m.E. der Fall, wenn eben der ADC permanent am Anschlag ist, aber wie schaut das bei den die Frequenzen angebenden Bins aus? Kann man denn aus dem Maximalwert bzw. der maximalen Skala der Eingangssignale den resultierenden Maximalwert der FFT-Ausgabe berechnen? Das wäre z.B. nützlich, wenn man das ganze grafisch auf einem Display darstellen möchte, damit man das obere Ende kennt und passend "zoomen" kann. Ralf
Nachtrag: Ich hab das grad mal durchgerechnet, anhand einer kleinen FFT mit 8 Eingangswerten, jeweils 1+0i. Ich komme im ersten Bin auf 8, alle anderen 0. Was heißt das nun bezogen auf einen Festkomma-Datentyp? Im Q15-Format kann man 8 ja nicht darstellen. Heisst das, dass ich das Ergebnis eigentlich noch durch 8 ( = Anzahl der Samples) teilen muss? Im Q15-Format also um drei Stellen nach links schieben? Ralf
>>>dass der Maximalwert des ADC dem Maximalwert des Q15-Formats entspricht
Ja, dann bekommst Du einen overflow, wie Du mit deinem 1+0*i Beispiel
auch gesehen hast. Eine FFT der Länge 2^n hat n 'stages' und von stage
zu stage gewinnst Du ein Bit hinzu. Bei Q15 hast Du 15Bit Dynamik, ne
1024er FFT macht Dir 9 Bit (oder 10 hm?) hinzu, Du darfst also maximal
mit 6Bit ADC Werten reingehen. In jeder stage machst du auch die cos/sin
Multiplikationen, das ist bei der nötigen Rechendynamik ebenfalls zu
berücksichtigen.
Das ganze ist auch signalabhängig: Dein reiner 'DC' versammelt sich
natürlich im ersten bin, ein reiner Sinus in einem einzigen bin.
Breitbandiges Rauschen verteilt sich auf alle bins, da hat mein keine
'peaks' im Frequenzbereich und kommt nicht so nahe an die Grezen des
Zahlenbereichs.
Wie die von Dir benutzte 'Bibliothek' das macht weiss ich nicht. Es gibt
auch Implementationen, die kucken in jeder stage ob sie an der
Aussteuerungsgrenze sind und renormalisieren.
Pi mal Daumen: m Bit ADC, 2^n Bit FFT Länge
Bitbreite =m+n+2 Sicherheitsbit, Vorzeichen ist ggf auch noch ein Bit.
Beim Rechnen der Sin/Cos auch nicht allzu viel stutzen: 15Bit*15Bit plus
Summe sind 31Bit, die möglichst wenig abschneiden, also nicht wieder
auch 15 Bit runternormieren, sonst Rauscht die Geschichte.
Cheers
Detlef
Hi Detlef, >> dass der Maximalwert des ADC dem Maximalwert des Q15-Formats >> entspricht > Ja, dann bekommst Du einen overflow, wie Du mit deinem 1+0*i Beispiel > auch gesehen hast. Eine FFT der Länge 2^n hat n 'stages' und von stage > zu stage gewinnst Du ein Bit hinzu. Bei Q15 hast Du 15Bit Dynamik, ne > 1024er FFT macht Dir 9 Bit (oder 10 hm?) hinzu, Du darfst also maximal > mit 6Bit ADC Werten reingehen. In jeder stage machst du auch die cos/sin > Multiplikationen, das ist bei der nötigen Rechendynamik ebenfalls zu > berücksichtigen. Okay, ich verwende eine 256er FFT, also könnte ich auch auf Q31 gehen. Das heisst aber dann, dass ich das Eingangssignal nicht schieben sollte. Wie sorgt man dann dafür, dass das ganze "gescheit" auf einem Display angezeigt werden kann? Den Bin mit dem höchsten Wert ermitteln und darauf zoomen? Aktuell mach ich das so, dass ich den Maximalwert auf den Displaybereich, den ich vorgesehen habe umrechne. Nur erreichen die Bins dann gerade mal etwa 20% Ausschlag (Testsignal Sinus, Offset 0.5, Amplitude 0.5). Deswegen auch die Frage, unter welchen Bedingungen denn eigentlich der Maximalwert erreicht wird. > Das ganze ist auch signalabhängig: Dein reiner 'DC' versammelt sich > natürlich im ersten bin, ein reiner Sinus in einem einzigen bin. > Breitbandiges Rauschen verteilt sich auf alle bins, da hat mein keine > 'peaks' im Frequenzbereich und kommt nicht so nahe an die Grezen des > Zahlenbereichs. > > Wie die von Dir benutzte 'Bibliothek' das macht weiss ich nicht. Es gibt > auch Implementationen, die kucken in jeder stage ob sie an der > Aussteuerungsgrenze sind und renormalisieren. > > Pi mal Daumen: m Bit ADC, 2^n Bit FFT Länge > > Bitbreite =m+n+2 Sicherheitsbit, Vorzeichen ist ggf auch noch ein Bit. > > Beim Rechnen der Sin/Cos auch nicht allzu viel stutzen: 15Bit*15Bit plus > Summe sind 31Bit, die möglichst wenig abschneiden, also nicht wieder > auch 15 Bit runternormieren, sonst Rauscht die Geschichte. Die Sin/Cos Werte werden auch von der Lib zur Verfügung gestellt. Ich vermute mal, dass Sättigung da durchaus beachtet und korrigiert wird. Ralf
Hi,
10Bit ADC, 256er FFT sind 18+x Bit, da passt dann Q31.
>>>
Deswegen auch die Frage, unter welchen Bedingungen denn eigentlich der
Maximalwert erreicht wird.
<<<<
Wenn sich alles in einem bin versammelt, also bei einem Sinus der
richtigen Frequenz.
Anzeige: Muss Du entscheiden, entweder feste Skalierung und schlechte
Aussteuerung oder variable Skalierung und immer bis zum Anschlag
ausgesteuert. Das ist Geschmacksfrage.
Wird schon.
Cheers
Detlef
Hi Detlef, > 10Bit ADC, 256er FFT sind 18+x Bit, da passt dann Q31. Danke erstmal für die Erläuterung ganz oben, das war mir erst gar nicht richtig bewusst, dass sich das pro Stufe aufaddiert. >> Deswegen auch die Frage, unter welchen Bedingungen denn eigentlich der >> Maximalwert erreicht wird. > Wenn sich alles in einem bin versammelt, also bei einem Sinus der > richtigen Frequenz. Ich glaub ich hab die Frage falsch formuliert: das o.g. ist klar, die Frequenz mit der höchsten Amplitude ergibt den höchsten Wert für einen Bin. Meine Frage bezog sich darauf, wann der Maximalwert des Datentyps (also Q15 bzw Q31) erreicht wird bzw ob das überhaupt geht. Das mit dem Schieben muss ich nochmal schauen, wie dann bei meiner aktuell festen Skalierung das Ergebnis aussieht. Wenn es dann immer noch "nix" ist, dann werd ich vielleicht doch auf variable Skalierung gehen. Muss ich bzgl der Schieberei noch etwas beachten -> dass ich mit rein reellen Werten in die FFT gehe, spielt ja keine Rolle, oder? Nicht dass dann auch noch Auswirkungen hat. > Anzeige: Muss Du entscheiden, entweder feste Skalierung und schlechte > Aussteuerung oder variable Skalierung und immer bis zum Anschlag > ausgesteuert. Das ist Geschmacksfrage. Ja, ich glaub dazwischen gibt's nix =) > Wird schon. Japp, vielen Dank für die bisherige Hilfe. Ralf
Hi, ich habe mal in meinen Archiven gestöbert und angehängten Code zu einer 16 Bit integer-FFT gefunden, Zwischenergebnisse in 32 Bit. Die FFT-Längen von 2^5 - 2^10 sind abgedeckt. Die FFT macht die oben erwähnte dynamische Skalierung: Drht Overflow wird renormiert. Das ist kein Hexenwerk, statt mich mit den Tücken von 'Bibliotheken' zu befassen programmier ich sowas lieber selber, das steht in jedem halbwegs fitten Lehrbuch. Cheers Detlef
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.