rookie benötigt hilfe mit arduino + 6 servos

Hallo zusammen!

Für ein schul-projekt benötige ich fix eine hilfe von euch, ich komm leider selbst nicht auf die lösung ( und dazu ein blutiger anfänger).

folgendes setup:

ich hab ein arduino uno und 6 mini-servos. ich möchte, dass sich die servos langsam von 0° nach 45° grad bewegen, dann wieder zurück nach 0° und -45° ( sprich, einmal "hochkippen", danach "runterkippen" - immer 45°).

Jedoch sollen alle servos nicht zeitgleich starten ( und sich bewegen), sondern jeweils um z.b 3 sekunden versetzt. also sprich, servo1 startet (3sec delay) servo2 beginnt sich zu bewegen (3sec delay)... usw.

Leider bekomme ich das selbst nicht zum laufen. ich hab mir das sweep example bei der servo lib angeschaut, bekomme das aber nicht für meinen zweck umgeschrieben.

könntet ihr mir bitte aushelfen, bis freitag muss ich das teil irgendwie zum laufen bekommen :o

1000 dank schonmal vorab, chris

dass sich die servos langsam von 0° nach 45° grad bewegen

wieviel Zeit soll ein Servo für die 45° benötigen?

Sag deinem Lehrer, das das man das in 2 Tagen nicht lernen kann. Das geht nur, wenn jemand den Code für dich schreibt. Und das kann ja wohl nicht der Sinn eines Projektes sein.

ardubu:
wieviel Zeit soll ein Servo für die 45° benötigen?

als ich versucht hab, dass mit dem sweep example zum laufen zu bekommen, war ein delay(70) ideal von der zeit.

void loop() {
for (pos = 0; pos <= 45; pos += 1) {
// in steps of 1 degree
myservo.write(pos);
delay(70);
}
for (pos = 45; pos >= 0; pos -= 1) {
myservo.write(pos);
delay(70);
}

ElEspanol: Sag deinem Lehrer, das das man das in 2 Tagen nicht lernen kann. Das geht nur, wenn jemand den Code für dich schreibt. Und das kann ja wohl nicht der Sinn eines Projektes sein.

das projekt hat nichts mit arduino zu tun, wir würden das nur gern als tool nutzen :)

Dann habt ihr euch viel vorgenommen. aber jurs wird euch vielleicht schon was auf die Schnelle zusammen zimmern :wink:

mit dem Delay von 70 hast du ja etwa 3 sec.
wenn dein Arduino sonst nichts anderes erledigen muß, brauchst du den Sketch doch nur fortsetzen.

void setup() {
  myservo_1.attach(2);
  myservo_2.attach(3);
  myservo_3.attach(4);

}

void loop() {
  for (pos = 0; pos <= 45; pos += 1) {
    // in steps of 1 degree
    myservo_1.write(pos);             
    delay(70);                       
  }
  for (pos = 0; pos <= 45; pos += 1) {
    // in steps of 1 degree
    myservo_2.write(pos);             
    delay(70);                       
  }
  for (pos = 0; pos <= 45; pos += 1) {
    // in steps of 1 degree
    myservo_3.write(pos);             
    delay(70);                       
  }
  for (pos = 45; pos >= 0; pos -= 1) {
    myservo_1.write(pos);             
    delay(70);                     
  }
  for (pos = 45; pos >= 0; pos -= 1) {
    myservo_2.write(pos);             
    delay(70);                     
  }
  for (pos = 45; pos >= 0; pos -= 1) {
    myservo_3.write(pos);             
    delay(70);                     
  }
}

die Servos sollen sich doch gleichzeitig bewegen, nur der Start ist um 3 Sekunden versetzt. Da darf kein delay im Sketch sein. Und in einer Schleife gleich zweimal nicht

ElEspanol: die Servos sollen sich doch gleichzeitig bewegen, nur der Start ist um 3 Sekunden versetzt. Da darf kein delay im Sketch sein. Und in einer Schleife gleich zweimal nicht

exakt, genau das ist dar problem :/

Das nennt man blockierungsfreies Programmieren, die Lösung ist einfach, wenn man weiß wie es geht.

Bin gerade nicht am PC, aber es wird sich schon noch jemand finden.

ich hab ne lösung gefunden! wenn ich mein kram fertig hab, stell ich's für die nachwelt hier rein :)

Der grobe Weg ist kein delay() zu verwenden und das Timing mit millis() und Zeit merken zu machen. Dann die for-Schleifen auflösen und das mit if-Abfragen erledigen. So dass man wenn für einen Motor gerade nichts zu tun ist, was anderes machen kann.

versuch es mal in der Art

#include <Servo.h> 
 
Servo myservo_1;  // create servo object to control a servo 
Servo myservo_2;  // twelve servo objects can be created on most boards
Servo myservo_3;
Servo myservo_4;
Servo myservo_5;
Servo myservo_6;
 
byte pos = 0;    // variable to store the servo position 
void setup() {
  myservo_1.attach(2);
  myservo_2.attach(3);
  myservo_3.attach(4);

}

void loop()
{
servo_1();
}
  
  void servo_1()
  {
  // in steps of 1 degree
  static unsigned long millis_alt;// Zeit merken       
   // millis() ist die aktuelle Zeit
  const int interval = 70;// Zeit zwischen an und aus     const bedeutet das es sich um eine Konstante handelt     
  
   if(millis() - millis_alt > interval)
     {
       if (pos < 46)
          {pos++;
           millis_alt = millis();   
           myservo_1.write(pos);             
          }
          else if (pos >0)
                  {pos--;
                   millis_alt = millis();   
                   myservo_1.write(pos);             
                  }        
      }
  }

ah mist, meine lösung klappt doch nich.

also im grunde müsste das ja irgendwie so sein:

arduino bekommt strom / ON:

0 sekunde: servo 1 geht an, wandert innerhalb von x-sekunden zu 45°, danach zu -45° und läuft danach kontinuierlich weiter ( wackelt)

3 sekunde: servo 2 geht an, wandert innerhalb.....

6 sekunde: servo 3 geht an .... . . . sobald alle zeitversetzt gestartet haben, laufen sie einfach die ganze zeit durch, bis ich den strom wieder ausschalte.

eine andere option/möglichkeit für uns wär auch, wenn das arduino startet, die 6 servos zuerst zu

s1 = 2° s2 = 4° s3 = 6° . . . wandern, haben alle ihre "start-grandzahl" erreicht, "wackeln" sie kontinuierlich & simultan, das wurde ja quasi den selben effekt haben, wie wenn ich sie mit einer verzögerung starten würde.

Du solltest sie beim starten in der setup Routine auf 0° stellen und dann (und nur hier!!!) mit delay warten, bis die Servos angekommen sind.

Danach startest du versetzt die Servos, ardubu hat ja die meiste Arbeit schon gemacht.

ich hatte noch einen kleinen Fehler im Sketch, der hier raus ist, außerdem habe ich es für 3 Servos erweitert, den Rest wirst du selber hin bekommen

#include <Servo.h> 
 
Servo myservo_1;  // create servo object to control a servo 
Servo myservo_2;  // twelve servo objects can be created on most boards
Servo myservo_3;
Servo myservo_4;
Servo myservo_5;
Servo myservo_6;
 

unsigned long millis_alt_start=millis();

void setup() {
  Serial.begin(9600);
  myservo_1.attach(14);
  myservo_2.attach(3);
  myservo_3.attach(4);

}

void loop()
{
  servo_1();
  if(millis() - millis_alt_start > 3000) servo_2();           
  if(millis() - millis_alt_start > 6000) servo_3();        

}
  
  void servo_1()
  {
  // in steps of 1 degree
  static unsigned long millis_alt;// Zeit merken       
  static boolean servo_State; 
  static byte pos;
  const int interval = 70;  
  
   if(millis() - millis_alt > interval)
     {
       if (pos <= 45 && !servo_State)
          {pos++;
           millis_alt = millis();   
           myservo_1.write(pos);
           if(pos ==45) servo_State = 1;             
          }
          
          else if (pos >=0 && servo_State)
                  {pos--;
                   millis_alt = millis();   
                   myservo_1.write(pos); 
                   if(pos ==0) servo_State = 0;           
                  }        
    }
  }  

    void servo_2()
  {
  // in steps of 1 degree
  static unsigned long millis_alt;// Zeit merken       
  static boolean servo_State; 
  static byte pos;
  const int interval = 70;
  
   if(millis() - millis_alt > interval)
     {
       if (pos < 46 && !servo_State)
          {pos++;
           millis_alt = millis();   
           myservo_2.write(pos);
           if(pos ==45) servo_State = 1;             
          }
          
          else if (pos >=0 && servo_State)
                  {pos--;
                   millis_alt = millis();   
                   myservo_2.write(pos); 
                   if(pos ==0) servo_State = 0;           
                  }        
      }
  } 
     void servo_3()
  {
  // in steps of 1 degree
  static unsigned long millis_alt;// Zeit merken       
  static boolean servo_State; 
  static byte pos;
  const int interval = 70;
  
   if(millis() - millis_alt > interval)
     {
       if (pos < 46 && !servo_State)
          {pos++;
           millis_alt = millis();   
           myservo_3.write(pos);
           if(pos ==45) servo_State = 1;             
          }
          
          else if (pos >=0 && servo_State)
                  {pos--;
                   millis_alt = millis();   
                   myservo_3.write(pos); 
                   if(pos ==0) servo_State = 0;           
                  }        
      }
  }