Hey, ich hab gestern eine FFT 256 auf nem Atmega32 Implementiert. Diese funktioniert auch gut. Ich möchte nur 6 Frequenzen so genau wie möglich bestimmen (+-0,5Hz). Ginge das irgendwie mit einer FFT 256 ?(Bei dem erforderlichen Frequenzspektrum habe ich eine ungefähre Bandbreite von nur 3,125Hz ) Kann ich vielleicht mehrere hintereinander laufen lassen oder so? Gibt es da allgemein noch irgendwelche Algorithmen? Gruß, Rasmus
Anregung/Fragen: Treten die 6 Freq. gleichzeitig auf ? Wieviel Zeit darf vergehen, bis die Frequenz angezeigt wird ? Man könnte auch eine Demodulation machen, mit der der Bandbereich auf: 0-3,125 Hz transferiert wird. Nun möchte man nur noch 6 Bereiche haben => wenige FFT-Stützstelle. (Falls die Bandbreite konstant im Freq.bereich liegt: fu = konstant, fo = konst.) Gruß c.
Nochmals : Du hast 6 moegliche Frequenzen innerhalb von 3.125Hz Bandbreite und die moechtest du auf ein halbes Hz genau bestimmen ? Das Halbe Hz gibt die minimale Messzeit von 2 Sekunden vor. Bei welcher Frequenz sind den die Frequenzen? Eigentlich wuerden 6 punkte genuegen, da es 6 halbe Hz innerhalb von 3Hz gibt. Da koennte man allenfalls etwas abkuerzen.
Ja die 6 Frequenzen treten Gleichzeitig auf und liegen so zwischen 50 und 400Hz. Ich habe nun mit der FFT die ungefähren Werte bestimmt. Wie läuft das dann weiter ab? Ich weiß zb. das eine bei ungefähr 61, eine bei 143 und eine bei 344 liegt. Es wäre gut wenn das ganze in unter 2 Sekunden bestimmt werden könnte. Gruß, Rasmus
Also, der Linienabstand bei einer FFT ist 1/Messzeit. Dh fuer 0.5Hz Linienabstandmisst man 2 sekunden. Da ist nichts zu machen. Ein Herr Shannon hat sich mit dieser Trivialitaet unsterbilch gemacht. Wieviele Punkte braucht man nun ? Die hoechste Frequenz ist 400Hz, macht 800 Punkte. Die FFT arbeitet mit 2^N zahlen dh. es wird eine 1024er FFT. Allenfalls sollte man einen anderen Algorithmus anschauen. zB den Goerzel.
Es gibt noch andere Tricks. Man kann die Frequenzen herunterfalten mit Subsampling. Dann wird's aber Muehsam. Zum Einen wird die Messzeit nicht reduzuert, aber man kommt mit kuerzeren Transformationen aus. Allenfalls ist es moeglich eine Sampling Frequenz zu finden, bei der man nur noch 32 oder 64 Punkte oder so braucht.
2 Sekunden wären theoretisch auch noch okay, solange die Frequenz ordentlich bestimmt wurde. Wenn ich also ne FFT 256 rübergelaufen habe. Muss ich danach für jede Frequenz noch 6 mal den Goertzel Algorithmus drüber laufen lassen und hätte dann ein Ergebnis, oder funktioniert das so nicht? Gruß, Rasmus
Nein, man sollte nur eine Messung machen muessen. Nach 1024 Samples waehrend 2 sekunden hat man genuegend Daten. Jetzt muss man nur noch rechnen. Moment. Man brauchr 2 punkte pro Periode. Macht 2048 Samples waehrend 2 sekunden.
Was ich sagen will. Da eine 2048 punkte FFT moeglicherweise zu aufwendig ist, muss man nach einer schnellen 256 punkte subset bestimmung nochmals nachrechnen. Aber immer basierend auf denselben Daten. Die Information steckt ja drin. Dh die Frage ist nun, wie verpulvert man moeglichst effizient die 2 Sekunden der naechsten Samples.
Jo dachte ich auch aber irgendwie funktioniert nur die FFT mit 256 Samples und die anderen nicht. Da ich normalerweise in Bascom arbeite habe ich auch nicht sooo viel Ahnung von ASM und von C auch nur beschränkt. Deswegen dachte ich mir das es jetzt einfacher wäre noch diesen Goertzel Algorithmus zu implementieren (sofern es geht?).Außerdem könnte ich mit dem Goertzel Algorithmus ja noch genauer dann in der Bandbreite von 3,125 nach der richtigen Frequenz suchen, oder?
Sry hab das posting nciht gesehen, Wie sieht so eine Subsetbestimmung aus? Was meinst du damit? Wenn man das alles über ne 256 FFT hinbekommen würde, wäre das natülrich unglaublich :-)! Gruß, Rasmus
Also, ich hab 2048 Samples innerhalb 2 seknunden, dh ca alle 1ms ein sample. Eine 256 sample subset FFT kann man nun machen, indem man nun das 1.Achtel nimmt. Damit erreicht man nur eine genauigkeit von 4Hz pro line. Der vorteil, davon, man kann schon waerend dem Sampeln mit dem Rechnen beginnen. Nach dem 1. Achtel kann man starten.
Okay ich mache also dann 8 FFTs und bin dann sogut wie nach 2 Sekunden fertig. Dann habe ich 8 Frequenzsprektren, aber wie genwinne ich daraus jetzt die Informationen die ich haben will? Gruß, Rasmus
Hallo, falls wirklich nur 6 Frequenzen gefragt sind, ist eine DFT kürzer als eine FFT. z.B. nur Görlitz Gruß Fritz
@Fritz Aber einen FFT Durchlauf muss ich doch mindestens machen um zumindestens ungefähr abzuschätzen in welchem Frequenzbereich die gesuchte Frequenz liegt (dieser 3,125Hz Bereich),oder? Gruß, Rasmus
Hallo, ich war der Meinung, die Frequenz ist bekannt und es muss von 6 genau bestimmten Frequenzen die Amplitude bestimmt werden. Kommen die 6 Frequenzen immer gleichzeitig vor ? Ist das Frequenzverhältnis zueinender immer gleich? Fritz
Weder gleichzeitig noch in einem bestimmten Verhältnis. Rasmus
Also. Die erste FFT eines Achtels bringen eine Aufloesung von 4 Hz. Das wars. Die zu Wiederholen bringt nichts. Nach einem weiteren Achtel, nun einem Viertel, koennte man eine 256er FFT machen, bei der nur jedes Zweite Sample benutzt wird. damit kann man mit einer Aufloesung von 2Hz den halben Frequenzbereich abdecken. Am Ende koennte man auch jesden achten punkt nehmen, das wuerde bei einer 256er FFT 0.5 Hz Aufloesen und einen Achtel Frequenz Abdecken. Man kann auch Subsamples nehmen und mit der Faltung arbeiten
Also vom ersten 1/8, vom ersten 1/4, von der 1/2, und einem vom ganzen. Da bekomme ich 4 mal 128 Werte. Wie muss ich die dann verarbeiten? Gruß,Rasmus
unter diesen Umständen ist (nach meiner Meinung) doch eine FFT günstig. Man kann auch eine kürzere FFT versuchen. z.B. 128 Punkt und Zero-Padding und danach eine Maximumbestimmung der Frequenzwerte. Dadurch kann man die Auflösung erhöhen. 1. Hamming 2. Zero Padding vorne und hinten 3. Power Spektrum 4. Peak Detektor (Polynom 2. Grad mit Fehlerqudratminimum und daraus Maximumbestimmung) Gruß Fritz PS: http://schulen.eduhi.at/htlbraunau/lehrer/ploetz/Labbsp/FeinFFT.vi Realisierung vom oben erwähnten in LabVIEW
Aber das würde doch bedeuten das ich gucke welche Frequenzen sind bei der FFT am stärksten Vertreten, oder? Damit würde ich doch dann bei ner FFT 256 uach nicht mehr als auf 3,125Hz genau bestimmen können (wenn ich das richtig verstehe). Gruß, Rasmus
Ein Signal mit einer reinen Sinus-Schwinung gibt durch Zero-padding und Fensterfunktion mehrere Spektrallinien in in "Gauß-Glockenform". Das Maximum dieser Verteilung muss nicht mit den Spektren übereinstimmen. Dadurch kann eine Feinauflösung der Frequenz realisiert werden. Fritz
Ich muss zugeben das ich von den Texten bei Wikipedia zu der Fensterfunktion und Zero-padding nicht viel verstehen (bin noch in der Schule). Da ich auch verstehen möchte was ich benutze würde es mich interessieren wie genau diese Methode von DSP Funktioniert, da hier nur die FFT verwendet wird. Gibt es dazu irgendwelche Erklärunegn? Gruß, Rasmus
Zero Padding: Falls 1000 Abtastpunkt mit 1 ms vorhanden sind, gibt es eine Aufnahmezeit von 1 sec. Daraus ergibt sich eine Frequenzauflösung (Abstand der Spektrallinien) von 1 Hz. Falls den 1000 Messpunkten noch 3000 mal der Wert 0 angehängt wird, kann eine Frequenzauflösung von 0,25 Hz erreicht werden. Fensterfunktion: Falls das abgetastete Signal nicht genau nach einer Periode aus dem kontinuierlichen Signal herausgeschnitten ist, sondern z.B. 3,5 Schwingungen enstehen Spektrallinien bei 3 und 4 aber auch bei 2 und 5. Diese Nebenfrequenzen kann man mit einer Fensterfunktion vermindern. Gruß Fritz
Aber wenn ich jetzt zb ne FFT 256 verwende, der 64 Werte übergebe und danach noch 192 Nullen übergeben, Ist das nicht ein bisschen ungenau? Also reichen 64 Werte aus um eine Signal so genau zu bestimmen. Es treten ja auch noch andere ungewollte Frequenzen auf.(Es geht darum bei einer Gitarre alle 6 leeren Saiten zu bestimmen,wobei alle Saiten gleichzeitig angeschlagen werden). Gruß, Rasmus
Hallo robotxy, ich bezeichne jetzt das Verfahren 64 Messwerte + Hammingfenster + Zeropadding mit 196 "0 er" + FFT + Maximumsuche in der Folge als "Methode 2". (wegen kürzerer Schreibweise. Es sind dabei folgende Eigenschaften zu erwarten. Vorteile von Methode 2 gegenüber einer 256 Punkt FFT 1. kürzere Rechenzeit 2. weniger Speicherbedarf 3. es wird die Frequenz aus weniger Daten gewonnen. Dadurch kann das Spektrum rascher erneuert werden. Das ist bei einer laufebnden Analyse von Musik oder Sprachsignalen besser, da das Spektrum zeitlich genauer zugeornet werden kann Nachteil von Methode 2 gegenüber einer 256 Punkt FFT 1. Komplizierter zu programmieren, da Maximumsuche über Polynom zweiten Grades erforderlich. 2. Falls z.B. Obertöne einer Gitarrensaite mit den Grundschwingungen einer anderen Saite übereinstimmen, entstehen relativ leicht Fehler. (Die zu analysierenden Frequenzen sollen einen bestimmten Abstand in der Frequenz haben.) Die Frequenzauflösung dürften etwa (je nach Signal) gleich sein. Bei reinem Sinus ist Methode 2 besser. ------------------ Noch eine andere Frage: Warum machst Du nicht die Datenerfassung im uC und die Analyse im PC ? Gruß Fritz
Die ganze Anwendung soll Portabel sein. Ich werde mich mal über das Wochenende dransetzen das ganze zu verstehen und mich Sonntag abend mal melden. Vielen Dank bis hierhin!! Gruß, Rasmus
Achja ich rechne nicht mit einem reinen Sinus, ist das sehr schlimm?
Anmerkungen: Wie wäre es mit Filtern, zB 7 Bandpässe 50-100 Hz 100-150 Hz ... Jeder ist 50 Hz "breit" (oder 14 Bandpässe) Schauen, ob am Ausgang ein Signal anliegt: dieses dann per FFT analysieren. Oh: Sinnvoll wäre jeweils eine Bandbreite von zB 64 Hz - wegen FFT (siehe oben Zeitdauer - Auflösung) Zu beachten: Bandpässe haben eine Laufzeit. Wenn nur eine Frequenz einen Bandpaß passiert, dann braucht es keine FFT mehr: hier reicht dann eine Bestimmung des Sinusverlaufs. Korrelation - Anforderungen am uC = ? oder: Nulldurchgang, dann 2 Meßwerte "später aufnehmen" und in Sinustabelle sin(phi)/Phase bestimmen => Frequenz. Oder bis zum Maximalwert warten/messen, dann hat man 90 Grad (oder bis zum 2. Nulldurchgang). Bei 2 Sinuskurven geht das auch - aber dann wird es für den uC ggf. zu umfangreich: Amplituden, Störsignale, .... Fensterfunktionen erzeugen (können) übrigens einen Latenzaun im Spektrum. Hier wären die Pegel relevant, wenn ein Nutzsignal einen kleinen Pegel hat => geht ggf. "unter". Gruss c. p.s.: fft ist dann sehr gut, wenn die Signal genau in das Abtastzeitfenster reinpassen. Ansonsten wird interpoliert => Latenzaun Eine DFT mit 200 Samples kann also besser sein als eine FFT mit 256, zB: 1 Sample je msec, 200 Sample = 200 msec Fenster: 5 Hz wird optimal "erkannt", aber auch 10, 15, 20, .... nicht aber 7 Hz.
Es geht um Spektralschätzung, da eine einfache FFT nicht das Mittel der Wahl. Man wird hier zwischen dem richtigen Ergebnis bis hin zu absolutem Müll alles messen können. Und wenn man nur eine einzige Periode des Signals abtastet, dann kommt man sehr leicht in den Bereich Müll. Also nicht wenn man genau eine Periode abtastet, das sieht gut aus. Aber probierts mal mit 1,5 Perioden eines Signals und macht dann ne FFT drüber. Man sollte schon min. 5 Perioden abtasten, je mehr desto geringer der systematische Fehler. Bessere Verfahren zur Spektralschätzung sind das WOSA (weighted overlapped segment averaging) und das STUSE (short-time unbiased spectrum estimation) Verfahren. Sind aber auch noch wesentlcih komplizierter zu verstehen und zu implementieren.
Das Problem ist nicht so die Laufzeit sondern eher die Genauigkeit. Und mit einer 256 FFT haben die Filter ja nur eine Breite von 3,125Hz. Da aber die Frequenz auf 0,5Hz genau bestimmt werden soll, ist meine Frage wie ich das gewonnene Wissen, das die gesuche Frequenz irgendwo um zb 140Hz +- 1,5Hz liegt, gewinne. Gibt es dafür einen Algorithmus? Gruß, Rasmus
Hallo robotxy, nimm doch einmal einen Ton mit der Soundkarte auf und stelle das ins Netz ? Fritz
Hallo robotxy, du nimmst 384 Abtastwerte auf. Von den ersten 256 Abtastwerten machst du die erste FFT (mit Hammingfenster). Eine halbe FFT-Länge später dann die zweite FFT (auch mit Hammingfenster). Deine 6 Frequenzen liegen immer etwas neben den Spektrallinien der FFT. Wieviel das ist kannst du aber über die Phasendrehung an der maximalen Spektrallinie von der ersten zur zweiten FFT berechnen. 140Hz liegt z.B. 0.625Hz unter 45*3.125Hz. Also ist die 45.Spektrallinie maximal. Du braucht also die Phase in rad an den entsprechendem FFT-Koeffizienten. f = (45 + (phi2-phi1)/pi) * 3.125Hz Die erreichbare Frequenzauflösung ist um den Rauschabstand des ADC besser als die Frequenzauflösung einer FFT und kann unter 1mHz sein.
So bin wieder da, hab das mit dem Hammingfenster als auch die Idee von Ralf verstanden und werde es jetzt demnächst umsetzen. Ein Problem habe ich noch: Ich verwende den Code von http://elm-chan.org/. Wie kann ich mir jetzt die Phase ausgeben lassen? Irgendwie funktioniert mein Code mit der Division nicht, und es kommt mir so vor als wenn der Imaginär und Realteil gleich groß sind. Hier ist einmal der Code der Output Funktion, wie muss ich diesen umschreiben (bin leider in ASM nicht so bewandert..):
1 | ;----------------------------------------------------------------------------; |
2 | .global fft_output |
3 | .func fft_output |
4 | fft_output: |
5 | pushw T2H,T2L |
6 | pushw T4H,T4L |
7 | pushw T6H,T6L |
8 | pushw T8H,T8L |
9 | pushw T10H,T10L |
10 | pushw AH,AL |
11 | pushw YH,YL |
12 | |
13 | movw T10L, EL ;T10 = array_bfly; |
14 | movw YL, DL ;Y = array_output; |
15 | ldiw ZH,ZL, tbl_bitrev ;Z = tbl_bitrev; |
16 | clr EH ;Zero |
17 | #ifdef INPUT_IQ |
18 | ldiw AH,AL, FFT_N ;A = FFT_N; (pluse/minus) |
19 | #else |
20 | ldiw AH,AL, FFT_N / 2 ;A = FFT_N / 2; (pluse only) |
21 | #endif |
22 | 1: lpmw XH,XL, Z+ ;X = *Z++; |
23 | addw XH,XL, T10H,T10L ;X += array_bfly; |
24 | ldw BH,BL, X+ ;B = *X++; |
25 | ldw CH,CL, X+ ;C = *X++; |
26 | FMULS16 T4H,T4L,T2H,T2L, BH,BL, BH,BL ;T4:T2 = B * B; |
27 | FMULS16 T8H,T8L,T6H,T6L, CH,CL, CH,CL ;T8:T6 = C * C; |
28 | addd T4H,T4L,T2H,T2L, T8H,T8L,T6H,T6L;T4:T2 += T8:T6; |
29 | SQRT32 ;B = sqrt(T4:T2); |
30 | stw Y+, BH,BL ;*Y++ = B; |
31 | subiw AH,AL, 1 ;while(--A) |
32 | rjne 1b ;/ |
33 | |
34 | popw YH,YL |
35 | popw AH,AL |
36 | popw T10H,T10L |
37 | popw T8H,T8L |
38 | popw T6H,T6L |
39 | popw T4H,T4L |
40 | popw T2H,T2L |
41 | clr r1 |
42 | ret |
43 | .endfunc |
Vielen Dank! Rasmus
So es funktioniert jetzt soweit wie ralf beschrieben hat, bis auf das mit der Fensterfunktion. Wie muss ich die Eingangswerte einfach nur mit dem jeweiligen Hammingfenster multiplizieren (n-ter Eingangswert mit dem n-ten Wert des Hammingfensters)? Gruß, Rasmus
So, habs hinbekommen. Jetzt sind die ergebnisse ein bisschen besser, aber es ist immer noch so, das die Frequenz schwankt und manchmal die Obertöne lauter als der Grundton sind. Gibt es da noch irgendwelche weiteren Algorithmen so ala der Fensterfunktion um die ergebnisse zu verbessern? Oder liegt es einfach daran das die Gitarre kein klares Sinus-Signal hat und deswegen das ganze schwankt? Gruß, Rasmus
Hallo Rasmus, vieleicht reicht es nach dem Anschlag einige 100ms zu warten bis alle Saiten frei schwingen und erst dann die Messung zu starten? Den Algorithmus vorher unbedingt mit einem synthetischem Sinussignal bei verschiedenen Frequenzen testen. Was ich mir noch vorstellen kann ist eine Schwebung der Grundschwingung einer Saite mit der Oberwelle einer anderen. Beim Anschlag einer einzelnen Saite sollt dieser Effekt dann nicht auftreten. Wenn das so ist muß die Messdauer beim Anschlag aller Saiten größer als das Schwebungsintervall sein. Gruß, 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.