FEBaily:
And you can't use pin 13, it's got the pulse led on it...
Nor can pin 7 be a button and a servo at the same time....
const byte buttonPins[] = {7, 8, 12, 13};
const int myServoPins[] = {4, 6, 7, 11};
(And I think that's your actual problem. Along with making that array all 0's as previous.)
Servos don't need to be on PWM ~ pins btw, and pins are good, even the analog pins Ax.
i now have the 4 servos connected to pins 8, 9, 10, 11 and the buttons on pins 0, 1, 2, 3
i've updated the code and there is still one rogue servo which is constantly turning clockwise and counter clockwise for about 3 seconds at a time without any input from the corresponding button. (pressing the button does nothing)
// https://forum.arduino.cc/index.php?topic=638602
// state change detect on a button array to drive an array of servos
// OP was silent on what happens if button is pressed while servo running
// so this version just re-starts the clock
// servos' run speed, stop speed (nominally 90) and time it should run are all independent and in arrays
// 1 october 2019
// set the values in the lines marked //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
// run with serial monitor open to read what's happening
// DISCLAIMER... tested on real servos moving to a position, not on continuous "not-really-"servos running at some speed
// BASED ON State change detection (edge detection), changed for INPUT PULLUP https://www.arduino.cc/en/Tutorial/StateChangeDetection
// INCLUDES delay()-less millis()-based bwod pulse pin 13 https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
// SERVO ARRAY idea from PaulS https://forum.arduino.cc/index.php?topic=170597.0
// the buttons
const byte buttonPins[] = {0, 1, 2, 3}; //remember indexed from 0 //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
// add as many pins as you can handle servos
// the buttons must be wired from pin to ground, pinmodes are input_pullup
const byte howManyButtons(sizeof(buttonPins));
bool buttonStates[howManyButtons]; // current state of the button
bool lastButtonStates[howManyButtons]; // previous state of the button
bool buttonIsNewlyPressed[howManyButtons] = {0, 0, 0, 0};
//the servos
#include <Servo.h>
Servo myServos[howManyButtons]; //number of servos will be same as number of buttons
const int myServoPins[] = {8, 9, 10, 11}; //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
const int myServoSpeeds[] = {100, 100, 100, 100}; // or whatever //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
const int myServoStops[] = {90, 90, 90, 90}; //nominally but not necessarily 90 //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
const int myServoIntervals[] = {3000, 3000, 3000, 3000}; //this is how long they run for //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
unsigned long myServoStartedToMoveAt[howManyButtons];
int myServoIsRunning[] = {0, 0, 0, 0}; //this is just to stop the serial print spewing when servo's time is up
//the pulse led
const int pulseLedInterval = 500;
unsigned long previousMillisPulse;
bool pulseState = false;
void setup()
{
// initialize serial communication:
Serial.begin(9600); //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
Serial.print("setup() ... ");
Serial.println("run servos with buttons forum thread 638602 ....");
Serial.println(__FILE__);
Serial.print("Compiler: ");
Serial.print(__VERSION__);
Serial.print(", Arduino IDE: ");
Serial.println(ARDUINO);
Serial.print("Created: ");
Serial.print(__TIME__);
Serial.print(", ");
Serial.println(__DATE__);
// initialize the button pins as input with pullup so active low
// make sure the button is from pin to ground
for (int i = 0; i < howManyButtons; i++)
{
pinMode(buttonPins[i], INPUT_PULLUP);
//initialize button states
buttonStates[i] = digitalRead(buttonPins[i]);
lastButtonStates[i] = buttonStates[i];
}
//initialise pulse led
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, pulseState);
//attach the servos
for (int i = 0; i < howManyButtons; i++)
{
myServos[i].attach(myServoPins[i]);
Serial.print("Servo ");
Serial.print(i);
Serial.print(" is on pin ");
Serial.println(myServoPins[i]);
}
Serial.println("setup() done");
Serial.println("Press a button to start its servo....");
Serial.println(" ");
}
void loop()
{
pulse(); // to prove nothings blocking
checkButtons();
manageServos();
} //loop
void checkButtons()
{
for (int i = 0; i < howManyButtons; i++)
{
buttonStates[i] = digitalRead(buttonPins[i]);
// compare the buttonState to its previous state
if (buttonStates[i] != lastButtonStates[i]) // means it changed... but which way?
{
if (buttonStates[i] == LOW) // changed to pressed
{
//Serial.print(i);
//Serial.println(" newly pressed");
buttonIsNewlyPressed[i] = true;
}
// poor man's de-bounce
delay(50);
}
// save the current state as the last state, for next time through the loop
lastButtonStates[i] = buttonStates[i];
}
} // checkButtons()
void manageServos()
{
for (int i = 0; i < howManyButtons; i++)
{
if (buttonIsNewlyPressed[i])
{
Serial.print("Starting servo ");
Serial.print(i);
buttonIsNewlyPressed[i] = false;
myServos[i].write(myServoSpeeds[i]);
myServoStartedToMoveAt[i] = millis();
myServoIsRunning[i] = true;
Serial.print(" at ");
Serial.print(myServoStartedToMoveAt[i]);
Serial.print(" for ");
Serial.print(myServoIntervals[i]);
Serial.println("ms");
}
if (millis() - myServoStartedToMoveAt[i] >= myServoIntervals[i] && myServoIsRunning[i])
{
myServoIsRunning[i] = false;
myServos[i].write(myServoStops[i]);
Serial.print(" Stopping servo ");
Serial.print(i);
Serial.print(" at ");
Serial.println(millis());
}
}//which button
}//manageServos
void pulse()
{
if (millis() - previousMillisPulse >= pulseLedInterval)
{
previousMillisPulse = millis();
pulseState = !pulseState;
digitalWrite(LED_BUILTIN, pulseState);
}
} //pulse
here's the serial log:
setup() ... run servos with buttons forum thread 638602 ....
C:\Users\ethan\AppData\Local\Temp\arduino_modified_sketch_104745\sketch_oct02a.ino
Compiler: 7.3.0, Arduino IDE: 10810
Created: 16:51:34, Oct 2 2019
Servo 0 is on pin 8
Servo 1 is on pin 9
Servo 2 is on pin 10
Servo 3 is on pin 11
setup() done
Press a button to start its servo....
Starting servo 1 at 404 for 3000ms
Stopping servo 1 at 3404
Starting servo 1 at 3454 for 3000ms
Stopping servo 1 at 6454
Starting servo 1 at 6504 for 3000ms
Stopping servo 1 at 9504
Starting servo 1 at 9554 for 3000ms
Stopping servo 1 at 12554
Starting servo 1 at 12604 for 3000ms