Ablesen der Frequenz einer Sinuswelle

Ich versuche, einen Tachometer für mein Auto zu bauen, indem ich die Ausgabe des Geschwindigkeitssensors des Autos verwende. Der Geschwindigkeitssensor gibt eine Sinuswelle aus. Hier ist es auf einem Oszilloskop:asdf

So wie ich es verstehe, muss dieses Signal zwischen 0 und 5 V liegen, damit das Arduino glücklich ist.

Es scheint, dass die Spitze-zu-Spitze dieser Welle ungefähr 8 V beträgt, was bedeutet, dass ich, wenn ich die negative Spannung dieses Signals irgendwie "abhacke", etwas wie 0-4 V übrig lassen sollte, was ich brauche.

Wie gehe ich vor, um dieses Signal vom Arduino zu lesen? Ich möchte die Schaltung aufgrund der rauen (ish) Umgebung, in der sie sitzen wird, einfach halten.

Ich habe einige Leute gesehen, die einfach eine Diode und einen Widerstand vorschlagen, und andere schlagen Operationsverstärker, Schmitt-Trigger und andere Konzepte vor, auf die ich nicht stark bin.

Jede Hilfe ist sehr willkommen!

+1 für die Bereitstellung des Bildes, das sehr informativ für die Form Ihres Signals ist.
Welches Arduino-Modell verwendest du? Könnten Sie Ihre Frage bitte mit dem entsprechenden Arduino-Typ markieren?
@EdgarBonet Der Arduino ist in dieser Frage wirklich zufällig. Es geht darum, eine Sinuswelle zum Lesen durch einen digitalen Eingang einer MCU zu konditionieren. Ich werde es zu EE migrieren, wo es mehr zu Hause wäre.
Hast du das Signal bei allen Motordrehzahlen gemessen/erfasst? Einige Sensoren variieren sowohl die Amplitude als auch die Frequenz mit sich ändernder Geschwindigkeit - normalerweise gilt: Je höher die Geschwindigkeit, desto höher die Amplitude der Sinuswelle. Diese Sensorcharakteristik kann einen erheblichen Einfluss auf viele gängige „Quadrierungs“-Schaltungen haben. Ich sehe auch auf dem Foto, dass dieses Signal eine erhebliche Menge an "Rauschen" aufweist, wie die zahlreichen überlappenden sinusförmigen Spuren auf dem Foto bezeugen. Sie müssen dies quantisieren, um eine Quadrierungsschaltung zu formulieren, die die Frequenz der Sinuswelle originalgetreu in eine Rechteckwelle übersetzt.

Antworten (5)

Es gibt mehrere Möglichkeiten. Mit einem Operationsverstärker und einigen diskreten Komponenten können Sie einen Nulldurchgangsdetektor erhalten, der einen Impuls liefert, dessen Amplitude nicht größer ist als die positive Versorgungsschiene zum Operationsverstärker, der mit einem externen Interrupt oder Pin-Wechsel erkannt werden kann Interrupt auf dem Arduino.

Unten ist ein Beispiel eines Nulldurchgangsdetektors.

schematisch

Simulieren Sie diese Schaltung – Mit CircuitLab erstellter Schaltplan

verzeihen Sie meine Unwissenheit, aber wie bestimmen Sie den Wert der Widerstände und Kondensatoren in dieser Schaltung? und wozu dient der widerstand vor der diode?
Die Werte hängen von den erwarteten Frequenzen ab, die Sie erwarten. Die Diode blockiert die negative fallende Flanke, da der Detektor sowohl steigende als auch fallende Nulldurchgänge erkennt. Um die Frequenz zu messen, müssen Sie nur die Zeit zwischen Kreuzungen gleicher Richtung messen. Bei Widerstands- und Kondensatorwerten passen Sie im Wesentlichen an, um einen Impuls der gewünschten Form zu erhalten. Experiment.
Mir wurde beigebracht, dass Operationsverstärker durchbrennen würden, wenn die Eingangsspannung außerhalb der Versorgungsspannung läge. Ich habe es nie versucht, vielleicht ist es nicht wahr.
@MarkSmith Es gibt verschiedene Operationsverstärker mit unterschiedlichen Einschränkungen. Einige Operationsverstärker verhalten sich so, wie Sie es gerade beschrieben haben. Lesen Sie das Datenblatt für jeden spezifischen Operationsverstärker, wenn Sie sicher sein wollen.
Dioden blockieren nicht wirklich fallende Flanken, sie begrenzen nur den Bereich auf nur positive Spannungen. Außerdem hätten Sie wirklich einen Komparator anstelle eines Operationsverstärkers verwenden sollen, der die ganze Zeit nur in Sättigung sitzt.

Wie ich in Ihrem Oszilloskopbild sehe, erstreckt sich Ihr Signal über einen Bereich von ungefähr –4 V bis ungefähr +2,5 V. Das Hauptproblem bei diesem Signal ist nicht sein negativer Teil, sondern die Tatsache, dass die positive Spannung nicht hoch genug wird. Die meisten Arduinos werden mit 5 V betrieben und haben Schmitt-Trigger an ihren digitalen Eingängen. Die Spannungsschwelle für das Pin-Schalten HIGHliegt typischerweise bei etwa 2,6 V, aber dies ist nur ein typischer Wert. Das einzige, was das Datenblatt garantiert, ist, dass der Pin gelesen wird, HIGHwenn sein Potenzial mindestens 0,6 V CC beträgt , dh 3 V auf einem 5 V Arduino.

Eine Option wäre die Verwendung eines Arduino mit 3,3 V, wie die 3,3-V-Version des Pro Mini. Damit lesen die digitalen Pins garantiert HIGHbei 2 V. Das ist aber grenzwertig für dein Signal. Ihr Bild zeigt, dass einige der Schwingungen maximal 2 V erreichen. Daher würde ich diese Option vermeiden.

Die andere Möglichkeit besteht darin, dem Signal einen DC-Offset hinzuzufügen, damit es um V CC /2 = 2,5 V oszilliert. Auf diese Weise haben Sie eine verschobene Sinuswelle, die ungefähr von –0,75 bis +5,75 V reicht. Dann sind Sie garantiert um sowohl die Schwelle zum Lesen zu erreichen LOW, die nicht niedriger als 0,3 V CC  = 1,5 V ist, als auch die Schwelle zum Lesen HIGH. Ich würde eine Schaltung wie diese verwenden:

schematisch

Simulieren Sie diese Schaltung – Mit CircuitLab erstellter Schaltplan

Der Spannungsteiler erzeugt einen DC-Offset von V CC /2. Der Kondensator auf der linken Seite lässt die AC-Wellenform herein. Zusammen bilden der Kondensator und der Spannungsteiler einen Hochpassfilter mit einer Grenzfrequenz von 1/(πRC). Wenn Sie beispielsweise R = 100 kΩ und C = 1 µF wählen, dann haben Sie eine Grenzfrequenz von 3,18 Hz. Ihr Signal hat etwa 300 Hz, daher sollten Sie in der Lage sein, ein Signal zu messen, das bis zu 100-mal langsamer ist als das abgebildete.

Für den negativen Teil des Signals haben die Arduino-Eingänge Schutzdioden, die sich darum kümmern. Sie müssen nur sicherstellen, dass der Strom durch diese Dioden 1 mA nicht überschreitet. Aus diesem Grund hat das obige Filter einen Strombegrenzungswiderstand nach dem Spannungsteiler. Ein 10-kΩ-Widerstand sorgt dafür, dass Sie den normalen Eingangsspannungsbereich sicher um bis zu 10 V überschreiten können, dh Sie sind sicher, solange die verschobene Sinuswelle zwischen -10 V und +15 V bleibt.

Bearbeiten : Wie aus dem Kommentar von Dmitry Grigoryev hervorgeht, lässt diese Schaltung das Rauschen durch, wenn die Fahrzeuggeschwindigkeit Null ist. Rauschen an einem digitalen Eingang ist oft kein Problem, da es durch die Schmitt-Trigger des Eingangs unterdrückt wird. Ihre Rauschamplitude scheint jedoch ziemlich groß zu sein und ist wahrscheinlich größer als die Hysterese von ~ 0,5 V, die Sie an den Arduino-Eingängen haben. Dann können Sie störende Übergänge erkennen, die als endliche Geschwindigkeit angesehen werden.

In diesem Fall besteht eine einfache Lösung darin, den DC-Offset zu ändern, um ihn von den Übergangsschwellen wegzubewegen. Beispielsweise setzt ein 47-kΩ-Pulldown in Kombination mit einem 100-kΩ-Pullup die DC-Vorspannung auf 1,6 V. Sie können mehr asymmetrische Widerstände verwenden, wenn Sie die DC-Vorspannung noch niedriger machen müssen. Beachten Sie, dass das Ändern der Widerstände auch die Grenzfrequenz ändert. Die 47-kΩ/100-kΩ-Widerstände in Kombination mit einem 1-µF-Kondensator haben eine Grenzfrequenz von etwa 5 Hz.

Wenn das Auto stillsteht, wird sich Ihr Schaltungsausgang auf V / 2 einstellen, und der Hochpassfilter lässt alle Geräusche durch, die vom Sensor kommen.
@DmitryGrigoryev: Dies wäre ein Problem, wenn die Rauschamplitude höher als die Hysterese der Schmitt-Trigger der MCU ist. Aber es scheint, dass das Rauschen des OP tatsächlich ziemlich groß ist ...
Ich glaube nicht, dass das, was auf dem Oszilloskop zu sehen ist, Rauschen ist, eher eine instabile Signalamplitude. Aber in einer realen Autoumgebung kann das Rauschen tatsächlich ziemlich groß sein. Es gibt einen Grund, warum der CAN-Bus einen 120-Ω-Abschluss verwendet und nicht 10 kΩ wie I2C - so wird sichergestellt, dass das Signal unterwegs nicht ein paar zusätzliche Volt aufnimmt.

Angenommen, die Geschwindigkeit ist proportional zur Frequenz und Sie planen, sie durch Zählen der Kanten zu messen, sollte etwas so Einfaches wie ein BJT mit gemeinsamem Emitter gut funktionieren:

schematisch

Simulieren Sie diese Schaltung – Mit CircuitLab erstellter Schaltplan

Die meisten BJTs können problemlos einigen Volt Sperrspannung standhalten, und 2 V positive Spannung reichen aus, um sie in Sättigung zu treiben. Die Tatsache, dass das Signal invertiert wird und das Tastverhältnis nicht 50 % beträgt, sollte Sie nicht daran hindern, die Flanken richtig zu zählen.

Wenn Sie eine 1N914- oder Schottky-Diode zwischen dem Eingangswiderstand und der Basis des Transistors hinzufügen würden, würde dies verhindern, dass höhere negative Spannungen den Transistor beschädigen, und würde die Schaltung immer noch wie beabsichtigt funktionieren?
@VE7JRO Eine bessere Idee wäre, Klemmdioden (sowohl zu VCC als auch zu GND) hinzuzufügen, wenn ein Überspannungsschutz erforderlich ist. Schottky-Dioden haben hohe Leckströme, daher schützen sie nichts: Für den Zweck eines geschlossenen Transistors leiten solche Dioden rückwärts.

Sobald Sie den Schaltplan aus den bisherigen hervorragenden Antworten herausgefunden haben, richten Sie einen Interrupt mit steigender Flanke ein: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

Dadurch können Sie jedes Mal, wenn die Wellenform von negativ nach positiv wechselt, ein bisschen Code ausführen. Ich habe tatsächlich vor einiger Zeit einen Code geschrieben, um dies zu tun, um einige PWM-Sachen zu messen (praktischer 0-5-V-Eingang, keines der Filterprobleme, mit denen Sie es zu tun haben). Ich entschied mich dafür, eine FIFO-Liste der Kreuzungszeitdeltas zu führen, und dann, um die Frequenz zu erhalten, addierte sie und bitverschoben, um sie zu teilen und den Durchschnitt dieser Samples zu erhalten. Das Arduino hat keine Hardware-Division, so dass die Anzahl der Samples diktiert wurde, um die Bitshift-Division durchführen zu können. Ohne Mittelwertbildung fand ich das Signal sehr zittrig.

Sie könnten einen Widerstand, eine Diode und eine Zenerdiode wie die hier abgebildete Schaltung verwenden:

Geben Sie hier die Bildbeschreibung ein

Ich habe "Netzspannung" mit einem Abwärtstransformator verwendet, um den Ausgang der Schaltung zu testen, der so aussieht:

Geben Sie hier die Bildbeschreibung ein

Zwei Probleme mit Ihrer Schaltung: 1. Sie sollten rechts einen Pulldown-Widerstand hinzufügen, sonst gibt es nichts, um das Signal zu senken. Bei Ihrem Experiment erfüllt der Eingangswiderstand des Oszilloskops diese Rolle, aber die Arduino-Eingänge sind im Wesentlichen rein kapazitiv. 2. Das OP-Signal hat einen Spitzenwert von etwa 2,5 V. Subtrahieren Sie die Durchlassspannung des 1N914 und Sie werden garantiert niemals die LOW → HIGH-Eingangsschwelle erreichen.
Ich habe die Tatsache völlig übersehen, dass die Spannung bei etwa 2,5 V gipfelt, und ich stimme Ihnen zu, einen Pulldown-Widerstand hinzuzufügen. Im Moment gibt es 5 Antworten auf die Frage, und die Antwort von Dmitry gefällt mir wirklich am besten, weil das OP die Schaltung einfach halten wollte.