Servo langsam bewegen

mit millis()


Im Projekt #4.2 Servo langsam bewegen haben wir es geschafft, den Servo nicht Ruckartig auf eine Position zu bewegen, sondern langsam seine neue Position anzufahren. 

Nun haben wir dort die Funktion Delay() verwendet. Nachteil an dieser Funktion: das ganze Program stoppt für die vorgegebene Zeit.

Es werden keine weiteren Taster ausgewertet noch kann solange eine weitere Funktion ausgeführt werden.

Die Lösung: millis()

Das Funktionsprinzip

Im Arduino läuft ein Timer dauerhaft mit. Anstatt einen delay() zu programmieren, speichert man sich den Wert des Timers ab und vergleicht diese mit sich selbst + die Zeit die verstreichen soll. 

Beispiel

Eine LED soll jede Sekunde ihren Status ändern.

An - Aus - An - Aus - An - Aus ....

 

Denn wird die LED eingeschaltet und der aktuelle Wert des Timers gespeichert.

-> LEDprevMil = millis() // sagen wir Lillis hat den Wert 9563

Dann vergleichen wir in jedem Durchlauf den aktuellen Wert mit gespeicherten + Zeit X

-> if(millis() > LEDprevMil + 1000) 

Wenn das der fall ist, können wir den Status ändern.

 



Servo Bewegen

Dieses Prinzip können wir uns jetzt zu Nutze machen, wenn wir den Servo all X Millisekunden 1 Grad weiter Takten möchten.


Zunächst brauchen wir wieder die Servo Library und ein paar Variablen auf die wir Wert schreiben und speichern können.

Wir müssen der Servo benennen, den Pin bekannt machen, eine Variable für die Ausgangsposition und eine für die Zielposition anlegen, eine für die Millisekunden die zwischen jedem Schritt verstreichen sollen, und eine in der wir den Wert des Timers festhalten.

#include <Servo.h>

//Servo 1 Variablen
Servo Tor1;
const int Tor1Pin = 9;
int Tor1Pos = 0;
int Tor1Sollpos = 0;
const long Tor1Speed = 100;
unsigned long Tor1PreMillis = 0;

Zusätzlich wollen wir den Servo über 2 Taster steuern und auch dazu legen wir die entsprechenden Variablen an.

//Taster Variablen
const int Tor1_T1 = 4;
const int Tor1_T2 = 5;

Im Setup Bereich definieren wir dann unsere Pins nach ihren Funktionen.

void setup() {
//Taster Setup
pinMode(Tor1_T1, INPUT_PULLUP);
pinMode(Tor1_T2, INPUT_PULLUP);
//Servo Setup
Tor1.attach(Tor1Pin);
Tor2.attach(Tor1Pin);
}

Und dann gehts los.

Zunächst speichern wir uns den aktuellen Wert unseres Timer.

Dann prüfen wir ob ein Taster gedrückt wurde, und legen ggf. eine neue Sollposition fest.

Entspricht die Ist- nicht der Sollposition aktivieren wir den Servo. Dann prüfen wir nach dem oben erklärten Muster, ob die letzte Bewegung lang genug her ist, um eine neue Bewegung anzustoßen.

Wenn ja geht es ein Schritt in die entsprechende Richtung.

Erreicht der Servo die Sollposition wird der Servo wieder deaktiviert.

void loop() {
unsigned long currentMillis = millis();
//Servo 1 --------------------------------
if (digitalRead(Tor1_T1) == LOW) {
Tor1Sollpos = 90;
}
if (digitalRead(Tor1_T2) == LOW) {
Tor1Sollpos = 0;
}
if (Tor1Pos != Tor1Sollpos) {
Tor1.attach(Tor1Pin);
if (currentMillis - Tor1PreMillis >= Tor1Speed){
Tor1PreMillis = currentMillis;
if (Tor1Pos < Tor1Sollpos) {
Tor1Pos = Tor1Pos + 1;
Tor1.write (Tor1Pos);
}
if (Tor1Pos > Tor1Sollpos) {
Tor1Pos = Tor1Pos - 1;
Tor1.write (Tor1Pos);
}
}
} else {
Tor1.detach();
}
}

Wird nun z.B. wieder eine taste gedrückt, wird der Tastendruck sofort ausgewertet und der Servo dreht bei Bedarf um. 

Zusätzlich könnte auch ein Blinklicht integriert werden. Wie das geht zeige ich unter Anderem in meinem YouTube Video.



Zwei Servos bewegen

Um nach diesem Prinzip zwei Servos mit einem Arduino zu bewegen, Müssen wir zunächst alle Variablen doppelt anlegen.

 

//Servo 2 Variablen
Servo Tor2;
const int Tor2Pin = 10;
int Tor2Pos = 0;
int Tor2Sollpos = 0;
const long Tor2Speed = 100;
unsigned long Tor2PreMillis = 0;

//Taster Variablen
const int Tor1_T1 = 4;
const int Tor1_T2 = 5;
const int Tor2_T1 = 6;
const int Tor2_T2 = 7;

Die Pins natürlich im Setup Bereich wieder ihrer Funktion zuordnen.

void setup() {
//Taster Setup
pinMode(Tor1_T1, INPUT_PULLUP);
pinMode(Tor1_T2, INPUT_PULLUP);
pinMode(Tor2_T1, INPUT_PULLUP);
pinMode(Tor2_T2, INPUT_PULLUP);
//Servo Setup
Tor1.attach(Tor1Pin);
Tor2.attach(Tor1Pin);
}

Und im Loop den zweiten Servo mit den entsprechenden Variablen einfügen.

//Servo 2 --------------------------------
if (digitalRead(Tor2_T1) == LOW) {
Tor2Sollpos = 90;
}
if (digitalRead(Tor2_T2) == LOW) {
Tor2Sollpos = 0;
}
if (Tor2Pos != Tor2Sollpos) {
Tor2.attach(Tor2Pin);
if (currentMillis - Tor2PreMillis >= Tor2Speed){
Tor2PreMillis = currentMillis;
if (Tor2Pos < Tor2Sollpos) {
Tor2Pos = Tor2Pos + 1;
Tor2.write (Tor2Pos);
}
if (Tor2Pos > Tor2Sollpos) {
Tor2Pos = Tor2Pos - 1;
Tor2.write (Tor2Pos);
}
}
} else {
Tor2.detach();
}

Download
Layout und Sketch als PDF
Layout_Sketch.pdf
Adobe Acrobat Dokument 50.1 KB