Forum: Digitale Signalverarbeitung / DSP / Machine Learning Frequenzzähler für mehrere Frequenzen


von robotxy (Gast)


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

von chris (guest) (Gast)


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.

von GSP (Gast)


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.

von robotxy (Gast)


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

von GSP (Gast)


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.

von GSP (Gast)


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.

von robotxy (Gast)


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

von GSP (Gast)


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.

von GSP (Gast)


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.

von robotxy (Gast)


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?

von robotxy (Gast)


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

von GSP (Gast)


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.

von robotxy (Gast)


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

von Fritz (Gast)


Lesenswert?

Hallo,

falls wirklich nur 6 Frequenzen gefragt sind, ist eine DFT kürzer als 
eine FFT.
z.B. nur Görlitz

Gruß Fritz

von robotxy (Gast)


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

von Fritz (Gast)


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

von robotxy (Gast)


Lesenswert?

Weder gleichzeitig noch in einem bestimmten Verhältnis.
Rasmus

von GSP (Gast)


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

von robotxy (Gast)


Lesenswert?

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

von Fritz (Gast)


Angehängte Dateien:

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

von robotxy (Gast)


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

von Fritz (Gast)


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

von robotxy (Gast)


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

von Fritz (Gast)


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

von robotxy (Gast)


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

von Fritz (Gast)


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

von robotxy (Gast)


Lesenswert?

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

von robotxy (Gast)


Lesenswert?

Achja ich rechne nicht mit einem reinen Sinus, ist das sehr schlimm?

von chris (guest) (Gast)


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.

von Matthias (Gast)


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.

von robotxy (Gast)


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

von Fritz (Gast)


Lesenswert?

Hallo robotxy,

nimm doch einmal einen Ton mit der Soundkarte auf und stelle das ins 
Netz ?

Fritz

von ralf (Gast)


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.

von robotxy (Gast)


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

von robotxy (Gast)


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

von robotxy (Gast)


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

von ralf (Gast)


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

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
Noch kein Account? Hier anmelden.