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
@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
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
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
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,
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..):
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