16 servos with 16 toggle switches

I would like to know if there is way we can control 16 servos with 16 toggle switches. Each toggle switch for each servo. The switch will be either left at 45 degree or right at 45 degree. Can we do that on Arduino Uno or Mega board? I found some information with push button but I rather to use toggle switch. I need some information on schematic and code for it. I will use it for my HO train.

Reid

A push button is one side of a toggle switch. Wire one side of the toggle switch like below, and don’t wire the other side.

//zoomkat servo button test 7-30-2011

#include <Servo.h>
int button1 = 4; //button pin, connect to ground to move servo
int press1 = 0;
Servo servo1;

void setup()
{
  pinMode(button1, INPUT);
  servo1.attach(7);
  digitalWrite(4, HIGH); //enable pullups to make pin high
}

void loop()
{
  press1 = digitalRead(button1);
  if (press1 == LOW)
  {
    servo1.write(160);
  }
  else {
    servo1.write(20);
  }
}

Need a mega for up to 48 Servo's. Uno will only do 12. Then code like above.

I wrote the following demo sketch for another forum. It works 9 servos on an Uno. Obviously a lot more are possible on a Mega.

// a simple Arduino Sketch to control 9 servos for point or signal control
//   using 9 toggle switches.
// each servo moves between one of two position depending on the switch setting
// each servo can have different limits to it's movement

// the servos must not be powered from the Arduino, it can't supply enough current
//   typical wiring for the servos is like this
//
//   Arduino servo pin -------------------Servo Signal wire (Orange or white perhaps)
//   Power supply Positive -------------- Servo Positive (Centre wire - red) 
//   Power supply Ground   -------------- Servo Ground (Black or Brown wire)
//                             |
//   Arduino Ground -----------     (NB Arduino Ground must be connected to power supply ground)

// The toggle switches should be connected so that when switched they connect the Arduino switch pin to ground
//
//  Arduino Switch pin ---------- \---------- Arduino Ground
//
//  If the switch moves the servo in the wrong direction turn the switch around in it's mounting

//  The high and low positions can be set separately for each servo by editing the data in the
//    arrays servoLowPos and servoHighPos. In the program as written they are all set to 50 and 150 degrees.


#include <Servo.h>

Servo pointServo[9];

byte servoPin[] =     {  2,   3,   4,   5,   6,   7,   8,   9,  10}; // pin numbers for servo signals
byte switchPin[] =    { 19,  18,  17,  16,  15,  14,  13,  12,  11}; // pin numbers for switch connections
// Uno analog pins      A5   A4   A3   A2   A1   A0
byte servoLowPos[] =  { 50,  50,  50,  50,  50,  50,  50,  50,  50}; // degrees for low servo position
byte servoHighPos[] = {150, 150, 150, 150, 150, 150, 150, 150, 150}; // degrees for high servo position

byte servoPos[9];


void setup() {
  setupServos();
  setupSwitches();
}

void loop() {
  for (byte n = 0; n < 9; n++) {
     boolean servoMove = false;
     byte sw = digitalRead(switchPin[n]);
     if (sw == HIGH) {
        if (servoPos[n] != servoHighPos[n]) { // check if the position has changed
          servoMove = true;
          servoPos[n] = servoHighPos[n];
        }
     }
     else {  // if sw == LOW
       if (servoPos[n] != servoLowPos[n]) {  // check if the position has changed
          servoMove = true;
          servoPos[n] = servoLowPos[n];
       }
     }
     if (servoMove) {  // only move the servo if the switch has changed
        pointServo[n].write(servoPos[n]);
     }
  }
}

void setupServos() {
  for (byte n = 0; n < 9; n++) {
    pointServo[n].attach(servoPin[n]); 
    servoPos[n] = servoLowPos[n]; // this is just a starting value and may be over-ridden immediately by a switch
  }
}

void setupSwitches() {
  for (byte n = 0; n < 9; n++) {
     pinMode(switchPin[n], INPUT_PULLUP);
  }
}

…R

Thank you for input. I have some more question. I would like to use double pole single throw switch. One pole goes right and other pole goes left. I assume I will need to use two pins from arduino for each switch. How many pins does arduino n mega has? I don't have mega but I do have arduino uno. I will not use all servos at the same time. I will use one severo at one time.

Hi, do you mean SIngle Pole, Double Throw, that is a three terminal switch that in one postion is center to left term, in other position center to right term.

If all you need is two servo positions, and you are using internal pullups, connect the arduino input to the centre term of the switch and gnd to one of the other outside terminals. This will then give a HIGH input when switch is open and LOW input when switch is closed.

Tom..... :)

Hi people. First I´m sorry for wakening an old thread, but I just started with Arduino and found almost what I need/want here. I tryed the sketch from Robin2 in answer #3, it works perfectly and I really like when all the servopositions are easily accesible in the program, but I would like to use momentary off-(on) switches for the toggling. The reason is that I want to control the servos from different locations with fixed controlpanels. The answer might be somewhere else here on the forum but I can´t find it, maybe I don´t search correctly or misspelling (I am a Swede...)

Robert

Olds98: but I would like to use momentary off-(on) switches for the toggling.

Are you planning to have two switches for each servo - one to indicate the left position and the other to indicate the right position?

...R

Have a look at the StateChangeDetection example, which might give you some ideas. The example counts the presses: what you need to do with a button to use it as a toggle switch is check that it has just been pressed.

Robin2: Are you planning to have two switches for each servo - one to indicate the left position and the other to indicate the right position?

...R

No, the idea is to use only one switch / servo. Like this one This maybe or similar.

manor_royal: Have a look at the StateChangeDetection

That link only show me a picture of someone in military outfit?

Robert

Olds98: That link only show me a picture of someone in military outfit?

Crap, sorry. Forgot to ctrl-C when I highlighted the url. Fixed it now.

That sparkfun link gives me an empty page.

But if you use one button per servo, then you can use the state change detect approach I linked. Every odd press will be left, every even will be right.... you should be able to figure out something along those lines.

I was bored this afternoon so I put together a sketch that uses the Bounce2 library to debounce a button then uses the StateChangeDetect approach to see if it's a new press, and alternately moves servo left and right.

You're welcome to it, but I won't post it yet in case you relish the challenge.

Olds98:
No, the idea is to use only one switch / servo.

That can certainly be done.

In the program in Reply #3 there are these lines

byte sw = digitalRead(switchPin[n]);
    if (sw == HIGH) {

You need to create some code to fit with a modified version of that … something like

byte sw = swState[n]);
    if (sw == HIGH) {

You can use your push-buttons to cause the value in buttonVal[n] to toggle with something like this

for (byte n = 0; n < numButton; n++) {
  prevSwVal = switchVal[n];
  switchVal[n] = digitalRead(switchPin[n];
  if (prevSwVal != switchVal[n]) {
     swState[n] = ! swState[n];
  }
}

However one complication with just using 1 button per servo is that you can’t tell which way it is set, unless perhaps you also have an LED to indicate the setting.

A short interval (maybe 50 millisecs) between each iteration of reading all the switches would be a good idea to avoid switch bounce. You can see how to do that using millis() in the demo Several Things at a Time

…R

Robin2: However one complication with just using 1 button per servo is that you can't tell which way it is set, unless perhaps you also have an LED to indicate the setting.

The code I mention in #12, and which OP may or may not ask for, does exactly that, using the R & G of an RGB LED to indicate the servo is at port or starboard.

Thank´s guy´s, I will try Robin´s later on tonight, and if you manor would upload you sketch I try that one to. It will be some ours till I can try anything because my kids has decided to jump on my head and fight all day so far............ I only get som few minutes at a time for my self at the computer.

Robert

Here you go…

It has a load of stuff in there that you may want to take out, mostly debugging. But you may like to leave them in so you can better follow the logic at first.

It’s one button and one servo: assuming you like the approach you’ll need to do the array thing to handle so many. But the general idea is I think sound: it debounces the button (I bought crap ones) then checks to see if it’s newly pressed (active low). Then if it is a new press, it toggles the servo between left and right, also has 2x indicator LEDs.

//http://forum.arduino.cc/index.php?topic=226116

//debounced button to control a servo
//alternate presses move servo left or right
//initialised left
//also lights one of two leds to show it's working if no servo available

//there are 3 possibilites with a button:
//   unchanged (and either high or low)
//   changed, gone high
//   changed, gone low
// only the last moves the servo (active low button with pullup)
// others are in the code but do nothing except serial print to show they are there

#include <Bounce2.h>
#include <Servo.h>
Servo myservo;

#define BUTTON_PIN 2
#define LED_LEFT 6
#define LED_RIGHT 7
#define IS_PRESSED LOW //button has a pullup, so active low

int buttonState = 0;         // current state of the button
int lastButtonState = 1;     // previous state of the button, starts unpressed,ie high

bool facingLeft;
byte angleLeft = 45;
byte angleRight = 135;

// Instantiate a Bounce object
Bounce debouncer = Bounce();

void setup() {
  // put your setup code here, to run once:
  Serial.println("starting setup");
  Serial.begin(9600);

  // Setup the button
  pinMode(BUTTON_PIN, INPUT_PULLUP);

  // After setting up the button, setup debouncer
  debouncer.attach(BUTTON_PIN);
  debouncer.interval(5);

  //Setup the LEDs
  pinMode(LED_LEFT, OUTPUT);
  pinMode(LED_RIGHT, OUTPUT);
  //blink leds to say hello
  digitalWrite(LED_LEFT, HIGH);
  digitalWrite(LED_RIGHT, HIGH);
  delay(1000);
  digitalWrite(LED_LEFT, LOW);
  digitalWrite(LED_RIGHT, LOW);
 
  
  //initialise direction
  facingLeft = true; //........change this if necessary
  if (facingLeft)
  {
    Serial.println("Initializing left");
    myservo.write(angleLeft);
    digitalWrite(LED_LEFT, HIGH);
    digitalWrite(LED_RIGHT, LOW);
  }
  else
  {
    Serial.println("Initializing right");
    myservo.write(angleRight);
    digitalWrite(LED_LEFT, LOW);
    digitalWrite(LED_RIGHT, HIGH);
  }
  myservo.attach(9);
  delay(1000);
  
  Serial.println("leaving setup");
}

void loop() {
  // put your main code here, to run repeatedly:
  // Update the debouncer
  debouncer.update();

  // Get the update value
  buttonState = debouncer.read(); //this is the Bounce2 answer to digitalRead
  Serial.print(buttonState);
  Serial.print(lastButtonState);
  if (buttonState != lastButtonState)
  { //changed
    if (buttonState == IS_PRESSED)
    { //changed and pressed
      Serial.print(" pressed");
      //button was pressed so it's time to flip the servo
      flipServo(); //see below loop()
    } //changed and pressed
    else //changed and unpressed
    {
      Serial.println(" unpressed");
    }//changed and unpressed
  }//changed
  else //no change
  {
    Serial.println(" nochange");
  }//no change

  lastButtonState = buttonState;
  //delay(500); //to slow the serial prints down
}//loop

void flipServo()
{
  Serial.print(" flipping the servo to the ");
  if (facingLeft)
  {
    Serial.println(" right");
    myservo.write(angleRight);
    digitalWrite(LED_LEFT, LOW);
    digitalWrite(LED_RIGHT, HIGH);
    facingLeft = false;
  }
  else //was facing right
  {
    Serial.println(" left");
    myservo.write(angleLeft);
    digitalWrite(LED_LEFT, HIGH);
    digitalWrite(LED_RIGHT, LOW);
    facingLeft = true;
  }
}//flipservo

oops.... servo.attach() was missing in above after an edit... it's back now if you already copied it.

manor_royal: That sparkfun link gives me an empty page.

Try it now it might work.

Robert

Olds98: Try it now it might work.

Pretty much what I used to test- mine aren't so fancy