Multiple Pin Define for Servos and Buttons ?

I have a code for only one servo and buttons.I need to add several servo and button to the code but doesn't work what I'm doing.
So How can I add multiple pin following line?

int Pin_Servo = 3;
int Pin_Taster = 12;

In german Taster is Button.

Original code ;

// Einbinden der Servo-Bibliothek
 
#include <Servo.h>
 

// Definition der Variablen
 
// für den Servo
 
int Weiche_Gerade = 60;           // Endlage des Servos wenn Weiche auf Gerade
int Weiche_Mitte = 90;            // Mittellage
int Weiche_Abzweig = 120;         // Endlage des Servos wenn Weiche auf Abzweig
int Weiche_soll = Weiche_Mitte;   // Speichervariable für die aktuelle Lage 
int Stellzeit_Servo_Weiche = 30;  // Stellgeschwindigkeit Weiche
int Pin_Servo = 3;                // Servo an PIN 3
 
// für den Taster
 
int Pin_Taster = 12;               // Taster an PIN 4
unsigned long entprellzeit = 20;  // Zeitintervall der Tasterabfrage
unsigned long tasterzeit = 0;     // Speichervariable für die Zeit
int taster_gedrueckt = 0;         // Speichervariable für den Tasterzustand
 
// Anlegen eines Servo-Objektes
 
Servo servo;
 
void setup()
{
 
  // Initialisieren der Weiche auf Grundstellung
   
  servo.attach(Pin_Servo);              // Aktivierung ServoPin
  servo.write(Weiche_Mitte);            // Servo fährt in Mittelstellung
  delay(500);                           // Warten das der Servo die Stellung erreicht hat
  
// Servo fährt in Stellgeschwindigkeit in die Grundlage (in der Regel Gerade 
  
  
  while (Weiche_Gerade < Weiche_soll)
  {
    Weiche_soll--;
    servo.write(Weiche_soll);
    delay(Stellzeit_Servo_Weiche);
    if (Weiche_soll == Weiche_Gerade) 
    {
      servo.detach();                   // Deaktivierung Servo
    }
  } 
}
  
 
void loop()
{
 
// Definition des PINS 
 
  pinMode(Pin_Taster, INPUT);
 
// Entprellen des Tasters
  
  if (digitalRead(Pin_Taster) == HIGH)
  {
    tasterzeit = millis();                  // Speichern der aktuellen Zeit
    taster_gedrueckt = 1;
  }
 
// Abfrage der Weichenlage, Servo fährt dann in die jeweils Andere
 
  if ((millis() - tasterzeit > entprellzeit) && taster_gedrueckt == 1 && Weiche_soll == Weiche_Abzweig)
    {
    while (Weiche_Gerade < Weiche_soll)
      {
      servo.attach(Pin_Servo);
      Weiche_soll--;
      servo.write(Weiche_soll);
      delay(Stellzeit_Servo_Weiche);
      if (Weiche_soll == Weiche_Gerade) 
        {
        servo.detach();                   // Deaktivierung Servo
        taster_gedrueckt = 0;     
        }
      }
    }
   
  if ((millis() - tasterzeit > entprellzeit) && taster_gedrueckt == 1 && Weiche_soll == Weiche_Gerade)
    {
    while (Weiche_Abzweig > Weiche_soll) 
      {
      servo.attach(Pin_Servo);
      Weiche_soll++;
      servo.write(Weiche_soll);
      delay(Stellzeit_Servo_Weiche);
      if (Weiche_soll == Weiche_Abzweig)        // Abfrage ob Endlage erreicht
        {
        servo.detach();                         // Deaktivierung Servo
        taster_gedrueckt = 0;                   //  Zurückstellen des Tasterstatus
        }
      }
    }
  
} 

Although I'm language limited, it doesn't appear that you tried more than one button or servo in the code you posted, so we can't see what's going wrong. If that's the case, please post the nonworking code, and we can further advise.

You can use arrays, like this:

int Pin_Servo[3] = {3, 4, 5};
int Pin_Taster[3] = {12, 19, 33};

You can also create array of servo objects

Servo servo[3];

and attach your servos like this

  for (int s=0; s<3; s++) {
    servo[s].attach(Pin_Servo[s]);              // Aktivierung ServoPin
    servo[s].write(Weiche_Mitte);
  }

To switch multiple turnouts, you could use the MobaTools library. It provides classes for moving servos slowly and to debounce buttons. A dokumentation in english and german is provided.
Arrays are the way to go with multiple turnouts.

Thank you for inform.I tested some good examples ofMobaTools, but I'm not good at coding. Do you have any sketch for modelrail turnout with relay?

Didn't you want to use a servo to switch your turnout?

Both of them. Multiple switches and relays for 4 servos.

Why do you need relais for the servos?

For polarization the frogs.

Ok, then I misunderstood you. You need a servo and a relais for each turnout. And the relais should switch when the servo is in the middle of its movement to avoid shortcircuits at the switch blade? Or are the switch blades firmly connected to the stock rail and only the frog is insulated and has to be switched? In the latter it doesn't matter when the relais switches.

I need a servo and a relais for each turnout. And the relais should switch when the servo is in the middle of its movement to avoid shortcircuits at the switch blade.
Actually, I have working code from @kolaha multiple switches with relay and uses pca9685 servo driver.In fact I can't add the MobaTools for slow speed. Here is the working code. This code just need a slow-speed servo.

/*
    This example uses 2 servos, one on Pin 0, the other on pin 12 of AdaFruit PCA9685 module
    Relays are on pins 12 and 13

   1 PCA9685 board
   2 servos
   2 3-pole switches
   2 relay modules

   SDA/SCL connections for PCA9685

  Arduino UNO: A4 (SDA), A5 (SCL)
  Arduino Mega 2560: 20 (SDA), 21 (SCL)
  ESP32: 21(SDA), 22 (SCL)

  pins 8 - 11 for buttons/switches
  pins 12-13 relays
*/

#include "Wire.h"
#include <MobaTools.h>
#include "Adafruit_PWMServoDriver.h"
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); // called this way, it uses the default address 0x40

#define USMIN  600 // This is the rounded 'minimum' microsecond length based on the minimum pulse of 150
#define USMAX  1800 // This is the rounded 'maximum' microsecond length based on the maximum pulse of 600
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates

void setServoPos(int servo, int pos) {
  //This first bit of code makes sure we are not trying to set the servo outside of limits
  int sendPos;
  if (pos > 180) pos = 180 ; 
  if (pos < 0)     pos = 0;
  sendPos = map(pos, 0, 180, USMIN, USMAX);
  if (servo > -1 && servo < 16) { //only try to move valid servo addresses
    pwm.writeMicroseconds(servo, sendPos);
    delay (500);
  }
}

void setup() {
  pwm.begin();
  pwm.setOscillatorFrequency(27000000);
  pwm.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates

  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);

  Serial.begin(9600);
  Serial.print("PCA9685ServoSetterV3");
  Serial.end();

}

void loop() {
  static bool StateFirst = false;
  static bool StateSecond = false;
  
  
  if (StateFirst) {                                   //code variant 1
    if (!digitalRead(8)) {
      StateFirst = false;
      setServoPos(0, 180);
      digitalWrite(12, HIGH);
    }
  } else {
    if (!digitalRead(9)) {
      StateFirst = true;
      setServoPos(0, 0);
      digitalWrite(12, LOW);
    }
  }

  if (!digitalRead(10) && StateSecond) {     //code variant 2
    StateSecond = false;
    setServoPos(12, 180);
    digitalWrite(13, HIGH);
  } else if (!digitalRead(11) && !StateSecond) {
    StateSecond = true;
    setServoPos(12, 0);
    digitalWrite(13, LOW);
  }

}

That is very different from the code you posted in #1.

I don't see a need to use the PCA9685 to switch a turnout. But if you want to use it, my advices regarding MobaTools don't fit.

That's right very different from the I'm posted #1. I don't think so either need to use pca9685.

I'm not quite shure to understand your post. Do you want to use the PCA?

If not, this may be a solution ( it will be a servo example for model railroaders in the next release of MobaTools :wink: ):

/* MobaTools - Model railroad example for servos
    Switching two turnouts with servos and a relais for frog polarisation.
    The relais is switched in the middle of the path whe switching the turnout.
    It uses a FSM for each turnout.
    The example can easily expanded for more turnouts

*/

#include <MobaTools.h>

// Pin definitions, change to your needs
constexpr byte servoPin[] = { 2, 3 };
constexpr byte nbrTurnouts = sizeof(servoPin); // Number of turnouts
constexpr byte relPin[nbrTurnouts]    = {4, 5};
constexpr byte switchPin[nbrTurnouts] = {A0, A1}; // The switches must be connected between pin and Gnd
// Open switch is the straight position of the turnout

// you can set the servo positions for STRAIGHT and DEVIATE individually for each turnout:
constexpr byte straightPos[nbrTurnouts]  = { 30, 120 };  // Servo position in the straight position of the turnout.
constexpr byte deviatePos[nbrTurnouts] = { 120, 30 };  // Servo position in the deviating position of the turnout
constexpr uint16_t servoSpeed = 2000;                   // 2 sec to move from 0 to 180 deg

//FSM states:
enum fsmStates : byte { STRAIGHT, MOVE2DEV, DEVIATE, MOVE2STRAIGHT };
fsmStates turnoutState[nbrTurnouts];

MoToServo   myServo[nbrTurnouts];                              // create servo objects

void setup() {
  Serial.begin(115200);
  // initialize all objects
  Serial.print("Initializing all turnouts ...");
  for ( byte toIx = 0; toIx < nbrTurnouts; toIx++ ) {
    pinMode( relPin[toIx], OUTPUT );
    pinMode( switchPin[toIx], INPUT_PULLUP);
    myServo[toIx].attach( servoPin[toIx], true );   // with auto switch off the pulses
    myServo[toIx].setSpeedTime( servoSpeed );

    // Set initial servo position and relais according to the switches
    // If switches are not changed since last shut down, this should be the actual servo position
    if ( digitalRead( switchPin[toIx] ) ) {
      // switch is open -> 'strait' position
      myServo[toIx].write( straightPos[toIx] );
      digitalWrite( relPin[toIx], LOW );
      turnoutState[toIx] = STRAIGHT;
    } else {
      // switch is closed -> 'deviate' position
      myServo[toIx].write( deviatePos[toIx] );
      digitalWrite( relPin[toIx], HIGH );
      turnoutState[toIx] = DEVIATE;
    }
  }
  Serial.println("finished");
}


void loop() {

  for ( byte toIx = 0; toIx < nbrTurnouts; toIx++ ) {
    // turnout-FSM
    switch ( turnoutState[toIx] ) {
      case STRAIGHT: /////// Turnout is in the STRAIGHT position. wait until switch is changed
        if ( !digitalRead(switchPin[toIx] ) ) {
          // switch now in deviate position -> change servo position
          myServo[toIx].write( deviatePos[toIx] );
          turnoutState[toIx] = MOVE2DEV;
          Serial.print(toIx); Serial.print(" - moving to DEV position...");
        }
        break;
      case MOVE2DEV:  /////// Turnout is moving to deviate position
        // set relais when servo reaches middle position
        if ( myServo[toIx].moving() < 50  ) {
          // Servo has reached middle position -> switch relais
          digitalWrite( relPin[toIx], HIGH );
        }
        if ( !myServo[toIx].moving()  ) {
          // Servo has reached end position -> next FSM state
          turnoutState[toIx] = DEVIATE;
          Serial.println("finished");
        }
        break;
      case DEVIATE:  /////// Turnout is in DEVIATE position
        if ( digitalRead(switchPin[toIx] ) ) {
          // switch now is in straight position -> change servo position
          myServo[toIx].write( straightPos[toIx] );
          turnoutState[toIx] = MOVE2STRAIGHT;
          Serial.print(toIx); Serial.print(" - moving to STRAIGHT position...");
        }
        break;
      case MOVE2STRAIGHT:  /////// Turnout is moving to straight position
        // set relais when servo reaches middle position
        if ( myServo[toIx].moving() < 50  ) {
          // Servo has reached middle position -> switch relais
          digitalWrite( relPin[toIx], LOW );
        }
        if ( !myServo[toIx].moving()  ) {
          // Servo has reached end position -> next FSM state
          turnoutState[toIx] = STRAIGHT;
          Serial.println("finished");
        }
        break;
    }
  }
}

Wow. I will try this code this morning.
I don't want to use a PCA driver.
This is amazing. Thank you very much.