Die Rede ist von PWM – Pulsweitenmodulation. Dieses Thema mag kompliziert klingen, aber ein paar praktische Beispiele werden sicher alle Zweifel ausräumen!
Was ist ein PWM-Signal?
Angenommen, wir schließen eine Leuchtdiode an den Mikrocontroller an und lassen sie in einer Schleife blinken. Die Diode ist eine Sekunde lang an und bleibt eine Sekunde lang aus, und so weiter:
void setup() {
pinMode(3, OUTPUT); //Konfiguration von Pin 3 als Ausgang
}
void loop() {
digitalWrite(3, HIGH); //Diode einschalten
delay(1000); //1 Sekunde warten
digitalWrite(3, LOW); //Diode ausschalten
delay(1000);
}
Wenn wir ein Diagramm der Spannungsänderung (über die Zeit) an Pin drei des Arduino zeichnen würden, erhielten wir eine rechteckige Wellenform:
Der mit x gekennzeichnete Wert ist die Zeit, zu der die LED leuchtet. T hingegen ist die Periode, in der die LED blinkt. Der Kehrwert 1/T wiederum steht für die Frequenz. Das Verhältnis zwischen der Zeit, in der die LED leuchtet, und der Zeit, in der sie nicht leuchtet, beträgt 1:1, d. h. sie bleibt nur während 50 % des Programms an. In der Fachsprache wird dieser Parameter als Signalfüllung bezeichnet.
Zusammenfassung der Informationen über unser Signal:
- Amplitude (Höchstwert): 5V
- Signalperiode: 2 Sekunden
- Signalfrequenz: 1/2 = 0,5 Hz
- Signalfüllung: 50%
Nun ist es Zeit für ein ähnliches Experiment. Allerdings mit einer veränderten Füllung, wobei die vorherige Periode beibehalten wird. Wie macht man das? Man erhöht einfach die Zeit, in der die Diode eingeschaltet ist, während man die Zeit, in der sie ausgeschaltet ist, verkürzt. Zum Beispiel:
void setup() {
pinMode(3, OUTPUT); //Konfiguration von Pin 3 als Ausgang
}
void loop() {
digitalWrite(3, HIGH); //Diode einschalten
delay(1667);
digitalWrite(3, LOW); //Diode ausschalten
delay(333);
}
Diesmal ist die Diode etwa 5/6 der Zeit eingeschaltet. Das heißt, die Füllung beträgt etwa 83 %. Stellt man die Situation in einem Diagramm analog zum vorherigen dar, erhält man:
Wenn wir die Verzögerungen umstellen, erhalten wir die umgekehrte Situation, d. h. ein Signal mit einer Füllung von 17 %. Letzte Grafik:
Schau dir die obigen Beispiele noch einmal an. Welcher Parameter hat sich jedes Mal geändert? Die Antwort ist einfach: die Füllung. Die Frequenz der Wellenformen blieb gleich.
In praktischer Sprache ausgedrückt, änderte sich nur der „Prozentsatz der Zeit, in der das Signal ein hohes Potenzial aufweist“.
Glückwunsch! Ihr habt soeben das Prinzip von PWM in der Praxis verstanden. Das heißt, die Methode der Modulation eines Rechtecksignals durch Anpassung der Pulsbreite.
Wahrscheinlich denkst du dir jetzt: Toll, aber wozu braucht man das?
Wenn dieses Ein- und Ausschalten viel schneller erfolgt, können wir den beschriebenen Effekt auch mit scheinbar sehr „schnellen“ Bauteilen – Leuchtdioden – nutzen.
Das vom Arduino erzeugte PWM-Signal schaltet im Allgemeinen 490/Sekunde.
Welchen Verwendungszweck hat das PWM-Signal?
Nun, in der Digitaltechnik wird dieses Signal sehr häufig verwendet. Mit ihm kann man die Helligkeit der LED, die Position des Servos und die Geschwindigkeit, mit der sich der Motor dreht, steuern! Wie du deutlich sehen kannst, gibt es viele Anwendungen sowohl in der Amateur-Robotik als auch in jedem anderen Heimwerkerbereich.
Steuerung der Helligkeit von LEDs
Der Arduino ist mit 6 Hardware-PWM-Kanälen ausgestattet. Jeder Ausgang, an dem wir ein PWM-Signal erhalten können, ist auf der Platine mit einem Tilde-Zeichen „~“ gekennzeichnet, und auf unserer Grafik erschien zusätzlich daneben der Hinweis PWM:
Hardware-generierte PWM bedeutet, dass die Erzeugung dieses Signals den Betrieb des Programms nicht beeinträchtigt (es wird nicht verzögert). Außerdem brauchen wir die Funktionen zur Erzeugung eines solchen Signals nicht selbst zu schreiben.
Für die erste Übung ist es notwendig, eine Diode an Pin 3 anzuschließen. Es sollte kein Problem mehr sein, die Schaltung selbst zusammenzubauen:
Es ist an der Zeit, ein Programm zu erstellen. Unser Ziel ist es, ein paar Zeilen zu schreiben, mit denen die Diode langsam blinken wird. Mit anderen Worten, wir werden in einer Schleife die Füllung des PWM-Signals variieren, mit dem die Diode gesteuert wird.
#define diodePIN 3
int Füllung = 0;
int Änderung = 5;
void setup() {
pinMode(diodaPIN, OUTPUT);//Konfiguration des Pins als Ausgang
}
void loop() {
analogWrite(DiodePIN, Füllung); //Wir erzeugen ein Signal mit einer bestimmten Füllung
if (Füllung < 255) { //Wenn die Füllung weniger als 100% beträgt
Füllung = Füllung + Änderung; //Wir erhöhen die Füllung
} else {
Füllung = 0; //Wenn die Füllung größer als 100% ist, kehren wir zum Anfang zurück
}
delay(50); //Kleine Verzögerung, um den Effekt sichtbar zu machen
}
Die Aufgabe des obigen Programms ist es, die Füllung zyklisch von Null zu erhöhen, bis ihr Wert kleiner als 255 (100%) ist. Wenn die maximale Füllung erreicht ist, wird die Diode ausgeschaltet (Füllung 0 %) und der Prozess des Aufleuchtens der Diode wird fortgesetzt.
Hausaufgabe 5.1
Versuche, das obige Programm so zu vereinfachen, dass du die bedingte if-Anweisung nicht verwenden musst. Tipp: Überlege, wie sich die Art der Variablen Füllung auf das Programm auswirkt.
Hausaufgabe 5.2
Schreibe ein Programm, das bei einer Erhöhung der Füllung auf 255 beginnt, sie allmählich auf Null zu verringern (und so weiter im Kreis). Prüfe, bei welcher Verzögerung in jedem Schleifenzyklus der beobachtete pulsierende Effekt am interessantesten sein wird.
Zeit für den Einsatz des Servos!
Wahrscheinlich hat mehr als ein Leser auf den Moment gewartet, in dem wir ein Servo besprechen und in der Praxis einsetzen. Wenn du noch nicht genau weißt, wovon ich spreche, such dir ein Bauteil in deinem Set, das mit dem unten abgebildeten identisch (oder ähnlich) ist:
Es handelt sich um ein Mikro-Servo, das zu den kleinsten auf dem Markt erhältlichen gehört. Seine Größe hat jedoch keinen Einfluss auf die Art und Weise, wie es gesteuert wird. Sobald du das Funktionsprinzip verstanden hast, wirst du in der Lage sein, größere, stärkere und schnellere Servos in deinen Projekten zu verwenden.
Was ist ein Servomotor?
Ein Servoantrieb besteht aus einem Motor, einem Getriebe und einer speziellen Steuerung, die in einem einzigen Gehäuse untergebracht sind. Diese Antriebe sind jedoch nicht für eine vollständige Drehung ausgelegt. Die meisten Servos können den montierten Arm um einen Winkel von 0-180º bewegen. Wichtig ist, dass sie ihre aktuelle Position kennen, so dass wir uns z. B. keine Sorgen über zunehmende Positionsfehler machen müssen.
Die zwei wichtigsten Regeln für den Einsatz von Servos:
- Die Wellenposition darf nicht ohne Notwendigkeit von Hand gedreht werden. Dies kann die relativ empfindlichen Kunststoffzahnräder, aus denen die Getriebe bestehen, beschädigen.
- Versorge die Servos nicht direkt mit der Stromquelle, mit der auch der Rest des Systems versorgt wird. Jeder Motor zieht einen relativ hohen Strom. Dies gilt insbesondere zu Beginn einer Bewegung. Dies kann das übrige System stören und im Extremfall sogar beschädigen.
Wie funktioniert ein Servo?
Die Füllung des erzeugten Signals sollte innerhalb von 5-10% liegen. Diese Werte werden in die beiden Endpositionen des Servos (maximal links und maximal rechts) umgerechnet.
- Masse (schwarz, dunkelbraun)
- Spannungsversorgung (rot)
- Steuersignal (gelb/orange)
Stromversorgung des Servos
Wie bereits erwähnt, sollte der Servomotor nicht direkt von der gleichen Spannung versorgt werden, die auch den Mikrocontroller versorgt. Zweitens müssen wir, da der Motor viel Strom ziehen kann, eine geeignete, effiziente Quelle an die Schaltung anschließen.
Leider könnte sich der USB-Anschluss, über den wir unser Board bisher mit Strom versorgt haben, als zu schwach erweisen!
Daher werden wir den Arduino zum ersten Mal über die mitgelieferte 9-V-Batterie mit einer Klemme mit Strom versorgen, die mit einem Stecker abgeschlossen ist, der in die Strombuchse am Arduino passt. Der genaue Schaltplan ist unten zu finden.
Servomechanismus in der Praxis
Es ist Zeit für das erste Programm zur Bewegung des Servoarms. Hierzu muss die Schaltung gemäß dem untenstehenden Schaltplan angeschlossen werden. Zuerst ist es notwendig, die Batterie anzuschließen. Als zweites müssen wir den Stabilisator LM7805 verwenden.
Wir verbinden den Eingang des Stabilisators mit dem Vin-Pin des Arduino, die Masse mit GND, und schließen das rote Kabel des Servos an den Ausgang an. Natürlich sind auch Kondensatoren zum Filtern notwendig. Die restlichen Anschlüsse sollten bereits klar sein:
Es ist Zeit für ein Programm, das den Servo schrittweise bewegt. Zu Beginn das fertige Programm, eine Erklärung findest du unten:
#include //Bibliothek zuständig für Servos
Servo servomechanismus; //Wir erstellen ein Objekt über das wir uns auf das Servo beziehen können
int Position = 0; //Aktuelle Servo-Position 0-180
int Änderung = 6; //Wie oft soll sich die Servoposition ändern?
void setup()
{
servomechanism.attach(9); //Servomechanismus angeschlossen an Pin 9
}
void loop()
{
if (Position < 180) { //Wenn die Position innerhalb des Bereichs liegt
servomechanism.write(Position); //Bewegung ausführen
} else { //Wenn nicht, zurück zum Start
Position = 0;
}
Position = Position + Änderung; //Aktuelle Servoposition erhöhen
delay(200); //Verzögerung für besseren Effekt
}
Dieses Mal müssen wir eine neue Bibliothek hinzufügen, die die Möglichkeiten unseres Programms um unsere Funktionen erweitert. Dies geschieht mit dem Befehl:
#include Servo.h
Wenn wir den Servo steuern wollen, müssen wir ein Objekt für ihn erstellen:
Servo servomechanismus;
Wenn das Programm gestartet wird, sollte sich das Servo sanft von einer Endposition zur anderen und dann wieder zurück zum Anfang bewegen. Die Schlüsselzeile ist:
servomechanism.write(Position);
Hier müssen wir einen Winkel von 0-180º als Position eingeben.
Hausaufgabe 5.3
Schreibe auf der Grundlage des obigen Programms ein eigenes, das jeden aufeinanderfolgenden Sprung zu einer neuen Position nach einer längeren Zeit (200ms, 250ms, usw.) durchführt.
Hausaufgabe 5.4
Hausaufgabe 5.5
Achtung, den Motor nicht selbst anschließen!
In diesem Teil des Kurses haben wir einen Servomotor direkt an den Arduino angeschlossen. Dies war möglich, weil diese Antriebe interne Controller haben, die den Betrieb des bloßen Motors steuern.
Daher wird dem Arduino-Pin, der die Bewegung des Servos steuert, nicht viel Strom entnommen.
Um den Motor direkt anzuschließen, ist eine Zwischenschaltung, bridge-h, erforderlich! Mehr Informationen dazu findest du später in diesem Kurs.
Zusammenfassung
Im nächsten zusätzlichen Teil werden wir einige nützliche Tricks im Zusammenhang mit der Übertragung über UART behandeln. Ich werde auch zeigen, wie ein Servo in der Praxis als analoger Zeiger verwendet werden kann und demonstrieren, wie man den Arduino und den L293D-Chip zur Steuerung eines Gleichstrommotors verwendet!