Frequenzzähler für mehrere Frequenzen

Gast #648713
Lesenswert?

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
Gast #648736
Lesenswert?

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.
Gast #648755
Lesenswert?

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.
Gast #648788
Lesenswert?

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
Gast #648798
Lesenswert?

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.
Gast #648802
Lesenswert?

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.
Gast #648807
Lesenswert?

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
Gast #648845
Lesenswert?

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.
Gast #648855
Lesenswert?

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.
Gast #648857
Lesenswert?

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?
Gast #648858
Lesenswert?

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
Gast #648868
Lesenswert?

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.
Gast #648871
Lesenswert?

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
Gast #648882
Lesenswert?

@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
Gast #648886
Lesenswert?

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
Gast #648910
Lesenswert?

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
Gast #648923
Lesenswert?

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
Angehängte Dateien:
Gast #648938
Lesenswert?

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
Gast #648944
Lesenswert?

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
Gast #648947
Lesenswert?

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
Gast #648953
Lesenswert?

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
Gast #648957
Lesenswert?

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
Gast #649005
Lesenswert?

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
Gast #649023
Lesenswert?

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.
Gast #649172
Lesenswert?

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.
Gast #649384
Lesenswert?

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
Gast #650353
Lesenswert?

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.
Gast #651185
Lesenswert?

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
Gast #656300
Lesenswert?

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
Gast #656699
Lesenswert?

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
Gast #656742
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren