Ich versuche, die Nulldurchgänge einer Sinuswelle zu finden, um die Sinuswelle in eine Rechteckwelle umzuwandeln. Das einzige Problem ist, dass die Sinuswelle laut ist, so dass ich viel Jitter und falsche Nulldurchgänge bekomme.
Kann jemand einen einfachen Pseudocode oder relevante Materialien empfehlen? Bisher habe ich so etwas:
if (sample[i]>0 && sample[i+1]<0) || (sample[i]<0 && sample[i+1]>0)
Kann jemand eine robustere Methode empfehlen?
Antworten:
Sie können versuchen, das Eingangssignal tief zu filtern, um glattere Nulldurchgänge zu erzielen (oder sogar eine Bandpassfilterung, wenn Sie eine gute Vorstellung vom Frequenzort der Sinuswelle haben). Das Risiko besteht darin, dass die zusätzliche Verzögerung des Filters ein Problem darstellt, wenn probengenaue Phaseninformationen für Ihre Anwendung wesentlich sind.
Ein anderer Ansatz: Anstatt zu versuchen, die Sinuswelle in eine Rechteckwelle umzuwandeln, wie wäre es, wenn ein unabhängiger Rechteckwellenoszillator sich in Phase / Frequenz mit der Sinuswelle ausrichtet? Dies kann mit einem Phasenregelkreis erfolgen .
quelle
Was Sie sicherlich gezeigt haben, ist ein Nulldurchgangsdetektor. Ein paar Dinge fallen Ihnen ein, die Ihre Situation verbessern könnten:
Wenn Sie Rauschen haben, das außerhalb des Bandes Ihres Signals liegt (was mit ziemlicher Sicherheit der Fall ist, da Ihr Eingang ein reiner Ton ist), können Sie das Signal-Rausch-Verhältnis verbessern, indem Sie ein Bandpassfilter um das interessierende Signal anwenden . Die Durchlassbandbreite des Filters sollte basierend darauf ausgewählt werden, wie genau Sie die Sinusfrequenz a priori kennen . Durch Reduzieren des auf der Sinuskurve vorhandenen Rauschens wird die Anzahl falscher Nulldurchgänge und deren Jitter um die korrekten Kreuzungszeiten verringert.
In Bezug auf den Nulldurchgangsdetektor selbst können Sie dem Prozess eine gewisse Hysterese hinzufügen . Dies würde die Erzeugung von zusätzlichen unechten gemessenen Kreuzungen um den richtigen Kreuzungszeitpunkt verhindern. Das Hinzufügen einer Hysterese zum Detektor könnte ungefähr so aussehen:
Tatsächlich fügen Sie Ihrem Nulldurchgangsdetektor einen Zustand hinzu. Wenn Sie glauben, dass das Eingangssignal einen positiven Wert hat, muss das Signal unter einen gewählten Schwellenwert fallen,
-T
um einen echten Nulldurchgang zu deklarieren. Ebenso müssen Sie das Signal wieder über den Schwellenwert ansteigen lassen,T
um zu erklären, dass das Signal wieder positiv ist.Sie können die Schwellenwerte so wählen, wie Sie möchten, aber für ein ausgeglichenes Signal wie eine Sinuskurve ist es sinnvoll, sie symmetrisch um Null zu haben. Dieser Ansatz kann Ihnen dabei helfen, eine sauberere Ausgabe zu erzielen, führt jedoch zu einer gewissen Zeitverzögerung, da Sie tatsächlich Schwellenübergänge ungleich Null anstelle von Nulldurchgängen messen.
Wie Pichenettes in seiner Antwort angedeutet hat, ist ein Phasenregelkreis höchstwahrscheinlich der beste Weg, da eine PLL ziemlich genau das tut, was Sie versuchen. Kurz gesagt, Sie betreiben einen Rechteckwellengenerator, der parallel zur Eingangssinuskurve läuft. Die PLL führt periodische Phasenmessungen an der Sinuskurve durch und filtert dann diesen Messstrom, um die Momentanfrequenz des Rechteckwellengenerators zu steuern. Irgendwann wird die Schleife (hoffentlich) verriegelt. An diesem Punkt sollte die Rechteckwelle in Frequenz und Phase mit der Sinuskurve des Eingangs verriegelt sein (natürlich mit einem gewissen Fehler; nichts in der Technik ist perfekt).
quelle
T
. Bedeutung statt&& (sample[i - 1] > -T) && (sample[i] < -T))
verwenden&& (sample[i - 1] >= -T) && (sample[i] < -T))
. Dies muss sowohl angewendet werdenif
undelse if
Aussagen.Ich habe gute Erfahrungen mit einer sehr einfachen Methode gemacht, um die Vorzeichenwechsel im Signal zu finden:
Durchschnitt / Median jedes Clusters, dies ist Ihr Vorzeichenwechsel
Korrelieren Sie mit der Schrittfunktion an dem durch 4 vorhergesagten Punkt
In meinem Fall erhöhen 5 und 6 die Genauigkeit der Methode nicht. Sie können Ihr Signal mit Rauschen zittern und sehen, ob es hilft.
quelle
Ich weiß, dass diese Frage ziemlich alt ist, aber ich musste kürzlich den Nulldurchgang implementieren. Ich habe die von Dan vorgeschlagene Art umgesetzt und bin ziemlich zufrieden mit dem Ergebnis. Hier ist mein Python-Code, wenn jemand interessiert ist. Ich bin nicht wirklich ein eleganter Programmierer, bitte tragen Sie mit mir.
Bitte beachten Sie: Mein Code erkennt keine Anzeichen und verwendet ein wenig a priori Kenntnis einer Zielfrequenz, um die Zeitschwelle zu bestimmen. Dieser Schwellenwert wird verwendet, um die Mehrfachkreuzung (verschiedene Farbpunkte im Bild) zu gruppieren, aus der diejenige ausgewählt wird, die dem Gruppenmedian am nächsten liegt (blaue Kreuze im Bild).
quelle