Datum:
Hallo, hat jemand eigentlich schon mal die Phase eines Sinus über Goertzel richtig berechnet? Die Amplitude bekomme ich genau hin doch die Phase ist immer Mist. Ich habe mich genau an diese Vorschrift gehalten. http://www.eetimes.com/design/embedded/4024443/The... Gruß D.
Datum:
Das wird Dir ohne weitere Infos niemand beantworten können. Warum meinst Du ist die Phase nicht OK? Wie stellt sich das Problem genau dar? Berechnest Du kontinuierlich, oder blockweise? Wie sieht Dein Code aus?
Datum:
Angehängte Dateien:Ich berechne Blockweise. Nach der Berechnung stimmt der Betrag der Amplitude exakt mit dem Sinus überein. Die Phase hat jedoch einen konstanten Fehler in Abhängigkeit der Blocklänge und der Abtastzeit.
Datum:
>Nach der Berechnung stimmt der Betrag der >Amplitude exakt mit dem Sinus überein. Die Phase hat jedoch einen >konstanten Fehler in Abhängigkeit der Blocklänge und der Abtastzeit. Was willst du mit der Phase? Soweit ich Goertzel und FFT verstanden habe kann man damit feststellen ob eine Frequenz in den Samples vorhanden ist. Man kann auch feststellen mit welchem Energieinhalt. Man kann nicht feststellen zu welchem Zeitpunkt sie in den Samples vorhanden ist. Sie kann in der ersten Hälfte der Samples mit sehr hohem Pegel vorhanden sein und in der zweiten gar nicht. Wenn sie über alle Samples mit halber Amplitude vorhanden ist bekommst du das gleiche Ergebnis. Eine Phase kannst du damit nicht feststellen. In Bezug auch was auch?
Datum:
Natürlich kann man mit FFT, Goertzel oder SDFT Algorithmen die Phase bestimmen. @Detlef: Ist der Fehler zufällig ein Vielfaches von "pi"? <der Holger mit Grossbuchstaben>
Datum:
Holger schrieb: > @Detlef: Ist der Fehler zufällig ein Vielfaches von "pi"? Ja, danke! Die atan-Berechnung benötigt noch die Korrektur um pi. Das war aber nicht der Fehler. Der korrekte Amplitudenwert ist gegenüber den korrekten Phasenwert genau um ZWEI Abtastschritte verschoben.
Datum:
Wieviel Werte shcibest Du denn rein und welche Frequenz interessiert dich?
Datum:
Hi ich verwende den G. zum Berechnen von Phase und Amplitude und hab keine Probleme. Es geistern aber im Netz aber einige falsche Implementierungen herum. Häufig hakt es an folgenden Umständen: - die Speicher-Zellen müssen vor dem Starten mit 0 initialisiert sein. - im letzten Durchlauf muss dem Eingangssignal eine 0 angehängt werden. Um den G. einer Sequenz mit N Samples zu berechnen benötigt man also N+1 Durchläufe des Filters. Grüße, Alex
Datum:
@Alex Danke! Das war es. Die Verschiebung von N-2 deutete irgendwie schon darauf hin. Nun läuft es perfekt. Detlef
Datum:
Angehängte Dateien:Dank der kompetenten Hilfe hier im Forum nun ein Goertzelalgorithmus der fehlerfrei arbeitet. Für alle Wiederholungstäter - siehe Anhang ;-) Detlef
Datum:
Hallo, ich versuche gerade verzweifelt den Görtzel Algorithmus auf einem Microcrontoller zu implemetieren. Habe aber noch Verständnisfragen. Ich möchte nur die Phase von zwei Sinus Signalen auslesen. Beide Signale liegen bei etwa 25 kHz. Das Original Signal ist ein Sinus mit einer Amplitude von ca. 1,25 Volt. Das verschobene Signal ein Sinus der etwa um 40 bis 60 Grad verschoben ist und eine Amplitude von ca. 0,8 Volt hat. Und ich taste mit 120 kHz ab. Ich gebe immer 100 Abtastwerte auf den Algorithmus. Ich möchte die Differenz der Phasenlagen berechnen. Jedoch ändert sich diese ständig, obwohl die Signale immer die gleiche Phasenlage zueinander haben. Was muss ich beachten bezüglich Abtastwerte oder besser gesagt Blockgröße? Danke für eventuelle Tipps! Gruß Marcus
Datum:
Angehängte Dateien:Hallo Marcus, deine Filterbandbreite ist zu groß. Du musst entweder die Abtastfrequenz kleiner machen oder die Blockgröße erhöhen. Anbei mal zwei Varianten. 1. 120 kHz Abtastfrequenz und Blockgröße 600 2. 20 kHz Abtastfrequenz und Blockgröße 100 Der Vorteil von Görtzel liegt ja gerade in der Unterabtastung.
Datum:
Der Goertzel (wie auch der FFT) Algorithmus liefert nur korrekte Werte für ganzzahlige Frequenzen (1/2/3/4... Schwingungen pro Block (bzw. Fenster)). Falls die Frequenz nicht ganzzahlig im Fenster ist -> leakage effect ( http://de.wikipedia.org/wiki/Leck-Effekt ). Gruß, Alex
Datum:
Hallo, @Detlef: danke für den Hinweis. Werde dies berücksichtigen. Hängt dies dann nicht auch an der benötigten Bandbreite. Was wäre wenn ich 120 Hz Bandbreite annehme? @Alex: danke für den Hinweis. Sollte ich eventuell sogar das Signal mit diversen Fensterfunktionen (Hamming usw.) multiplizieren oder ist der Algorithmus auch mit einem normales Rechteckfenster zu gebrauchen? Danke für die Hinweise. Gruß Marcus
Datum:
Marcus Moser schrieb: > Was wäre wenn ich 120 Hz > Bandbreite annehme? Das kannst du natürlich machen. Bei einer Abtastfrequenz von 20 kHz kommst du bei B=120 aber nicht auf ein ganzzahlige Blockgröße. Bei B=125 erhältst du jedoch für die Blockgröße N=160. Außerdem muss, wie Niedes schon sagte, immer eine ganzzahlige Periode der Schwingungen in den Block passen. Das ist bei N=160 auch erfüllt. Das „fenstern“ kannst du dir damit sparen, es ist ja somit ein Rechteckfenster.
Datum:
Alles klar danke. Werde es gleich mal mit Matlab simulieren. Das mit der Fensterfunktion war klar. Meinte nur ob ich eventuell das Signal an den Rändern nicht so "hart" (Rechteckfenster) fenstern soll, sondern durch Hamming usw. Gruß Marcus
Datum:
Marcus Moser schrieb: > Meinte nur ob ich eventuell das > Signal an den Rändern nicht so "hart" (Rechteckfenster) fenstern soll Wenn du dafür sorgst, dass immer eine volle Periode oder ein Vielfaches davon in den Block passt (Phasenlage egal), dann musst du nicht fenstern. Wenn du nun virtuell die Blöcke ins positive und ins negative aneinander hängen würdest, entsteht an den Blockgrenzen keine Unstetigkeit. Damit ist existiert das Signal von Minus Unendlich bis Plus Unendlich. Somit tritt kein Leakage auf.
Datum:
Hallo Detlef, ich hätte da noch eine Frage: Ich erzeuge in Matlab einen Sinus mit der Frequenz 25 kHz und nehme von diesem alle 4*10^-6 sec (entspricht einer Samplefrequenz von 250 kHz) eine Stützstelle. Dann muss ich schauen, dass ich ein ganzzahliges Vielfaches von Perioden im "Fenster" habe. Dies wären doch dann n*T = n* 40*10^-6. Bandbreite = fs/N. Wie groß sollte die Bandbreite maximal sein? Und wenn ich an der Samplefrequenz nichts ändern möchte, muss ich ich die Blockgröße N dann auf z.B. auf 1250 erhöhen? Dann hätte ich eine Bandbreite von 200 Hz. Und in N=1250 würden 125*T hineinpassen. Gruß Marcus
Datum:
Angehängte Dateien:@Marcus Deine Überlegung ist richtig. Du musst nur die Bedingung n*T = N*Ts einfach einhalten. Ist wie in deinem Fall n=125 dann ist N=1250. Es geht natürlich auch mit n=1 und damit mit N=10. Allerdings wird die Bandbreite katastrophal. Praktisch würde ich zunächst meine maximale Bandbreite ermitteln und dann das zugehörige n bzw. N ermitteln.
Datum:
Nur so'n Kommentar, wo ich grade mitlese: Unter dem Stichwort "Sliding Goertzel" gibt's einige Erkenntnisse zu Phase und beliebigen Frequenzen (müssen nicht ins "Fenster" passen. Zeitliche Änderungen und laufende Ermittlung der Phase ist also ansich kein Problem.
Datum:
Hallo zusammen, hallo Detlef, ich habe den Görtzel nun in Matlab realisieren können. Nun geht es darum, diesen Code auch im Controller zu implementieren. Bis jetzt habe ich folgenden Code:
double Fs = 229840;
double k;
double coeff;
double cos_coeff;
double realteil;
double imagteil;
double phi_rad;
double phi_grad;
double s0 = 0.0;
double s1 = 0.0;
double s2 = 0.0;
int ind;
k = round(f/Fs*N)+1;
coeff = 2*M_PI*(1/N)*k;
cos_coeff = cos(coeff) * 2;
x[N+1]=0;
for (ind=1; ind==N+1; ind++)
{
s0 = x[ind] + cos_coeff*s1 - s2;
s2 = s1;
s1 = s0;
}
realteil = s1 - s2*cos_coeff/2;
imagteil = s2*sin(coeff);
phi_rad= atan(imagteil/realteil);
if (realteil < 0)
{
phi_rad = phi_rad - (M_PI/2);
}
else
{
phi_rad = phi_rad + (M_PI/2);
}
phi_grad = 180*phi_rad/M_PI;
if (phi_grad > 180)
{phi_grad = phi_grad - 360;}
if (phi_grad < -180)
{phi_grad = phi_grad +360;}
return phi_grad;
|
Jedoch erhalte ich keine gescheiten Zahlen. Liegt wohl an den Nicht-Integer Berechnungen. Aber ich dachte, dass ich dies mit double Variablen richitg mache. Kann mir da jemand auf die Sprünge helfen? Danke. Gruß Marcus
Datum:
Hallo! Also im Görtzel-Teil sehe ich auf die Schnelle keinen Fehler. Was meinst du mit "keine gescheiten Zahlen"? Hast du die Berechnung in Matlab genau so gemacht? Alex
Datum:
Hi,
arbeitest Du mit MathCad? Das Ablaufdiagramm in den ersten Posts sieht
zumindest danach aus.
Wenn es MathCad ist, könnte es vielleicht am
atan (imag / real)
liegen, wenn die Phase "komisch" ist, da sich dieses "atan(...)" immer
auf den 1. Quadranten des komplexen Ebene bezieht. Wenn die komplexe
Zahl dort nicht liegt, produziert der "atan(...)" halt Käse.
Probier die Phase mal anders zu berechnen. Ich glaube, in MathCad gibt's
noch den Befehl "angle(...)" (oder so). Dabei wird automaisch der
richtige Quadrant bestimmt.
Dann klappt's auch mit der Phase ;-)
Datum:
Marcus Moser schrieb: > Jedoch erhalte ich keine gescheiten Zahlen. Der Code sieht korrekt aus. Was ist dein Fehler? Gebe mal ein Bsp. an.
Datum:
Hi Alex, SFT.., Detlef, sorry, dass ich mich erst jetzt melde, hatte letzte Woche keine Zeit mehr. Ja ich habe diesen Code in Matlab so laufen und er tut auch was er soll. Nur im Controller gab er mir die Phasen entweder gar nicht aus oder falsch. Ich habe mittlerweile den Code im Controller soweit am Laufen, dass er nun auch die Phase ausgibt. Nur habe ich bei der Berechnnung irgendwelche Schwankungen, so dass er immer zwischen 10 bis 20 Grad schwankt, aber stabil. Dieselbe Hardware nur mit Matlab über UART an Com Schnittstelle angesteuert und ausgelesen gibt mir exaktere Werte. D.h. es muss an der Berechnung im Controller liegen. Deswegen habe ich die float Zahlen in meiner Berechnung unter verdacht. Hat da eventuell schon jemand den Görtzel auf dem Controller am Laufen mit Integer Zahlen (Code in C)? Den Code habe ich gerade auf dem anderen Rechner und kann diesen deswegen jetzt nicht anhängen, aber ich werde dies morgen früh noch nachholen. Gruß Marcus
Datum:
Ich habe gerade mal mit unterschiedlichen Rundungsvarianten gerechnet. 3 Nachkommastellen 0.1 % Phasenfehler 2 Nachkommastellen 1 % Phasenfehler 1 Nachkommastelle 4.5 % Phasenfehler 0 Nachkommastellen 18 % Phasenfehler
Datum:
Hallo Detlef, danke für die tolle Hilfe. Die Lösung meines Problems haben wir nun herausgefunden. Der µ-Controller hatte Probleme bei der Abtastung. Zuerst war der Kerntakt zu langsam eingestellt und dann der Timer für die Abtastung durch den ADC. Die Schwankungen sind soweit weg, da ich die Signale nun auch gescheit abtaste. @alle anderen: Wer diesen Thread zufällig liest und auch mit dem AdµC 7128/ 7129 arbeitet und Hilfe braucht. Ich habe den C-Code nun fertig. Einfach anfragen. Gruß Marcus




