Forum: Digitale Signalverarbeitung / DSP / Machine Learning Frequenzmessung durch lineare Regression des Sinus an der Nullstelle


von Note (Gast)



Lesenswert?

Hallo liebe Gemeinde,

ich versuche mich gerade an dem angehängten Paper zu orientieren, um die 
Frequenz eines Sinussignals im Bereich >0...100 Hz zu bestimmen. Die 
Samplerate beträgt 1250Hz - da werde ich vermutlich nicht auf 4 Samples 
VOR und 4 Samples NACH dem zero crossing kommen, aber theoretisch sollte 
dieser Algorithmus mit bei 30Hz-Sinussignal reibungslos funktionieren 
(Über 40 Samples pro Periode).

So mein Gedanke. Für 8 Koeffizienten besteht ein FIFO-Buffer. Nach jedem 
Sample wird geprüft, ob bei N/2, also zwischen x_n <= d < x_n+1 eine 
Nullstelle erfolgt, das normalisierte d also zwischen 0 und 1 ist. 
Sobald das der Fall ist, wird der Zeitpunkt des zero crossing notiert.

Sobald das 3. zero crossing erfolgt ist, wird die Periode über die 
Subtraktion des letzten und des ersten zero crossing berechnet und die 
Frequenz über den Kehrwert gebildet.

Falls meine wirren Gedanken soweit verständlich waren nun die 
eigentliche Frage: Ist der Algorithmus prinzipiell so richtig? Ich 
bekomme zwar bei der Code-Ausführung erst die richtige Frequenz hin 
(lasse sie auf einen DAC ausgeben zur Prüfung), jedoch bleibt der 
Algorithmus "nicht stabil" und es folgen irgendwelche Sprünge.
Ist nun der Algorithmus generell so machbar und der Fehler ist eher 
code-bedingt?

Danke im Voraus :)

von Egon D. (Gast)


Lesenswert?

Note schrieb:

> So mein Gedanke. Für 8 Koeffizienten besteht ein
> FIFO-Buffer. Nach jedem Sample wird geprüft, ob bei
> N/2, also zwischen x_n <= d < x_n+1 eine Nullstelle
> erfolgt, das normalisierte d also zwischen 0 und 1
> ist. Sobald das der Fall ist, wird der Zeitpunkt
> des zero crossing notiert.

Warum zitierst Du einen Artikel, der eine lineare
Regression verwendet, wenn Du dann KEINE lineare
Regression verwendest?


> Sobald das 3. zero crossing erfolgt ist, wird die
> Periode über die Subtraktion des letzten und des
> ersten zero crossing berechnet und die Frequenz
> über den Kehrwert gebildet.

Gefährlich. Jede Störung, die einen Nulldurchgang
außer der Reihe erzeugt, stört auch Deine Frequenz-
messung.

von Note (Gast)


Lesenswert?

> Gefährlich. Jede Störung, die einen Nulldurchgang
> außer der Reihe erzeugt, stört auch Deine Frequenz-
> messung.

Und du hast dir auch ganz sicher das angehängte Paper durchgelesen?

von Burkhard (Gast)


Lesenswert?

Note schrieb:
> um die
> Frequenz eines Sinussignals im Bereich >0...100 Hz zu bestimmen. Die
> Samplerate beträgt 1250Hz ...

Wenn Dein Sinussignal mehrere Komponenten enthält, entgehen Dir bei der 
Zero-Crossing Analyse die niedrigeren Frequenzen. Falls Dein Signal 
Anteile oberhalb der halben Samplerate hat, bekommst Du Aliasing - d.h. 
Du siehst "falsche" Signale im erfassten Frequenzband, die sich nicht 
mehr von "echten" Signalen unterscheiden lassen. Diese Frequenzen 
müssten zunächst herausgefiltert werden (digital geht das nicht mehr).

Oft wird für die ZC-Analyse das Signal über einen Schmitt-Trigger 
(Komparator mit Hysterese) in ein Rechtecksignal umgewandelt, kleine 
Schwankungen um den Nullpunkt dadurch ausgeblendet, aber die 
Amplitudeninformation geht verloren. Ein Schmitt-Trigger löst das 
Problem bei mehreren Frequenzanteilen nicht.

Wie/wozu soll das digitalisierten Signal weiter verarbeitet werden?

von Burkhard (Gast)


Lesenswert?

Note schrieb:
> Und du hast dir auch ganz sicher das angehängte Paper durchgelesen?

Vielleicht hättest Du beschreiben sollen, welche der dort beschriebenen 
Massnahmen Du bereits implementiert hat. Du hast auch gesehen, dass die 
Autoren das zu analysierende Signal mit min. 6000 Samples pro Wellenzug 
gesamplet haben?

von Note (Gast)


Lesenswert?

> Vielleicht hättest Du beschreiben sollen, welche der dort beschriebenen
> Massnahmen Du bereits implementiert hat. Du hast auch gesehen, dass die
> Autoren das zu analysierende Signal mit min. 6000 Samples pro Wellenzug
> gesamplet haben?

Ich habe den gesamten Software-Algorithmus implementiert. Und sie haben 
diese Samplerate genommen, um eine Genauigkeit von 0.006 Hz zu 
erreichen, die ich erstmal nicht benötige. Und die generelle Frage ist, 
ob ihr Probleme dabei sehr, diesen Algorithmus für die Frequenzmessung 
(wie o.g.) zu verwenden?

von Note (Gast)


Lesenswert?

> Wie/wozu soll das digitalisierten Signal weiter verarbeitet werden?
Es soll die korrekte Frequenz bei einer (erstmal unter Testbedingungen 
reiner) 30Hz-Sinuskurve berechnet werden.
Später soll die Geschichte dazu dienen, auch etwas unsaubere Signale 
(jedoch alles unter der Aliasing-Grenze) rauszufiltern, bzw immer noch 
einen sauberen zero crossing point zu berechnen.

von Egon D. (Gast)


Lesenswert?

Note schrieb:

>> Gefährlich. Jede Störung, die einen Nulldurchgang
>> außer der Reihe erzeugt, stört auch Deine Frequenz-
>> messung.
>
> Und du hast dir auch ganz sicher das angehängte Paper
> durchgelesen?

Wie hätte ich sonst bemerken sollen, dass Du in Deinem
Beitrag nicht das Verfahren beschreibst, von dem im
Paper die Rede ist?


Aber das ist nicht mein Problem. Du willst ja etwas
wissen. Viel Spaß noch.

von Note (Gast)


Lesenswert?

> Aber das ist nicht mein Problem. Du willst ja etwas
> wissen. Viel Spaß noch.

Dankeschön, werde ich haben.

von Michel (Gast)


Lesenswert?

Burkhard schrieb:
> u hast auch gesehen, dass die
> Autoren das zu analysierende Signal mit min. 6000 Samples pro Wellenzug
> gesamplet haben?

... was sehr interessant und relativ unnötig ist, angesichts der im 
Signal vermuteten Oberwellen. Wichtiger wäre, mehrere Wellen zu 
überdecken.

von Rübezahl (Gast)


Lesenswert?

Wenn die Amplitude immer gleich hoch ist, dann kann man die Frequenz 
tatsächlich mit der linearen Regression berechnen. Aber je 
unterschiedlicher die Amplituden sind, um so ungenauer wird das 
Ergebnis.

von Bauform B. (bauformb)


Lesenswert?

Note schrieb:
> Es soll die korrekte Frequenz bei einer (erstmal unter Testbedingungen
> reiner) 30Hz-Sinuskurve berechnet werden.

Bei solchen Frequenzen funktioniert hier eine PLL mit 0.0025 Hz 
Auflösung.

von Tobias P. (hubertus)


Lesenswert?

Bauform B. schrieb:
> Note schrieb:
> Es soll die korrekte Frequenz bei einer (erstmal unter Testbedingungen
> reiner) 30Hz-Sinuskurve berechnet werden.
>
> Bei solchen Frequenzen funktioniert hier eine PLL mit 0.0025 Hz
> Auflösung.

wie hast du das gemacht, kannst du da ein paar Infos geben?
ich wollte auch schon lange mal das vom TO erwähnte Verfahren verwenden, 
um Nulldurchgänge eines niederfrequenten (1..10 Hz) Sinussignals genauer 
zu bestimmen. Hintergrund (und ich denke der TO hat etwas ähnliches vor) 
ist, dass man so mit einem DMTD-System (dual mixer time difference) die 
Stabilität von Oszillatoren vergleichen kann.
Dazu muss man aber die Nulldurchgänge zweier niederfrequenter Signale 
genau vergleichen.

von Note (Gast)


Angehängte Dateien:

Lesenswert?

> wie hast du das gemacht, kannst du da ein paar Infos geben?

Ich kann dir auch die ganze Bibliothek geben :)

Im Header-File siehst du die Datenstruktur mit den structs:
INPUT_DATA_T -> FIFO_DATA_T -> OUTPUT_DATA_T

D.h. von der Architektur her werden diese Daten durchgereicht und 
aktualisiert bzw. ausgelesen.
1
int Freq_CheckIfZeroCrossingOccured(INPUT_DATA_T *inputData, FIFO_DATA_T *fifoData)

wird nach jeder Abtastung ausgeführt und liest in den FIFO-Buffer den 
neuen Wert samt Zeitstempel rein. Sobald der Buffer mit den ersten 8 
(N_SAMPLES) gefüllt ist, findet die erste Berechung statt, ob ein 
Nulldurchgang erfolgte. Und zwar - falls dieser stattfand, befindet sich 
dieser um N/2 rum, also in der Arraymitte, zwischen Array[3] und [4]. 
Das d ist die Entfernung von Array[3].

Das normierte d wird anschließend in einen Zeitstempel umgerechnet, der 
in OUTPUT_DATA_T gesichert wird. Anschließend wird zyklisch per
1
int Freq_CheckIfFullPeriod(FIFO_DATA_T *fifoData, OUTPUT_DATA_T *outputData)

geprüft, ob wir nun 3 Nulldurchgänge haben, so dass wir diese zu einer 
Periode umrechnen können (Endzeit - Startzeit). Davon den Kehrwert und 
dann haben wir eine Frequenz.

Soviel dazu. Du kannst es natürlich bestimmt hinsichtlich der 
Geschwindigkeit optimieren. Ich habe es alles in die Länge gezogen, weil 
ich noch nicht den Fehler ausschließen konnte. Falls die Fkt. bei dir 
also funktioniert, wüsste ich schon mal, dass der Bug nicht in diesen 
Funktionen liegt.

Viel Erfolg

von Detlef _. (detlef_a)


Lesenswert?

Frequenz, Amplitude, Phase und Offset eines gesampelten Signals kann man
super so bestimmen:

Beitrag "Frequenz, Amplitude und Phase eines Sinussignals bestimmen"

Cheers
Detlef

: Bearbeitet durch User
von Tobias P. (hubertus)


Lesenswert?

Note schrieb:
> Ich kann dir auch die ganze Bibliothek geben :)

danke, das ist sehr cool und schaue ich mir gerne an.
Allzu bald darfst du aber noch nicht mit einer Rückmeldung von Messdaten 
zwecks Vergleich rechnen, da ich zunächst noch mein GPS-Frequenznormal 
in der 2. Version fertig bauen will, danach noch dessen Software fertig 
schreiben muss und DANN erst dazu komme, mir ein DMTD-System zu bauen.
Und, wie mir scheint, habe ich mit meiner Vermutung weiter oben ins 
Schwarze getroffen und du hast das bei dir auch für ein DMTD verwendet 
:-) vielleicht möchtest du per PN o.ä. ein paar mehr Infos noch geben, 
welche Mischer hast du verwendet, was für ADCs, welcher Prozessor etc., 
und wie gut funktioniert es bei dir, welchen Noise Floor konntest du 
erzielen usw.

Detlef _. schrieb:
> Frequenz, Amplitude, Phase und Offset eines gesampelten Signals kann man
> super so bestimmen:
>
> Beitrag "Frequenz, Amplitude und Phase eines Sinussignals bestimmen"
>
> Cheers
> Detlef

Hi Detlef
jup mit Prony geht das auch super; hast du das schon mal im Zusammenhang 
mit einem DMTD verwendet?
Bei den "normalen" DMTDs verstärkt man ja einfach das heruntergemischte 
Signal und gibt es auf einen Schmitt-Trigger, mit dem danach ein TIC 
gefüttert wird. Man misst dann das Zeitintervall zwischen den 
Nulldurchgängen zweier Sinussignale.
Die DDMTD sind etwas fancier, dort kann man das heruntergemischte Signal 
sampeln und intern korrelieren und so die Phasenverschiebung bzw. 
zeitlichen Versatz herausfinden, scheint mir aber sehr aufwendig, evtl. 
ginge es mit Prony einfacher? man muss halt eine einigermassen gute 
zeitliche Auflösung haben. Daher würde ich mich bei einem selbstbau DMTD 
noch nicht an sowas heran wagen, sondern zuerst klassisch mit einem TIC 
arbeiten, aber vielleicht kannst du dazu ja noch was sagen.
Aber ich will den Thread hier jetzt nicht kapern.

von Detlef _. (detlef_a)


Lesenswert?

Hallo Tobias,

just die Idee ist mir erst gekommen, als ich Deinen Beitrag zu DMTD las, 
gemacht hab ich das noch nicht. Ich wüßte nicht, dass das jemand so 
gemacht hätte. Ich bin noch relativ unfit was diese Allan-Deviation 
Messung angeht, aber die Frequenzbestimmung kann ich sehr gut und ich 
hätte großen Spaß dran Dich dort zu unterstützen. Ich glaube, Du bist 
auch bei time-nuts unterwegs. Vllt. kannst Du ja nen neuen thread dazu 
aufmachen oder pn .

Cheers
Detlef

von Bauform B. (bauformb)


Lesenswert?

Tobias P. schrieb:
> Bauform B. schrieb:
>> Note schrieb:
>> Es soll die korrekte Frequenz bei einer (erstmal unter Testbedingungen
>> reiner) 30Hz-Sinuskurve berechnet werden.
>>
>> Bei solchen Frequenzen funktioniert hier eine PLL mit 0.0025 Hz
>> Auflösung.
>
> wie hast du das gemacht, kannst du da ein paar Infos geben?

Ich glaube kaum; ich hab' übersehen, dass ihr hier in einer ganz anderen 
Liga spielt. Die PLL ist ein HEF4046, davor sitzt ein Tiefpass und ein 
total übersteuerter Verstärker, die Zeitbasis ist ein billiger 2.4576MHz 
Quarz.

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.