Mehrere Servos mit Taster

Hallo zusammen,

wie mein Username schon sagt bin ich absoluter Anfänger. Bitte schlagt mich nicht :joy:
Nun zu meiner Frage:

Ich möchte das 4 Servos mit einem Tastendruck sich nacheinander bewegen und dann stoppen. Also das Programm nicht wieder von vorne startet, sondern erst wenn ich wieder auf den Knopf drücke.

Drücke auf den Taster….Servo1 dreht sich 180 Grad und geht wieder auf null zurück….Pause 10 Sekunden …..Servo 2 das selbe….Servo 3 das selbe…Servo 4 dreht sich 180Grad zurück auf Null 2 mal….und stop

Gibt es schon so einen Sketch? Oder kann mir jemand erklären wie ich das hinbekommen kann?

Wäre euch echt dankbar :wink:

Hallo,
das machst Du am besten mit einer Schrittkette, Ablaufsteuerung, Statemaschine. Das sind alles Begriffe für das Gleiche. Du kannst z.B hier im Forum danach suchen , es gibt unzählige Beispiele.
Im einfachsten Fall geht das sicher auch mit delay() und einer if Abfrage "Taster gedrückt"

Ja.
Gerade gebaut und nicht direkt für Servos, das Ergebnis ist aber das selbe:

Da Du keine Endschalter brauchst, ist nur das Steppen durch die Schrittkette und die Pausen interessant.

Gebaut werden kann das unterschiedlich - was bleibt, ist Deine Schrittkette.

Mal kurz zusammengebaut.
Ist eigentlich selbsterklärend.

// Forensketch
// https://forum.arduino.cc/

#include <Streaming.h>     // https://github.com/janelia-arduino/Streaming
#include <Servo.h>

Servo servoOne;
Servo servoTwo;
Servo servoThree;
Servo servoFour;

constexpr uint8_t sNums {4};
Servo myServo[sNums] = {servoOne, servoTwo, servoThree, servoFour};
constexpr uint8_t servoPin[sNums] {9, 10, 11, 12};      // angeschlossene Servo Pins

constexpr uint8_t tasterPin {2};

uint8_t schritt = 0;;
uint32_t stepStart;                      // Merker für Start
uint32_t stepTime;                       // Laufzeit des jeweiligen Step

void setup()
{
  Serial.begin(115200);
  delay(300);
  Serial << (F("\r\nStart...\r\n")) << endl;

  for (byte b = 0; b < sNums; b++)       // zählt durch alle Servos
  { myServo[b].attach(servoPin[b]); }    // Zuweisung der Pins

  pinMode(tasterPin, INPUT_PULLUP);      // Taste schaltet nach GND
  pinMode(LED_BUILTIN, OUTPUT);          // Kontrollleuchte
}

void loop()

{
  schrittKette();                        // Abaufsteuerung
  heartBeat(500);                        // lässt die onBoardLed blinken
}

void setServo(const uint8_t sNum, const uint8_t winkel, const uint32_t myTime)
{
  Serial << F("Servo: ") << sNum + 1 << F(" Winkel: ") << winkel << "°" << F(" mit Laufzeit: ") << myTime << "ms" << endl;
  myServo[sNum].write(winkel);
  stepStart = millis();
  stepTime = myTime;
}

bool timeIsEnd()
{
  if (millis() - stepStart >= stepTime)
  {
    Serial << F("Schrittzeit abgelaufen") << endl;
    return 1;
  }

  return 0;
}

void schrittKette()
{
  switch (schritt)
  {
    case 0:                              // Warten auf Tastendruck
      if (!digitalRead(tasterPin))       // Taste ausgelöst
      {
        setServo(0, 180, 100);           // Servonummer, Winkelstellung, Haltezeit
        schritt++;                       // nächster Schritt
      }

      break;

    case 1:
      if (timeIsEnd())
      {
        setServo(0, 0, 10000);
        schritt++;                       // nächster Schritt
      }

      break;

    case 2:
      if (timeIsEnd())
      {
        setServo(1, 180, 100);
        schritt++;                       // nächster Schritt
      }

      break;

    case 3:
      if (timeIsEnd())
      {
        setServo(1, 0, 10000);
        schritt++;                       // nächster Schritt
      }

      break;

    case 4:
      if (timeIsEnd())
      {
        setServo(2, 180, 100);
        schritt++;                       // nächster Schritt
      }

      break;

    case 5:
      if (timeIsEnd())
      {
        setServo(2, 0, 10000);
        schritt++;                       // nächster Schritt
      }

      break;

    case 6:
      if (timeIsEnd())
      {
        setServo(3, 180, 100);
        schritt++;                       // nächster Schritt
      }

      break;

    case 7:
      if (timeIsEnd())
      {
        setServo(3, 0, 100);
        schritt++;                       // nächster Schritt
      }

      break;

    case 8:
      if (timeIsEnd())
      {
        setServo(3, 180, 100);
        schritt++;                       // nächster Schritt
      }

      break;

    case 9:
      if (timeIsEnd())
      {
        setServo(3, 0, 100);
        schritt++;                       // nächster Schritt
      }

      break;

    case 10:
      if (digitalRead(tasterPin))
      {
        schritt = 0;
      }

      break;
  }
}

void heartBeat(const uint32_t switchTime)
{
  static uint32_t lastTik = 0;

  if (millis() - lastTik >= switchTime)
  {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    lastTik = millis();
  }
}

Hey wow danke. Muss ich später gleich mal ausprobieren

Ist nicht schön, sollte aber funktionieren.

Achtung: Ich habe für die Bewegung des Servo 100ms eingeplant. Wenn die nicht reicht, dann musst Du probieren. Wie und wo sollte aus den Kommentaren ersichtlich sein :wink:

Moin @my_xy_projekt ,

habe mir erlaubt, Deinen Sketch bei Wowki einzustellen:
https://wokwi.com/projects/439369305035539457

und einige wenige Anpassungen einzufügen, die das Testen möglicherweise vereinfachen können;

  • Konstante shortWaitTime und longWaitTime eingeführt
  • shortWaitTime von 100 auf 500 ms hochgesetzt, damit die Zeit für die Servos genügt
  • Grüne Led eingeführt, die anzeigt, wann der Tastendruck (wieder) akzeptiert wird

Die 100 ms waren für die Wokwi-Servos zu kurz, daher 500 ms.

/*
  Forum: https://forum.arduino.cc/t/mehrere-servos-mit-taster/1402415/4
  Wokwi: https://wokwi.com/projects/439369305035539457

  2025/08/15
  Sketch von my_xy_projekt
  umgesetzt und (nur leicht) angepasst durch ec2021

  -   Konstante shortWaitTime und longWaitTime eingeführt
  -   shortWaitTime von 100 auf 500 ms hochgesetzt, damit die Zeit für die Servos genügt
  -   Grüne Led eingeführt, die anzeigt, wann der Tastendruck (wieder) akzeptiert wird

*/
// Forensketch
// https://forum.arduino.cc/



#include <Streaming.h>     // https://github.com/janelia-arduino/Streaming
#include <Servo.h>

Servo servoOne;
Servo servoTwo;
Servo servoThree;
Servo servoFour;


constexpr uint8_t ledPin {3};
constexpr uint32_t shortWaitTime {500};
constexpr uint32_t longWaitTime {10000};
constexpr uint8_t sNums {4};
Servo myServo[sNums] = {servoOne, servoTwo, servoThree, servoFour};
constexpr uint8_t servoPin[sNums] {9, 10, 11, 12};      // angeschlossene Servo Pins

constexpr uint8_t tasterPin {2};

uint8_t schritt = 0;;
uint32_t stepStart;                      // Merker für Start
uint32_t stepTime;                       // Laufzeit des jeweiligen Step

void setup()
{
  Serial.begin(115200);
  delay(300);
  Serial << (F("\r\nStart...\r\n")) << endl;

  for (byte b = 0; b < sNums; b++)       // zählt durch alle Servos
  {
    myServo[b].attach(servoPin[b]);  // Zuweisung der Pins
  }

  pinMode(tasterPin, INPUT_PULLUP);      // Taste schaltet nach GND
  pinMode(LED_BUILTIN, OUTPUT);          // Kontrollleuchte
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
}

void loop()

{
  schrittKette();                        // Abaufsteuerung
  heartBeat(500);                        // lässt die onBoardLed blinken
}

void setServo(const uint8_t sNum, const uint8_t winkel, const uint32_t myTime)
{
  Serial << F("Servo: ") << sNum + 1 << F(" Winkel: ") << winkel << "°" << F(" mit Laufzeit: ") << myTime << "ms" << endl;
  myServo[sNum].write(winkel);
  stepStart = millis();
  stepTime = myTime;
}

bool timeIsEnd()
{
  if (millis() - stepStart >= stepTime)
  {
    Serial << F("Schrittzeit abgelaufen") << endl;
    return 1;
  }

  return 0;
}

void schrittKette()
{
  switch (schritt)
  {
    case 0:                              // Warten auf Tastendruck
      if (!digitalRead(tasterPin))       // Taste ausgelöst
      {
        digitalWrite(ledPin, LOW);
        setServo(0, 180, shortWaitTime);           // Servonummer, Winkelstellung, Haltezeit
        schritt++;                       // nächster Schritt
      }
      break;

    case 1:
      if (timeIsEnd())
      {
        setServo(0, 0, longWaitTime);
        schritt++;                       // nächster Schritt
      }

      break;

    case 2:
      if (timeIsEnd())
      {
        setServo(1, 180, shortWaitTime);
        schritt++;                       // nächster Schritt
      }

      break;

    case 3:
      if (timeIsEnd())
      {
        setServo(1, 0, longWaitTime);
        schritt++;                       // nächster Schritt
      }

      break;

    case 4:
      if (timeIsEnd())
      {
        setServo(2, 180, shortWaitTime);
        schritt++;                       // nächster Schritt
      }

      break;

    case 5:
      if (timeIsEnd())
      {
        setServo(2, 0, longWaitTime);
        schritt++;                       // nächster Schritt
      }

      break;

    case 6:
      if (timeIsEnd())
      {
        setServo(3, 180, shortWaitTime);
        schritt++;                       // nächster Schritt
      }

      break;

    case 7:
      if (timeIsEnd())
      {
        setServo(3, 0, longWaitTime);
        schritt++;                       // nächster Schritt
      }

      break;

    case 8:
      if (timeIsEnd())
      {
        setServo(3, 180, shortWaitTime);
        schritt++;                       // nächster Schritt
      }

      break;

    case 9:
      if (timeIsEnd())
      {
        setServo(3, 0, longWaitTime);
        schritt++;                       // nächster Schritt
      }

      break;

    case 10:
      if (digitalRead(tasterPin))
      {
        schritt = 0;
        digitalWrite(ledPin, HIGH);
      }

      break;
  }
}

void heartBeat(const uint32_t switchTime)
{
  static uint32_t lastTik = 0;

  if (millis() - lastTik >= switchTime)
  {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    lastTik = millis();
  }
}

Hoffe, dass es Dir gut geht!
Grüße
ec2021

@andy-anfaenger : Und Dir natürlich viel Spaß mit der Arduino-Technik! Falls Du Wokwi noch nicht kanntest, ist das möglicherweise für Dich auch eine hervorragende Möglichkeit, Dich mit der Anwendung verschiedener Sensoren und Aktuatoren auseinanderzusetzen, ohne vorher stecken oder löten zu müssen ... :wink:

Hatte ich extra noch nicht gebaut, weil wenn die Timings noch angepasst werden, lohnt sich vielleicht ein struct und sowohl timing als auch status dann mit einer Funktion abhandeln.

Ich lebe und brauch noch keinen Rollator. :slight_smile:

Ich kenne überhaupt noch nicht viel von dem ganzen, aber ich finde es so faszinierend was man damit alles machen kann und deshalb möchte ich das ganze lernen. Bin für jeden Tipp dankbar.

Den Code schon getestet?
Brauchst Du noch was zusätzlich?

Und dann Lektüre, die relativ einfach geschrieben ist. Bis zur Hälfte sind es Grundlagen. Nur durchlesen. Wenn Du weist, was drin steht, kannste später nachschlagen :slight_smile:

Die Faszination für die technischen Möglichkeiten der Mikrocontroller-Welt, die heute nahezu jedem zugänglich ist, ist sicher ein wesentliche Motivation für viele hier im Forum!

Nun kommt es noch darauf an, mit welchen Vorkenntnissen und Erfahrungen man startet:

  • Programmiersprachen?
  • Elektronik-Kenntnisse ?

Das Internet bietet reichlich Tutorials, um sich Grundlagen zu erarbeiten.

Man sollte aber berücksichtigen, dass die allermeisten Beispiele tatsächlich nur die grundsätzliche Handhabung aufzeigen und eher selten zur Lösung realer Anwendungen taugen.

Das ist vergleichbar mit dem ersten Schulbuch im Deutschunterricht. Man lernt korrektes Schreiben, den Aufbau von Sätzen und die ersten Regeln der Zeichensetzung. Für das Erstellen eines Aufsatzes reicht es jedoch kaum.

Um über das Niveau der Beispiele hinaus zu kommen, lohnt sich i.d.R. ein Buch zum Erlernen der Programmiersprache C++.

Ich empfehle ein "analoges" Buch, weil man sich damit auch ohne Ablenkung durch eine verführerische Tastatur Zusammenhänge erarbeiten kann.

Zusätzlich findet man mit ein wenig Suche gerade hier im Forum gute Tutorials, die über die absoluten Basics hinaus gehen.

Gruß
ec2021

Aktuell für 11,99€ im Angebot Breymann C++-Programmieren. Ursprünglich 40€.
Als Buch mit PDF (gut zum Suchen)

Gruß Tommy

@ec2021 wenn ich ehrlich bin hab ich von beidem nicht viel Ahnung.
Elektrik ein bisschen vom Modellbau, aber programmieren absolut nichts.
Man kann ja aber versuchen es zu lernen.

Gruß Andi

@Tommy56 Danke dir. Hab ich bestellt :wink:

Gruß Andi

Du hast ja einiges an Lesematerial vorgeschlagen bekommen. AIch die IDE bringt viele Beispiele mit. Fange klein an. Taster einlesen, LED zum leichten bringen, 2 LED mit unterschiedlicher Geschwindigkeit blinken lassen, ...
Wenn Du diese Grundlagen verinnerlicht hast, kannst Du an die Servos gehen.
Dazu sind dann die MoBaTools zu empfehlen, da sie gut dokumentiert sind.

Gruß Tommy

@my_xy_projekt erstmal Danke für deine Hilfe.
Hab mir das ganze etwas leichter vorgestellt, aber aller Anfang ist schwer.
Um ehrlich zu sein qualmt mir gerade der Kopf.
Bin noch nicht dazu gekommen deinen Code auszuprobieren. Denke am Montag hab ich Zeit.
Mach jetzt mal Heute und Morgen Pause.

Hallo andy-anfaenger

Hier kommen prima Anleitungen von Harmut zum Üben und Lernen.

Viel Spass beim gemeinsamen Hobby :slight_smile:

@paulpaulson vielen Dank :wink: sowas kann ich gut gebrauchen.

Grüße Andi

@my_xy_projekt brauche doch vielleicht noch was :see_no_evil_monkey:
Meinst du der Arduino UNO packt das mit den 4 Servos und dem Taster oder soll ich besser externen Strom nehmen?

Geht die Variante mit der LED auch beim UNO?

Man bin ich eine Lötfeile🙈 ne, ich bin bei Strom vielleicht zu vorsichtig.

Grüße Andi

Hallo,

für ein kleines Servo ohne Last reicht es, also zum ersten Test. Ansonsten immer eigene Stromversorgung für Servos einplanen.

Da immer nur ein Servo läuft, sollte das auch mit der Versorgung aus dem UNO heraus funktionieren.

Die LED geht überall, solange Du einen PIN dafür hast.
In meinem Code ist die ON-Board-LED benutzt. Die liegt parallel an PIN 13. Du kannst den PIN also nutzen UND die LED auf dem Board läuft mit.

Bei anderen Boards ist zu prüfen, ob und wo eine LED verbaut ist.

Wenn Dir die da nicht gefällt, kannst Du die auch auf einen anderen PIN legen, brauchst dann aber zwingend eine externe LED-