ich bin noch ein anfänger, und möchte gerne zwei servos steuern. ich habe mir dazu den sweep code geladen, und ihn ein bisschen umgeschrieben. :
// Controlling a servo position using a potentiometer (variable resistor)
// by Michal Rinott
der code soll servo 1 (s1) langsam hin und zurück drehen und dabei servo2(s2) um 90 grad hin und her drehen. dies sollte gleichzeitig passieren. allerdings dreht sich s1 hin und zurrück und dann s2 hin und zurück. wie kann man dacs gleichzeitig machen?
Einfach alles in eine for Schleife Prg. Ansonsten wird jede Schritt nacheinander abgearbeitet. IMHO ist Loop bzw. Delay keine multithreading Möglichkeit.
du musst deine Delay Rausschmeissen und dann deine Aktionen mit den millis ausführen wie in dem Beispiel Blink without delay.
Damit kann die Loop weiterlaufen und deine Sachen laufen quasi gleich.
Ich möchte den Satz "Delay keine multithreading Möglichkeit." von Peacekeeper nochmal aufgreifen und besser erklären:
Die Funktion delay() hält den Probrammablauf für die eingestellte Zeit an; es werden keine anderen Sachen gemacht. Darum ist delay() bzw delayMicroseconds() in den Programmen meist zu vermeiden. Als Alternative, wie volvodani voschlägt, ist Milli() zu nehmen. Diese Funktion gibt die Zeit in Milisekunden ab Einschalten im Variablentyp unsigned long zurück und um etwas nach einer gewissen Zeit zu machen, kontrolliert man, ob die Zeit um diesen Betrag größer geworden ist. Die Variable läuft nach ca 50 Tagen über, weil der Zahlenwert größer geworden ist als mit unsignet long darstellbar ist und fängt wieder bei null an.
Als Beispiel Blinkwithoutdelay im IDE unter den Beispielen (File, Examples, Digital) oder im Tutorial http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
da ja offensichtlich das Problem noch nicht "codemäßig" gelöst wurde, habe ich mich mal daran versucht. Allerdings komme ich nun auch nicht mehr weiter..
Zum Problem in meinem Beispiel:
2 Servos (myservo1, myservo2)
myservo1 soll von Schritt 0 bis 50 "hochlaufen", dann wieder bis auf 0 "runterlaufen" und so weiter..
myservo2 soll mittels Poti gesteuert werden.
Funktioniert soweit auch, nur dass ich eben nicht weiß wie ich von 50 wieder auf 0 kommen soll.. Habe es auch schon mit "for" und "do" - Schleife probiert, hat dann auch funktioniert, allerdings bleibt das Programm ja dann in der Schleife "hängen" und kann dann myservo2 nicht mehr bedienen..
hier mal der Code (aus den "Examples", leicht abgeändert):
#include <Servo.h>
Servo myservo1;
Servo myservo2;
int pos = 0;
int potpin = 0;
int val;
long previousMillis = 0;
long intervall = 100;
void setup()
{
myservo1.attach(9);
myservo2.attach(10);
}
void loop()
{
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > intervall){
previousMillis = currentMillis;
myservo1.write(pos);
pos=pos+1;
if(pos == 50){ // ab hier wird's knifflig ;-)
pos=pos-1; // ???
???
myservo1.write(pos);
}
}
val = analogRead(potpin);
val = map(val, 0, 1023, 0, 179);
myservo2.write(val);
}
der code soll servo 1 (s1) langsam hin und zurück drehen und dabei servo2(s2) um 90 grad hin und her drehen. dies sollte gleichzeitig passieren. allerdings dreht sich s1 hin und zurrück und dann s2 hin und zurück. wie kann man das gleichzeitig machen?
hmm.. ok.. ist jetzt nicht ganz das was ich mir erwünscht hatte, da ich ja servo2 mit dem poti steuern wollte, aber trotzdem Danke mal..
wie auch immer bin jetzt aber auf ne "einigermaßen" akzeptable Lösung gekommen.. hab den code für servo2 einfach jeweils in die for-Schleife kopiert und siehe da es funktioniert! Leider nicht optimal, da ich durch die Verzögerung (delay(15)) den servo nicht mit voller Geschwindigkeit steuern kann..
hier noch der code, falls es jm. interessiert:
#include <Servo.h>
Servo myservo1;
Servo myservo2;
int pos = 0;
int potpin = 0;
int val;
void setup()
{
myservo1.attach(9);
myservo2.attach(10);
}
void loop()
{
for(pos = 0; pos < 180; pos += 1)
{
myservo1.write(pos);
val = analogRead(potpin);
val = map(val, 0, 1023, 0, 179);
myservo2.write(val);
delay(15);
}
for(pos = 180; pos>=1; pos-=1)
{
myservo1.write(pos);
val = analogRead(potpin);
val = map(val, 0, 1023, 0, 179);
myservo2.write(val);
delay(15);
}
}
Sollte jm. noch auf eine "elegantere" Lösung bzw. eine in der millis() oder sonst eine Funktion ohne delay vorkommt kommen, gerne her damit!
Wieso ist die Bedingung für die Schleife immer wahr ?
** milli1 = millis();**
milli2 = milli1;
while (milli2 - milli1 <= 15)
{
val = analogRead(potpin);
val = map(val, 0, 1023, 0, 179);
myservo2.write(val);
** milli2 = millis();**
}
Der Wert von milli2 ändert sich bei jedem Schleifendurchgang, wodurch die Bedingung (milli2 - milli1 <= 15) irgentwann nicht mehr erfüllt sein wird ! Jedoch ist sichergestellt das milli2 - milli1 vor dem Eintritt in die Schleife auf jeden Fall NULL ergibt !
milli2 - milli1:
5 - 5 = 0 Beim Eintritt in die Schleife
10 - 5 = 5
15 - 5 = 10
20 - 5 = 15
5 25 - 5 = 20 Schleife wird nicht mehr durchlaufen !
Das Konstrukt mit while und for Schleifen ist nicht gerade optimal.
Es funktioniert zwar für den momentan geplanten Zweck, aber sobald das Programm erweitert werden soll (z.B. Taster oder Sensor abfragen) gehen die Probleme wieder los.