Servo mit einem Taster auf 2 Positionen stellen

Moin Gemeinde, ich benötige hilfe um die Servos mit dem gleichen Taster auch wieder Retour zu stellen. Habe da einiges gelesen von wegen `bounce´ oder ´toogle´, aber ich blick da nicht durch und weiß gar nicht ob ich damit richtig liege. Bin recht frisch dabei, das was bis jetzt da ist, funzt, aber noch nicht nach meinen Wünschen.

Bitte Danke

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// Platinen-Objekte mit spezifischer Adresse erstellen
Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x40); // Adresse 0x40 für Platine 1
Adafruit_PWMServoDriver pwm2 = Adafruit_PWMServoDriver(0x41); // Adresse 0x41 für Platine 2

#define SERVOMIN 150 // Minimaler Pulswert (abhängig vom Servo)
#define SERVOMAX 600 // Maximaler Pulswert (abhängig vom Servo)

// Pins für Taster (D2 bis D13)
const int buttonPins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
const int numButtons = 12;

void setup() {
  Serial.begin(9600);
  pwm1.begin();
  pwm2.begin();
  pwm1.setPWMFreq(60); // Servos laufen meist mit ~60 Hz
  pwm2.setPWMFreq(60);

  // Taster-Pins als INPUT_PULLUP initialisieren
  for (int i = 0; i < numButtons; i++) {
    pinMode(buttonPins[i], INPUT_PULLUP);
  }
}

// Hilfsfunktion zur Winkelkonvertierung
uint16_t angleToPulse(int angle) {
  int pulse = map(angle, 0, 180, SERVOMIN, SERVOMAX);
  return pulse;
}

void loop() {
  // Beispiel: Beim Drücken des ersten Tasters (Pin 2), Servo 0 auf Platine 1 bewegen
  if (digitalRead(buttonPins[0]) == LOW) {
    pwm1.setPWM(0, 0, angleToPulse(90)); // Bewege Servo 0+1 auf 90 Grad
    pwm1.setPWM(1, 1, angleToPulse(0));
    delay(500);
  }
  if (digitalRead(buttonPins[1]) == LOW) {
    pwm1.setPWM(2, 2, angleToPulse(90)); // Bewege Servo 2+3 auf 90 Grad
    pwm1.setPWM(3, 3, angleToPulse(0));
    delay(500);
  }
  if (digitalRead(buttonPins[2]) == LOW) {
    pwm1.setPWM(4, 4, angleToPulse(0)); // Bewege Servo 4+5 auf 90 Grad
    pwm1.setPWM(5, 5, angleToPulse(90));
    delay(500);
  }
  if (digitalRead(buttonPins[3]) == LOW) {
    pwm1.setPWM(6, 6, angleToPulse(0)); // Bewege Servo 6+7 auf 90 Grad
    pwm1.setPWM(7, 7, angleToPulse(90));
    delay(500);
  }
  if (digitalRead(buttonPins[4]) == LOW) {
    pwm1.setPWM(8, 8, angleToPulse(0)); // Bewege Servo 8+9 auf 90 Grad
    pwm1.setPWM(9, 9, angleToPulse(90));
    delay(500);
  }
  if (digitalRead(buttonPins[5]) == LOW) {
    pwm1.setPWM(10, 10, angleToPulse(0)); // Bewege Servo 10+11 auf 90 Grad
    pwm1.setPWM(11, 11, angleToPulse(90));
    delay(500);
  }
  if (digitalRead(buttonPins[6]) == LOW) {
    pwm1.setPWM(12, 12, angleToPulse(0)); // Bewege Servo 12+13 auf 90 Grad
    pwm1.setPWM(13, 13, angleToPulse(90));
    delay(500);
  }
  if (digitalRead(buttonPins[7]) == LOW) {
    pwm1.setPWM(14, 14, angleToPulse(0)); // Bewege Servo 14+15 auf 90 Grad
    pwm1.setPWM(15, 15, angleToPulse(90));
    delay(500);
  }
  if (digitalRead(buttonPins[8]) == LOW) {
    pwm2.setPWM(0, 0, angleToPulse(0)); // Bewege Servo 16+17 auf 90 Grad
    pwm2.setPWM(1, 1, angleToPulse(90));
    delay(500);
  }
  if (digitalRead(buttonPins[9]) == LOW) {
    pwm2.setPWM(2, 2, angleToPulse(0)); // Bewege Servo 18+19 auf 90 Grad
    pwm2.setPWM(3, 3, angleToPulse(90));
    delay(500);
  }
  if (digitalRead(buttonPins[10]) == LOW) {
    pwm2.setPWM(4, 4, angleToPulse(0)); // Bewege Servo 20+21 auf 90 Grad
    pwm2.setPWM(5, 5, angleToPulse(90));
    delay(500);
  }
  if (digitalRead(buttonPins[11]) == LOW) {
    pwm2.setPWM(6, 6, angleToPulse(90)); // Bewege Servo 22+23 auf 90 Grad
    pwm2.setPWM(7, 7, angleToPulse(0));
    delay(500);
  }
  // Fügen Sie hier Logik für die anderen 11 Taster und 23 Servos hinzu
}

Ich hoffe das war alles richtig so.

mach dir für jeden dieser Pins auch einen merker, wo du dir die letzte Stellung merkst.
Also im ersten Schritt auch wieder ein array der gleichen größe. Als bool reichts.

Und dann wertest du einfach in deinem "digitalread blabblub == LOW" aus ob das flag true oder false ist und entsprechend setzt du den Servowinkel rauf oder runter und drehst das jeweilige Flag um.

Dein Servostellen muss ich mir noch ansehen. Das schaut bei dir eigenartig aus.

Das hast du richtig erkannt!
Entprellen, Flanken erkennen und Zustand merken.

Findest du alles tausendfach hier im Forum.

@cchurchman66
das könntest mal probieren:

/*
  viele Buttons - doppelt so viele Servos

  https://forum.arduino.cc/t/servo-mit-einem-taster-auf-2-positionen-stellen/1424568

  2026-01-10 by noiasca
 */

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// Platinen-Objekte mit spezifischer Adresse erstellen
Adafruit_PWMServoDriver pwm1(0x40); // Adresse 0x40 für Platine 1
Adafruit_PWMServoDriver pwm2(0x41); // Adresse 0x41 für Platine 2

constexpr uint16_t SERVOMIN {150}; // Minimaler Pulswert (abhängig vom Servo)
constexpr uint16_t SERVOMAX {600}; // Maximaler Pulswert (abhängig vom Servo)


// Ein Gruppenmitglied besteht aus folgenden Elementen:
struct Group {
  const uint8_t buttonPin;
  Adafruit_PWMServoDriver &ic;         // Reference to the used IC
  const uint8_t outputA;               // output pin on the used IC
  //uint8_t outputB;                   // is always one higher then outputA
  bool state = 0;                      // previous state

  Group (const uint8_t buttonPin, Adafruit_PWMServoDriver ic, const uint8_t outputA) : buttonPin(buttonPin), ic(ic), outputA(outputA) {}
};

// und jetzt legen wir mehrere Gruppenmitglieder fest
Group group[] {
  {2, pwm1, 0},
  {3, pwm1, 2},
  {4, pwm1, 4},
  {5, pwm1, 6},
  {6, pwm1, 8},
  {7, pwm1, 10},
  {8, pwm1, 12},
  {9, pwm1, 14},
  {10, pwm2, 0},
  {11, pwm2, 2},
  {12, pwm2, 4},
  {13, pwm2, 6},
};


void setup() {
  Serial.begin(115200);  // kein grund für langsame 9600
  pwm1.begin();
  pwm2.begin();
  pwm1.setPWMFreq(60);   // Servos laufen meist mit ~60 Hz
  pwm2.setPWMFreq(60);

  // Taster-Pins als INPUT_PULLUP initialisieren
  for (auto & g : group) {                    // jedes Gruppenmitglied durchsuchen
    pinMode(g.buttonPin, INPUT_PULLUP);
  }
}

// Hilfsfunktion zur Winkelkonvertierung
uint16_t angleToPulse(int angle) {
  int pulse = map(angle, 0, 180, SERVOMIN, SERVOMAX);
  return pulse;
}

void loop() {

  for (auto & g : group) {                      // jedes Gruppenmitglied durchsuchen
    if (digitalRead(g.buttonPin) == LOW) {
      Serial.print(F("buttonPin:")); Serial.print(g.buttonPin);
      if (g.state) {
        g.ic.setPWM(g.outputA, 0, angleToPulse(90));
        g.ic.setPWM(g.outputA + 1, 0, angleToPulse(0));
        Serial.println(F(" up"));
      }
      else {
        g.ic.setPWM(g.outputA, 0, angleToPulse(0));
        g.ic.setPWM(g.outputA + 1, 0, angleToPulse(90));
        Serial.println(F(" down"));
      }
      g.state = !g.state;  // status umdrehen
      delay(500);          // dirty delay to debounce
    }
  }
}
//

Wenns nicht klappt, bitte genau beschreiben, was nicht geht bzw. was auf der Seriellen ausgegeben wird (die jetzt 115200 läuft!)

Erst mal lieben Dank für deine Mühe.

Es tut sich nix, bei Taster Bedienung, egal welchem, flackert die RX Diode. Aber langsam, ich möchte auch verstehen was da ablaufen soll und melde mich gleich nochmal. Jetzt ist der Hund dran.

So ich war dann nochmal dran, sehe ich das richtig, dass du in deinem VoidLoop auf die Gruppe zugreifst? Ich hatte da ja Fleißarbeit mit dem copy und paste für 12 Taster und 24 Servo.

void loop() {

  for (auto & g : group) {                      // jedes Gruppenmitglied durchsuchen
    if (digitalRead(g.buttonPin) == LOW) {
      Serial.print(F("buttonPin:")); Serial.print(g.buttonPin);
      if (g.state) {
        g.ic.setPWM(g.outputA, 0, angleToPulse(90));
        g.ic.setPWM(g.outputA + 1, 0, angleToPulse(0));
        Serial.println(F(" up"));
      }
      else {
        g.ic.setPWM(g.outputA, 0, angleToPulse(0));
        g.ic.setPWM(g.outputA + 1, 0, angleToPulse(90));
        Serial.println(F(" down"));
      }
      g.state = !g.state;  // status umdrehen

und ist das richtig, du gibst generell nur pwm an und nicht nummeriert? Da hatte ich gestern so ne Grübler weil ich mit 16……. weiter gebastelt hab und nicht auf pwm2 0 war……

die "Gruppe" ist eine Struktur.
Dort gibt es jeweils einen Button, eine Referenz auf den PWM Chip und den betroffenen Ausgang (zumindest den ersten).

Die "0" im setPWM ist eigentlich nur der Zeitslot, wann der Puls beginnen soll, da braucht es eigentlich keine Unterschiede.
Das schreibt Adafruit dazu:

/*!
 *  @brief  Sets the PWM output of one of the PCA9685 pins
 *  @param  num One of the PWM output pins, from 0 to 15
 *  @param  on At what point in the 4096-part cycle to turn the PWM output ON
 *  @param  off At what point in the 4096-part cycle to turn the PWM output OFF
 *  @return 0 if successful, otherwise 1
 */

Ok, das muß jetzt erstmal wirken. Habs nochmal aufgespielt, tut sich nix außer die RX Led. Bleibt der Taster länger gedrückt, zucken einige Servos kurz hin und her, es ist uninteressant ob PWM1 oder 2, an gerader oder ungerader Ziffer. alles gut, Rom ist auch nicht an einem Tag erbaut worden.

was gibt der Serielle Monitor bei 115200 aus?

Damit verstößt du gegen das DRY "Gesetz"!

Leider hast du bisher nicht klar gesagt, was deine Taster mit den Servos anstellen sollen.
Kann sein, dass das in deinem Kopf klar ist. Aber bei mir ist es noch nicht angekommen.

Wie bzw wo kann ich das sehen?

Was auch immer das fürn Gesetz ist,?

Ich betreibe eisenbahnmodellbau im Maßstab 1:160, sprich Spur N, und möchte meinen Ringlokschuppen, bzw dessen Tore damit steuern. 12 Ständiger Schuppen, sprich 24 Tore. Das via Taster, aber so das ein Taster 2 Tore bewegt. Auf und auch wieder zu. Wenn du noch Fragen hast, gern

Seit vielen Jahrzehnten wird Software entwickelt.
Tausende von Programmieren. Millionen von Mannstunden.
Dabei haben sich Regeln/Prinzipien ergeben, an die man sich halten sollte.
Diese "Gesetze"/Vorschläge dienen dazu, einem das Leben zu erleichtern.

@noiasca hat da mit seiner Struktur schon einen guten Anfang gemacht!

Und ich dachte daß Standart-Servos mit 50Hz angesteuert werden.
Spezialservos für schnellere Positioniertung werden mit 400Hz gesteuert.
Hab noch nie von 60Hz gehört.

Grüße UWE

1 Like

Ja und? Das berechtigt nicht alles mit Copy Paste zu erstellen.
Da sind 12 Taster. 24 Servos und 48 Endlagen.
Und lüpt das wirst Du drauf kommen das die Servos ja mehr oder weniger die Türen aufschlagen. Ergo wird das auf ein Timing hinauslaufen für die Türen die geöffnet oder geschlossen werden. Ab da biste mit Copy Paste am Ende.
Wie hier schon erwähnt Zauberwort lege es in eine Struktur
Ein Beispiel

z.B.
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// Platinen-Objekte mit spezifischer Adresse erstellen
Adafruit_PWMServoDriver PCA1 = Adafruit_PWMServoDriver(0x40); // Adresse 0x40 für Platine 1
Adafruit_PWMServoDriver PCA2 = Adafruit_PWMServoDriver(0x41); // Adresse 0x41 für Platine 2



const byte tore = 24;
struct Schuppentor
{
  const byte taster;
  const byte ServoPin;  
  const int Endlage_Auf;
  const int Endlage_Zu;  
  // const int Stellzeit;  
  //  brauchst Du nacher eine Zeit um die Servos langsammer zu bewegen {2,0,150,600,80} 
  void init()
  {
    pinMode(taster, INPUT_PULLUP);
  }
  
};

Schuppentor Tor[tore]
{
  //Taster
  //   PCA 9685 PIN
  //   |   Endlage Auf
  //   |   |  Endlage Zu
  //   |   |  |    
  { 2, 0,150,600},
  { 3, 1,150,600},
  { 4, 2,150,600},
  { 5, 3,150,600},
  { 6, 4,150,600},
  { 7, 5,150,600},
  { 8, 6,150,600},
  { 9, 7,150,600},
  {10, 9,150,600},
  {11, 8,150,600},
  {12,10,150,600},
  {13,12,150,600},
  { 2,13,600,150},  // xx ist in diesem Fall dann ja fast Spiegelbildlich
  { 3,14,150,600},
  { 4,15,150,600},
  { 5,11,150,600}, // Ab hier ja Trennung PCA9685 1 und 2
  { 6,16,150,600},
  { 7,17,150,600},
  { 8,18,150,600},
  { 9,19,150,600},
  {10,21,150,600},
  {11,22,150,600},
  {12,31,150,600},  // Das wäre ja dann PIN 15 auf dem 2. PA9685
  {13,10,150,600},
};


// Hier trenne ich habe somit die Strukt  0 bis 15 und 16 bis 31
void TorPWM(uint8_t pin, uint16_t pwm) {
    switch (pin) {
      case 0 ... 15:  //PIN Nummer des 1. PCA
        PCA1.setPWM(pin,0, pwm);
        break;
      case 16 ... 31:  //PIN Nummer des 2. PCA
        PCA2.setPWM(pin - 16,0, pwm);
        break;
    }
  }

void setup() {
  Serial.begin(115200);
  PCA1.begin();
  PCA2.begin();
  PCA1.setPWMFreq(60); // Servos laufen meist mit ~60 Hz
  PCA2.setPWMFreq(60);


}

void loop() {
  // put your main code here, to run repeatedly:

}

  • drücke Taste
    • Stelle Servo auf eine Position
  • drücke Taste erneut
    • stelle Servo auf die andere Position

Das löst sich auf in:

  • initialisiere Servo in eine Position
    • Merke Position
  • drücke Taste
    • stelle Servos auf andere Position
    • Merke Position
    • mache nichts, bevor die Taste nicht wieder losgelassen wurde
  • drücke Taste
    • stelle Servos auf andere Position
    • Merke Position
    • mache nichts, bevor die Taste nicht wieder losgelassen wurde

Dieser Teil:

  • initialisiere Servo in eine Position
    • Merke Position
      wird nur einmal ausgeführt -> und gehört damit ins setup.

Dieser Teil immer wieder:

    • stelle Servos auf andere Position
    • Merke Position
    • mache nichts, bevor die Taste nicht wieder losgelassen wurde

Durch das bekanntsein der Position des Servos muss der Code nicht wiederholt geschrieben werden, sondern wird immer wieder als Funktion aufgerufen.
Ebenso wird für alle anderen Taster (und Servos) verfahren.

Je weiter Du den Code in Module aufteilst, kommst Du weiter in wiederverwendbare Funktionen.

Was mir noch nicht ganz klar ist:
Du betreibst 2 Servos an einer Taste.
Sollen die gegenläufig arbeiten?

Ich hab es mal übertrieben und für EINEN Taster an Pin 2 und EINEN Sevo am ersten Shield Channel 0 einen Code gebaut, der sich relativ einfach auf EINEN Taster und ZWEI Servos erweitern ließe und dann nur noch für jede Taste die entsprechenden Einträge...

Ob das funktioniert? Keine Ahnung.
Ich habe weder Hardware, noch mit der Lib gearbeitet. Es ist ein Testballon.
Achte darauf: Es gibt Ausgaben auf dem seriellen Monitor, wenn Du die Taste betätigst.
Wenn etwas nicht funktioniert, brauche ich die Ausgaben.

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver srvShld[] = {Adafruit_PWMServoDriver(0x40), // Adresse 0x40 für Platine 1
                                     Adafruit_PWMServoDriver(0x41), // Adresse 0x41 für Platine 2
                                    } ;

constexpr uint16_t SERVOMIN {150}; // Minimaler Pulswert (abhängig vom Servo)
constexpr uint16_t SERVOMAX {600}; // Maximaler Pulswert (abhängig vom Servo)
constexpr uint8_t SERVO_FREQ {60};

constexpr bool isPressed {LOW};
constexpr uint32_t debounceTime {50};

struct TS
{
  const uint8_t btnPin;
  uint32_t pressTime;
  bool lastState;

  const uint16_t servP[2];
  uint16_t servPos;

  Adafruit_PWMServoDriver driver;
  const uint8_t channel;

  void begin() {
    pinMode(btnPin, INPUT_PULLUP);
    servPos = servP[0];
  }
  // Hilfsfunktion zur Winkelkonvertierung
  uint16_t angleToPulse(const uint8_t angle) {
    uint16_t servPWM = map(angle, 0, 180, SERVOMIN, SERVOMAX);
    return servPWM;
  }

  void update() {
    if (digitalRead(btnPin) == isPressed) {    // Taste gedrückt
      if (lastState != isPressed) {            // vorher nicht gedrückt
        Serial.print(F("Taste an Pin "));
        Serial.print(btnPin);
        Serial.println(F(" gedrückt"));
        lastState = isPressed;                 // Zustand merken
        pressTime = millis();                  // Zeitpunkt merken

        if (servPos == servP[0]) {
          servPos = servP[1];
        }
        else
        { servPos = servP[0]; }

        Serial.print(F("neue ServoPos: "));
        Serial.println(servPos);
      }
    }
    else {                                        // Taste nicht gedrückt
      if (lastState == isPressed) {               // vorher gedrückt
        if (millis() - pressTime > debounceTime) { // Und Zeit abgelaufen
          Serial.print(F("Taste an Pin "));
          Serial.print(btnPin);
          Serial.println(F(" nicht gedrückt"));
          lastState = !isPressed;
        }
      }
    }

    driver.setPWM(channel, 0, angleToPulse(servPos));
    //
  }

};

TS ts[]
{
  {2, 0, !isPressed, {0, 90,}, 0, srvShld[0], 0,},  //TasterPin, auslösezeit, status, {servoPos 0, 1}, startPosiion, shieldnummer, channel
};

void setup()
{
  Serial.begin(9600);
  Serial.println(F("Start...."));

  for (Adafruit_PWMServoDriver &s : srvShld)
  {
    s.begin();
    s.setPWMFreq(SERVO_FREQ); // Servos laufen meist mit ~60 Hz
  }

  for (TS &t : ts)
  {
    t.begin();
  }
}

// Hilfsfunktion zur Winkelkonvertierung
uint16_t angleToPulse(int angle)
{
  uint16_t pulse = map(angle, 0, 180, SERVOMIN, SERVOMAX);
  return pulse;
}

void loop()
{
  for (TS &t : ts)
  { t.update(); }
}

Würde noch eine kleine Verzögerung einbauen, damit das Prellen des Tasters nicht den Servo sofort wieder auslöst. Also:

  • drücke Taste
    • stelle Servos auf andere Position
    • Merke Position
    • Kleine Pause bzw Auslesen der betreffenden Taste erst nach einer gewissen Zeit wieder ermöglichen.
    • mache nichts, mit diesem Servo bevor die Taste nicht wieder losgelassen wurde

In dem gezeigten Sketch ist das mittels millis() implementiert, aber schon die Serrial.print("text") Funktionen bewirken die zum Entprellen notwendige Verzögerung. (Falls sie im endgültigen Sketch noch drin sind).
So wie es im Beispielsketch implementiert wurde ist das sicher die beste Methode. Zu bedenken ist, daß jede Taste seine Speichervariable für millis() braucht.

Grüße Uwe

So liebe Leuts, ich muß wohl erstmal was klarstellen. Ich habe mit Copy und Paste komplett was anderes gemeint, als hier verstanden wird. Ich will und werde nicht irgendein geistiges Eigentum ohne Einverständnis benutzen!

Ich meinte das komplett anders! Ich habe folgenden Code durch meine Suchen im Netz, auch mit KI gefunden.

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// Die I2C-Adresse ist standardmäßig 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40);

// Definitionen für Taster-Pins (2 bis 9 für 8 Taster)
const int buttonPins[] = {2, 3, 4, 5, 6, 7, 8, 9};
const int NUM_BUTTONS = 8;
const int NUM_SERVOS = 16;

// Positionswerte für die Servos (Beispielwerte, müssen eventuell angepasst werden)
// Ein typischer Bereich für 0 bis 180 Grad in Ticks bei 50Hz ist 100 bis 500
uint16_t servoPositions[NUM_SERVOS];
const uint16_t SERVOMIN = 150; // Minimaler Pulswert (0 Grad)
const uint16_t SERVOMAX = 600; // Maximaler Pulswert (180 Grad)

void setup() {
  Serial.begin(9600);
  pwm.begin();
  pwm.setPWMFreq(50); // Servos arbeiten typischerweise mit 50Hz

  // Taster-Pins als INPUT_PULLUP konfigurieren
  for (int i = 0; i < NUM_BUTTONS; i++) {
    pinMode(buttonPins[i], INPUT_PULLUP);
  }

  // Servos initial auf eine Mittelposition setzen
  for (int i = 0; i < NUM_SERVOS; i++) {
    servoPositions[i] = (SERVOMIN + SERVOMAX) / 2;
    pwm.setPWM(i, 0, servoPositions[i]);
  }
}

void loop() {
  // Überprüfe jeden Taster
  for (int i = 0; i < NUM_BUTTONS; i++) {
    // Wenn Taster gedrückt ist (LOW, wegen INPUT_PULLUP)
    if (digitalRead(buttonPins[i]) == LOW) {
      // Steuere Servos basierend auf dem Taster
      // Hier müssen Sie Ihre Logik implementieren, z.B. 2 Servos pro Taster
      // Beispiel: Taster 0 steuert Servo 0 und Servo 1
      if (i == 0) {
        // Beispiel: Servo 0 auf Minimum, Servo 1 auf Maximum
        moveServo(0, SERVOMIN);
        moveServo(1, SERVOMAX);
      }
      // Fügen Sie hier weitere else if Blöcke für die anderen Taster und Servos hinzu
      // ...
    }
  }
}

// Hilfsfunktion zum sanften Bewegen eines Servos (optional, macht die Bewegung schöner)
void moveServo(uint8_t servoNum, uint16_t targetPos) {
    // Diese einfache Version bewegt direkt. Für sanfte Bewegungen ist mehr Code nötig.
    pwm.setPWM(servoNum, 0, targetPos);
    // Eine kleine Verzögerung kann für Debouncing der Taster und zur Stabilisierung nützlich sein
    delay(10); 
}

Diesen dann mit Copy und Paste in den Obigen verändert. Das C+P bezog sich auf die einzelnen Taster sowie Servos.

Ich hoffe, das das nun geklärt ist.

Des weiteren bin ich absolut glücklich über eure Hilfen, ich werde alles versuchen zu verstehen und zu verarbeiten, auch wie oben erwähnt, bin ich Frischling, möchte aber wissen warum das nach recht oder links geht auch in welcher Zeit, bzw Reihenfolge. Lauflicht, Ampel und das Fahren einer Seilbahn ist mir als Projekt, durch erlesen hier im Forum, schon gelungen und ebenso bin ich schon “Opfer” von C+P geworden, und hab für 100€ das bekommen was vielleicht 20 gekostet hätte und beim verwirklichen auch noch Spaß gemacht hätte. Aber alles gut das war Lehrgeld.

In diesem Sinne Grüße aus Belgien

@cchurchman66: Also ich würde das Projekt klein anfangen:

  • 1 Taster
  • 1 Servo
  • 2 Positionen

Und dann nochmal aufteilen in:

  • Taster abfragen
  • Servo ansteuern

Ein Zustandsautomat für die Servoansteuerung könnte so aussehen:

Jede Ellipse ist hier ein Zustand.
Jeder Pfeil ein Übergang. Um einen Übergang ablaufen zu dürfen muss eine (oder mehre) Bedingung erfüllt sein. Beim Ablaufen können Aktionen ausgeführt werden.

In unserem Fall ist die Bedingung ein erkanntes Tastenklick.
Und die Aktion ein passendes servo.setPWM(...)

Hast du eine Idee, wie man das umsetzen könnte?

Ja, das habe ich zumindest auch so verstanden und gesehen und festgestellt, dass das überflüssig ist. :man_shrugging:
Darum habe ich versucht das zu erklären, dass das auch anders und vor allem effektiver geht.

Das müsste dann heissen "erneut gedrückt wurde".
Mit dem loslassen passiert nur die Freigabe, dass ein erneutes drücken erkannt werden kann.

Wenn man das in Textform in einen PAP packen will, ist das schon kompliziert :-)