#include <Servo.h>
//code written to demonstrate managing N servos with left and right pushbuttons, and varying endpoints.
//limitations - as presently arranged, min position must always be left, and must always be less than max position, else all will collapse in a heap.
struct mystruct { //defines a structure for all data relating to one servo
int minpos; //min value for servo
int curpos; //where the servo presently sits
int maxpos; //max value for servo
int leftp; //left button pin
int rightp; //right button pin
int servop; //pin for servo
Servo myservo; //reserves space for the data needed to manage a servo
}; //end mystruct
mystruct servos[] = {//creates 3 instances of that structure in an array
{70, 90, 110, 2, 3, 8},
{70, 90, 110, 4, 5, 9},
{70, 90, 110, 6, 7, 10}, //N.B. compiler generates a warning about an uninitialized component; ignore this
};
const int servoNum = sizeof(servos) / sizeof(servos[0]); //create constant indicating number of servos managed
const int movement = 2; // distance(degrees) to move servo (eg. 2 is small 20 is large movement per update)
//instead of using delay(ms), we will use the accepted millis() construct for implementing timed events
long unsigned int lastupdatetime = 0; //tracking variable for the last time we updated the servos
const long unsigned int cycletime = 100; //we will check the buttons and update the servos every n milliseconds; you can change this to increase/decrease movement speed
void setup() {
Serial.begin(115200); //sets up serial for Serial Monitor use, reporting
for (int index = 0; index < servoNum; index++) { //manage all setup for each servo sequentially
servos[index].myservo.write(servos[index].curpos); //write position (presets servo appropriately)
servos[index].myservo.attach(servos[index].servop);//attach (begins updates for servo)
pinMode(servos[index].leftp, INPUT_PULLUP);
pinMode(servos[index].rightp, INPUT_PULLUP);
} //end setup loop
} //end setup
void loop() {
unsigned long int currenttime = millis(); //get time
if (currenttime - cycletime > lastupdatetime) { //check to see if it's time to check buttons and update servos; see defn of cycletime and currtime, above
lastupdatetime = currenttime; //update our time tracking
for (int index = 0; index < servoNum; index++) { //check, update all servos sequentially
if (!digitalRead(servos[index].leftp)) { //if left pressed
servos[index].curpos = servos[index].curpos - movement; //calc new position
if (servos[index].curpos < servos[index].minpos) servos[index].curpos = servos[index].minpos; //limit if needed
servos[index].myservo.write(servos[index].curpos); //write position
Serial.print(index);
Serial.print(" ");
Serial.println(servos[index].curpos);
} //end if
else if (!digitalRead(servos[index].rightp)) { //else if right pressed (cannot press both, now, can we)
servos[index].curpos = servos[index].curpos + movement; //calc new position
if (servos[index].curpos > servos[index].maxpos) servos[index].curpos = servos[index].maxpos; //limit if needed
servos[index].myservo.write(servos[index].curpos); //write position
Serial.print(index);
Serial.print(" ");
Serial.println(servos[index].curpos);
} //end else if
} //end servo update loop
} //end timed update action
} //end loop