Inhaltsverzeichnis:

Superschnelle analoge Spannungen von Arduino - Gunook
Superschnelle analoge Spannungen von Arduino - Gunook

Video: Superschnelle analoge Spannungen von Arduino - Gunook

Video: Superschnelle analoge Spannungen von Arduino - Gunook
Video: Der einfache Einstieg in Arduino & Co. 7: Analoge Eingänge 2024, Juli
Anonim
Image
Image

Dieses Instructable zeigt, wie man superschnelle analoge Spannungsänderungen von einem Arduino und einem einfachen Widerstands- und Kondensatorpaar erzeugt. Eine nützliche Anwendung ist die Erzeugung von Grafiken auf einem Oszilloskop. Es gibt mehrere andere Projekte, die dies getan haben. Johngineer zeigt einen einfachen Weihnachtsbaum mit Pulsweitenmodulation (PWM). Andere haben dieses Projekt verbessert, indem sie eine Widerstandsleiter oder einen dedizierten Digital-Analog-Wandlerchip verwendet haben.

Die Verwendung von PWM verursacht viel Flackern, während die Verwendung einer Widerstandsleiter oder eines Digital-Analog-Wandlers mehr Ausgangspins und Komponenten erfordert, die möglicherweise nicht ohne weiteres verfügbar sind. Die von mir verwendete Schaltung ist das gleiche tote einfache Widerstands- und Kondensatorpaar wie in der Weihnachtsbaum-Demo, arbeitet jedoch mit deutlich weniger Flimmern.

Zuerst werde ich Sie durch den Prozess des Aufbaus der Schaltung führen. Dann werde ich Ihnen beibringen, wie Sie Ihr eigenes Bild hinzufügen. Schließlich werde ich die Theorie vorstellen, was es schneller macht.

Wenn Sie dieses Instructable mochten, erwägen Sie bitte, dafür zu stimmen!:)

Schritt 1: Aufbau der Schaltung

Aufbau der Schaltung
Aufbau der Schaltung

Um die Schaltung aufzubauen, benötigen Sie Folgendes:

a) Ein Arduino basierend auf dem Atmel 16MHz ATmega328P, wie ein Arduino Uno oder Arduino Nano.

b) Zwei Widerstände mit dem Wert R, der mindestens 150 beträgt.

c) Zwei Kondensatoren vom Wert C mit C = 0,0015 / R, Beispiele:

  • R = 150Ω und C = 10µ
  • R = 1,5kΩ und C = 1µ
  • R = 15kΩ und C = 100nF
  • R = 150kΩ und C = 10nF

Es gibt zwei Gründe für die Wahl dieser Werte. In erster Linie wollen wir den Strom an den Pins des Arduino unter dem maximalen Nennstrom von 40mA halten. Die Verwendung eines Wertes von 150Ω begrenzt den Strom auf 30mA, wenn er mit der Arduino-Versorgungsspannung von 5V verwendet wird. Größere Werte von R verringern den Strom und sind daher akzeptabel.

Die zweite Einschränkung besteht darin, dass wir die Zeitkonstante, die das Produkt von R und C ist, bei etwa 1,5 ms halten möchten. Die Software wurde speziell auf diese Zeitkonstante abgestimmt. Es ist zwar möglich, die Werte von R und C in der Software anzupassen, es gibt jedoch einen engen Bereich, in dem dies funktioniert. Wählen Sie daher Komponenten so nah wie möglich am empfohlenen Verhältnis aus.

Eine ausführlichere Erklärung, warum die RC-Konstante wichtig ist, wird im Theorieteil gegeben, nachdem ich Ihnen gezeigt habe, wie Sie die Demonstrationsschaltung zusammenbauen.

Schritt 2: Einrichten des Oszilloskops

Einrichten des Oszilloskops
Einrichten des Oszilloskops

Für die Demonstration ist ein Oszilloskop im X/Y-Modus erforderlich. Die Messleitungen müssen wie in den Schaltplänen gezeigt angeschlossen werden. Ihr Oszilloskop wird sich von meinem unterscheiden, aber ich werde die notwendigen Schritte durchgehen, um den X/Y-Modus auf meinem Gerät einzurichten:

a) Stellen Sie den horizontalen Sweep ein, der von Kanal B (der X-Achse) gesteuert werden soll.

b) Stellen Sie das Oszilloskop auf den Zweikanalmodus ein.

c) Stellen Sie Volt/Div auf beiden Kanälen so ein, dass Spannungen von 0 V bis 5 V angezeigt werden können. Ich habe meine auf 0,5 V/div eingestellt.

d) Stellen Sie den Kopplungsmodus auf beiden Kanälen auf DC ein.

e) Passen Sie die Position von X und Y so an, dass sich der Punkt in der unteren linken Ecke des Bildschirms befindet, wenn das Arduino ausgeschaltet ist.

Schritt 3: Laden Sie die Software herunter und führen Sie sie aus

Image
Image

Laden Sie die Software aus dem Fast Vector Display For Arduino-Repository herunter. Die Software ist unter der GNU Affero Public License v3 lizenziert und kann unter den Bedingungen dieser Lizenz frei verwendet und modifiziert werden.

Öffnen Sie die Datei "fast-vector-display-arduino.ino" in der Arduino IDE und laden Sie sie auf Ihr Arduino hoch. Auf Ihrem Oszilloskop-Bildschirm sehen Sie kurzzeitig eine "Happy New Year"-Animation.

Ich habe dieses Projekt in den Wochen vor Weihnachten als persönlichen Hackaton entwickelt, daher gibt es eine Weihnachts- und Neujahrsbotschaft, die Sie sehen können, indem Sie die PATTERN-Variable im Code ändern.

Schritt 4: Erstellen Sie Ihre eigene benutzerdefinierte Zeichnung

Verstehen Sie, warum PWM so langsam ist
Verstehen Sie, warum PWM so langsam ist

Wenn Sie Ihre eigene Zeichnung erstellen möchten, können Sie Punktkoordinaten in die Arduino-Skizze auf der Linie einfügen, die USER_PATTERN definiert.

Ich fand, dass Inkscape ein ziemlich gutes Werkzeug zum Erstellen einer benutzerdefinierten Zeichnung ist:

  1. Erstellen Sie Text mit einer großen, fetten Schriftart wie Impact.
  2. Markieren Sie das Textobjekt und wählen Sie im Menü "Pfad" die Option "Objekt zu Pfad".
  3. Wählen Sie einzelne Buchstaben aus und überlappen Sie sie, um eine verbundene Form zu erstellen
  4. Wählen Sie im Menü "Pfad" die Option "Vereinigung", um sie zu einer einzigen Kurve zu kombinieren.
  5. Wenn Buchstaben Löcher haben, schneiden Sie eine kleine Kerbe, indem Sie mit dem Rechteckwerkzeug ein Rechteck zeichnen und mit dem Werkzeug "Differenz" von der Kontur subtrahieren.
  6. Doppelklicken Sie auf den Pfad, um die Knoten anzuzeigen.
  7. Wählen Sie im Rechteck alle Knoten aus und klicken Sie auf das Werkzeug "Ausgewählte Knoten als Ecke erstellen".
  8. Speichern Sie die SVG-Datei.

Wichtig ist, dass Ihre Zeichnung einen einzigen geschlossenen Pfad und keine Löcher hat. Stellen Sie sicher, dass Ihr Design weniger als etwa 130 Punkte hat.

Schritt 5: Fügen Sie die Koordinaten aus der SVG-Datei in die Arduino IDE ein

  1. Öffnen Sie die SVG-Datei und kopieren Sie die Koordinaten. Diese werden in das "path"-Element eingebettet. Das erste Koordinatenpaar kann ignoriert werden; ersetze sie durch 0, 0.
  2. Fügen Sie die Koordinaten in die Arduino-Skizze innerhalb der Klammern direkt nach "#define USER_PATTERN" ein.
  3. Ersetzen Sie alle Leerzeichen durch Kommas, andernfalls erhalten Sie einen Kompilierungsfehler. Das Tool "Ersetzen & Suchen" kann hilfreich sein.
  4. Kompilieren und ausführen!
  5. Wenn Sie Probleme haben, überprüfen Sie die serielle Konsole auf Fehler. Insbesondere sehen Sie Meldungen, wenn Ihr Muster zu viele Punkte für den internen Puffer hat. In solchen Fällen weist das Bild übermäßiges Flimmern auf.

Schritt 6: Verstehen Sie, warum PWM so langsam ist

Betrachten wir zunächst das Verhalten eines Kondensators beim Aufladen.

Ein Kondensator, der mit einer Spannungsquelle Vcc verbunden ist, erhöht seine Spannung gemäß einer exponentiellen Kurve. Diese Kurve ist asymptotisch, dh sie verlangsamt sich, wenn sie sich der Zielspannung nähert. Für alle praktischen Zwecke ist die Spannung nach 5 RC-Sekunden "nah genug". Die RC wird als "Zeitkonstante" bezeichnet. Wie wir bereits gesehen haben, ist es das Produkt der Werte des Widerstands und des Kondensators in Ihrer Schaltung. Das Problem ist, dass 5 RC eine ziemlich lange Zeit ist, um jeden Punkt in einer Grafikanzeige zu aktualisieren. Dies führt zu viel Flackern!

Wenn wir Pulsweitenmodulation (PWM) verwenden, um einen Kondensator aufzuladen, sind wir nicht besser dran. Bei PWM wechselt die Spannung schnell zwischen 0V und 5V. In der Praxis bedeutet dies, dass wir schnell abwechselnd Ladung in den Kondensator schieben und ein wenig davon direkt wieder herausziehen – dieses Drücken und Ziehen ist eher so, als würde man versuchen, einen Marathon zu laufen, indem man einen großen Schritt nach vorne und dann einen kleinen Schritt zurück macht wieder und wieder.

Wenn Sie alles ausrechnen, ist das Verhalten beim Laden eines Kondensators mit PWM genau das gleiche, als ob Sie eine konstante Spannung von Vpwm zum Laden des Kondensators verwendet hätten. Es dauert immer noch etwa 5 RC-Sekunden, bis wir der gewünschten Spannung "nah genug" sind.

Schritt 7: Von a nach B kommen, ein bisschen schneller

Kommen Sie von a nach B, ein bisschen schneller
Kommen Sie von a nach B, ein bisschen schneller

Angenommen, wir haben einen Kondensator, der bereits auf Va aufgeladen ist. Angenommen, wir verwenden analogWrite(), um den neuen Wert von b auszuschreiben. Wie lange müssen Sie mindestens warten, bis die Spannung Vb erreicht ist?

Wenn Sie 5 RC-Sekunden erraten haben, ist das großartig! Durch Warten von 5 RC-Sekunden wird der Kondensator auf fast Vb aufgeladen. Aber wenn wir wollen, können wir tatsächlich ein bisschen weniger warten.

Schau dir die Ladekurve an. Sehen Sie, der Kondensator war bereits auf Va, als wir anfingen. Dies bedeutet, dass wir die Zeit t_a nicht warten müssen. Das müssten wir nur, wenn wir den Kondensator von Null aufladen würden.

Wenn wir also diese Zeit nicht warten, sehen wir eine Verbesserung. Die Zeit t_ab ist tatsächlich etwas kürzer als 5 RC.

Aber halten Sie durch, wir können so viel besser! Schauen Sie sich den ganzen Raum über v_b an. Das ist der Unterschied zwischen Vcc, der maximalen Spannung, die uns zur Verfügung steht, und dem Vb, das wir erreichen wollen. Können Sie sehen, wie diese zusätzliche Spannung uns helfen kann, viel schneller ans Ziel zu kommen?

Schritt 8: Mit einem Turbolader von A nach B kommen

Mit einem Turbolader von A nach B kommen!
Mit einem Turbolader von A nach B kommen!

Korrekt. Anstatt PWM bei der Zielspannung V_b zu verwenden, halten wir sie für einen viel, viel kürzeren Zeitraum auf einem konstanten Vcc. Ich nenne dies die Turbolader-Methode und sie bringt uns wirklich, sehr schnell ans Ziel! Nach der Zeitverzögerung (die wir berechnen müssen) bremsen wir, indem wir bei V_b auf PWM umschalten. Dadurch wird verhindert, dass die Spannung über das Ziel hinausschießt.

Mit diesem Verfahren ist es möglich, die Spannung im Kondensator von V_a auf V_b in einem Bruchteil der Zeit zu ändern, als wenn nur PWM verwendet wird. So bekommst du Plätze, Baby!

Schritt 9: Verstehen Sie den Code

Den Kodex verstehen
Den Kodex verstehen

Ein Bild sagt mehr als tausend Worte, daher zeigt das Diagramm die Daten und die Operationen, die im Code ausgeführt werden. Von links nach rechts:

  • Die Grafikdaten werden in PROGMEM (d. h. im Flash-Speicher) als Punktliste gespeichert.
  • Jede Kombination von Translations-, Skalierungs- und Rotationsoperationen wird zu einer affinen Transformationsmatrix kombiniert. Dies erfolgt einmal zu Beginn jedes Animationsframes.
  • Punkte werden einzeln aus Grafikdaten gelesen und jeweils mit der gespeicherten Transformationsmatrix multipliziert.
  • Die transformierten Punkte werden einem Scherenalgorithmus zugeführt, der alle Punkte außerhalb des sichtbaren Bereichs beschneidet.
  • Unter Verwendung einer RC-Verzögerungs-Nachschlagetabelle werden die Punkte in Ansteuerspannungen und Zeitverzögerungen umgewandelt. Die RC-Verzögerungs-Nachschlagetabelle wird im EEPROM gespeichert und kann für mehrere Durchläufe des Codes wiederverwendet werden. Beim Start wird die RC-Nachschlagetabelle auf Genauigkeit überprüft und alle falschen Werte werden aktualisiert. Die Verwendung von EEPROM spart wertvollen RAM-Speicher.
  • Die Treiberspannungen und Verzögerungen werden in den inaktiven Rahmen im Rahmenpuffer geschrieben. Der Rahmenpuffer enthält Platz für einen aktiven Rahmen und einen inaktiven Rahmen. Sobald ein vollständiger Rahmen geschrieben ist, wird der inaktive Rahmen aktiv gemacht.
  • Eine Interrupt-Service-Routine zeichnet das Bild ständig neu, indem sie Spannungswerte und Verzögerungen aus dem aktiven Bildpuffer liest. Basierend auf diesen Werten werden die Tastverhältnisse der Ausgangspins angepasst. Timer 1 wird verwendet, um die Zeitverzögerung mit einer Genauigkeit von wenigen Nanosekunden zu messen, während Timer 2 zum Steuern des Tastverhältnisses von Pins verwendet wird.
  • Der Pin mit der größten Spannungsänderung wird immer mit einem Tastverhältnis von null oder 100 % "turbogeladen" und bietet so die schnellste Lade- oder Entladezeit. Der Pin mit einer geringeren Spannungsänderung wird mit einem Tastverhältnis angesteuert, das so gewählt ist, dass es der Übergangszeit des ersten Pins entspricht. Diese Zeitanpassung ist wichtig, um sicherzustellen, dass Linien auf dem Oszilloskop gerade gezeichnet werden.

Schritt 10: Mit großer Geschwindigkeit kommt große Verantwortung

Da diese Methode so viel schneller als PWM ist, warum verwendet analogWrite() sie nicht? Nun, weil die Verwendung von PWM für die meisten Programme gut genug ist und viel fehlerverzeihender ist. Die Methode „Turbo Charger“erfordert jedoch eine sorgfältige Codierung und ist nur für spezielle Fälle geeignet:

  1. Es ist extrem zeitempfindlich. Sobald wir den Zielspannungspegel erreicht haben, muss der Ansteuerpin sofort in den regulären PWM-Modus geschaltet werden, um ein Überschwingen der Zielspannung zu vermeiden.
  2. Es erfordert die Kenntnis der RC-Konstante, daher müssen diese Werte vorher eingegeben werden. Bei falschen Werten ist das Timing falsch und die Spannungen sind falsch. Bei normaler PWM ist garantiert, dass Sie sich nach einiger Zeit auf die richtige Spannung einpendeln, auch wenn die RC-Konstante nicht bekannt ist.
  3. Die Berechnung des genauen Zeitintervalls zum Laden des Kondensators erfordert logarithmische Gleichungen, die für die Echtzeitberechnung auf dem Arduino zu langsam sind. Diese müssen vor jedem Animationsframe im Voraus berechnet und irgendwo im Speicher zwischengespeichert werden.
  4. Programme, die sich mit dieser Methode befassen, müssen mit der Tatsache fertig werden, dass die Verzögerungen sehr nichtlinear sind (sie sind tatsächlich exponentiell). Zielspannungen in der Nähe von Vcc oder GND werden viele Größenordnungen länger brauchen als Spannungen in der Nähe des Mittelpunkts.

Um diese Einschränkungen zu überwinden, macht mein Vektorgrafik-Code die folgenden Dinge:

  1. Es verwendet Timer 1 bei 16 kHz und eine Interrupt-Service-Routine für präzise Ausgabemanipulation und Timing.
  2. Es erfordert die Verwendung eines bestimmten Wertes der RC-Zeitkonstante, was die Auswahl der Kondensator- und Widerstandswerte einschränkt.
  3. Es speichert die Zeitverzögerungen für alle Punkte in einem Animationsframe in einem Speicherpuffer. Dies bedeutet, dass die Routine, die die Zeitverzögerungen berechnet, viel langsamer läuft als die Interrupt-Service-Routine, die die Ausgangspins aktualisiert. Jeder gegebene Rahmen kann mehrere Dutzend Mal gemalt werden, bevor ein neuer Satz von Verzögerungen für den nächsten Rahmen verwendet werden kann.
  4. Die Verwendung eines Speicherpuffers schränkt die Anzahl der Punkte ein, die pro Rahmen gezeichnet werden können. Ich verwende eine platzsparende Kodierung, um das Beste aus dem verfügbaren RAM herauszuholen, aber sie ist immer noch auf etwa 150 Punkte begrenzt. Über hundert oder so Punkten hinaus würde das Display sowieso anfangen zu flackern, also ist es ein strittiger Punkt!

Empfohlen: