Multiple Servos Sketch . . . .

Hi, first time poster and new to Arduino.

I'm intending to use the Uno R3 to run 7 servos operating points on a model railway.

I found a Sketch (attached - hopefully) elsewhere on this site that allowed a single push-button SPST (momentary) operation of a servo in either direction.

I'm set-up with the SPST attached to Pin 2 & the Servo attached to pin 3 which runs perfectly.
I'd like to run all 7 switches off of Pin 2 using a resistor circuit and attach the servos to pins 3-9.

How do I include the instructions for the other 6 servos in the Sketch so they operate as simultaneously as possible?

#include <VarSpeedServo.h>
const byte switchPinA = 2;
VarSpeedServo servo;
const byte servoPin = 3;
byte switchAstate = HIGH;
byte servoPos = 90;
byte posA = 50;
byte posB = 130;

void setup() {
pinMode(switchPinA, INPUT_PULLUP);
servo.attach(3);
}
void loop () {
readButtons();
moveServo();
}
void readButtons() {
switchAstate = digitalRead(switchPinA);
}
void moveServo() {
if (switchAstate == LOW) {
if (servoPos == posA) {
servoPos = posB;
}
else
{
servoPos = posA;
}
switchAstate = HIGH;
}
servo.write(servoPos, 10, true);
delay(1);
}

One_Button_Servo_Control.ino (596 Bytes)

I would create an array of servo objects.

VarSpeedServo servo[7];  // an array of 7 servo objects

to attach them:

const byte pins[]  =  {3,4,5,6,7,8,9}; // global pin array
// in serup()
for(int n = 0; n < 7; n++)
{
    servo[n].attach(pins[n]);  // servo[0] to pin 3, servo[1] to pin 4, etc,    
}

To write the same thing to all servos:

for(int n = 0; n < 8; n++)
{
    servo[n].write(90); // center all servos
}

to write to a single servo:

servo[3].write(125);

You can use an enum to give names to the servos:

enum crossings  // global crossing names
{
  elm,       //0
  oak,       //1
  pine,      //2
  main_st  //3
};
servo[pine].write(120);  // servo[2] move to 120

Hi Major,
groundfungus gave you a lot of good info. Just some comments on posting code...

To post code and/or error messages:

  1. Use CTRL-T in the Arduino IDE to autoformat your complete code.
  2. Paste the complete autoformatted code between code tags (the </> button)
    so that we can easily see and deal with your code.
  3. Paste the complete error message between code tags (the </> button)
    so that we can easily see and deal with your messages.
  4. If you already posted without code tags, you may add the code tags by
    editing your post. Do not change your existing posts in any other way.
    You may make additional posts as needed.
  5. Please provide links to any libraries that are used
    (look for statements in your code that look like nclude ). Many libraries
    are named the same but have different contents.

Before posting again, you should read the three locked topics at the top of the Programming Questions forum, and any links to which these posts point.

If your project involves wiring, please provide a schematic and/or a wiring diagram and/or a clear photograph of the wiring.

I'd like to run all 7 switches off of Pin 2 using a resistor circuit

You will need to use an analogue input for that. Did you mean pin A2 perhaps ?

A)

Wow! Thanks Groundfungus, that saved me a whole heap o' blood, sweat and tears. I'd tried declaring "servo1, servo2, etc. etc." and was getting problems with "moveServo" not being declared. I was thinking I'd have to go Serial or somesuch route. Array never even crossed my mind. Many, many thanks xXx Will let y'all know how it goes.

B) Ah, ok Vinceherman, I was puzzling over that. I was assuming I could just use an attachment function á la Email. Will know next time. I thought about giving a wiring diagram but, rightly, assumed that those in the Know would realise what I was talking about :wink:

C) UKHeliBob . . . Oh! I must admit that I'm currently using digital Pin 2 because that was what was used in the circuit diagram I based the current build on. I assume that, in the Sketch, once I've rebuilt the set-up, that I'll need to declare "switchPINA = A2" . . . sans parentheses, of course.

So, thanks to Groundfungus, I've written this Sketch and it works.

HOWEVER . . . whilst operating a servo on Pin 3 is almost instantaneous - almost - operating a servo on Pin 9 takes 14 SECONDS between pushing the switch and actual movement of the servo.

Is this normal for an Arduino? Is my code too bulky or long-winded? Please Help!

#include <VarSpeedServo.h>
const byte switchPinA = 16; //active low
VarSpeedServo servo[7];
const byte servoPin = (3, 4, 5, 6, 7, 8, 9);
byte switchAstate = HIGH;
byte servoPos = 90;
byte posA = 50; // new
byte posB = 130; // new

void setup() {
pinMode(switchPinA, INPUT_PULLUP);
for(int n = 0; n < 8; n++)
servo[0].attach(3);
servo[1].attach(4);
servo[2].attach(5);
servo[3].attach(6);
servo[4].attach(7);
servo[5].attach(8);
servo[6].attach(9);
}
void loop () {
readButtons();
moveServo();
}
void readButtons() {
switchAstate = digitalRead(switchPinA);
}
void moveServo() {
if (switchAstate == LOW) {
if (servoPos == posA) {  // new
servoPos = posB;
}
else
{
servoPos = posA;
}
switchAstate = HIGH; // new
}
servo[0].write(servoPos, 10, true);
servo[1].write(servoPos, 10, true);
servo[2].write(servoPos, 10, true);
servo[3].write(servoPos, 10, true);
servo[4].write(servoPos, 10, true);
servo[5].write(servoPos, 10, true);
servo[6].write(servoPos, 10, true);
delay(1); // modified
}
  for (int n = 0; n < 8; n++)
    servo[0].attach(3);
  servo[1].attach(4);
  servo[2].attach(5);
  servo[3].attach(6);
  servo[4].attach(7);
  servo[5].attach(8);
  servo[6].attach(9);

You might want to look at the code in that for loop as it is a waste of time having the for loop as currently written. It is not causing the problem that you describe but it is also not doing what you think.

I am not familiar with the VarSpeedServo library but is its write() function blocking ?

You really need to RTFM.

write(value, speed) - speed varies the speed of the move to new position 0=full speed, 1-255 slower to faster
write(value, speed, wait) - wait is a boolean that, if true, causes the function call to block until move is complete

So the way you have written the code, servo[0] move must complete before servo[1] can start to move, servo[1] must complete before servo[2] can start and down the line. Remove the true from the end to get simultaneous moves [servo[0].write(pos, 10);]

The main point of using arrays is that you can use a for loop to iterate through an array.

This

for(int n = 0; n < 8; n++) // useless for loop attaches servo[0] 8 times

servo[0].attach(3);
servo[1].attach(4);
servo[2].attach(5);
servo[3].attach(6);
servo[4].attach(7);
servo[5].attach(8);
servo[6].attach(9);

Can be

for(int n = 0; n < 7; n++)
{
servo[n].attach(servoPin[n]);
}

and this

servo[0].write(servoPos, 10, true);
servo[1].write(servoPos, 10, true);
servo[2].write(servoPos, 10, true);
servo[3].write(servoPos, 10, true);
servo[4].write(servoPos, 10, true);
servo[5].write(servoPos, 10, true);
servo[6].write(servoPos, 10, true);

like this (modified to not block)

for(int n = 0; n < 7; n++)
}
  servo[n].write(servoPos, 10);
}

Ah, thank you. That's most helpful.

Just so's you know, this Sketch has been somewhat of a grab from various places and is rather ad hoc. It's all very well telling me to oh-so politely RTFM but if'n I'm not C-literate it's a bit of a non-starter. I'm doing my best for a 52 yr old guy, and considering I only got the Arduino 5 days ago I reckon I'm doing reasonably okay in even getting a Sketch THIS Far.

EVERYBODY is a noob to begin with, yeah!?! :confused:

I apologize if I was not polite enough. I will be glad to provide as much assistance as I can. I know that C++ (and coding in general) is not easy to learn. But copying code without knowing, exactly, what it does will only lead to frustration. That is where the library references, language reference and questions here come in. Not using advice because it does not apply is one thing, but not using advice because you don't understand it is another. If you don't understand, ask.