So, I'm working on a project in which I needed to, at the press of a button, move two servos simultaneously to a 90-degree position and then, when I press the button again, return the servos to 0 degrees (neutral). I just wanted to share the program with others to make the switch action easier.
{
while (!digitalRead(button)){} // While button is not pushed do nothing
while (digitalRead(button)){} // When button is pushed satify above condition
if (servoState){ // When servo state nuetral move to 90 degrees on servo(s)
myservo.write(100);
myservo2.write(100);
}
else{ //When servo state active (not nuetral) return to 0 degrees (nuetral) on servo(s)
myservo.write(10);
myservo2.write(10);
}
servoState = !servoState; // reset servo state to nuetral
}
it's always a good idea to not rely on automatic promotion and the fact that LOW is 0. These should be written as
while (digitalRead(buttonPin) == LOW) {} // While button is not pushed do nothing
while (digitalRead(buttonPin) == HIGH) {} // When button is pushed satisfy above condition
And if your button is bouncing, this won't work anyway...
Using a button library would make the code much easier to read.
see the example here
click to see the code
#include <Servo.h>
#include <Toggle.h>
const byte servoPin = 3;
const byte buttonPin = 12;
enum {SERVO_0, SERVO_90} servoPosition = SERVO_0;
Toggle button;
Servo servo;
void moveTo0() {
servo.write(0);
servoPosition = SERVO_0;
}
void moveTo90() {
servo.write(90);
servoPosition = SERVO_90;
}
void setup() {
button.begin(buttonPin);
servo.attach(servoPin);
moveTo0();
}
void loop() {
button.poll();
if (button.onPress()) { // we got a new button press
switch (servoPosition) { // handle the change based on current position
case SERVO_0: moveTo90(); break; // we were at 0°, move to 90°
case SERVO_90: moveTo0(); break; // we were at 90°, move to 0°
}
}
}
Capacitors are often recommended for powering servo motors. They help stabilize the power supply, minimize voltage drops, and reduce electrical noise. The specific capacitor values may vary based on the servo motor's requirements, but including them is good practice for better performance and reliability.
I built your project and it is nearly impossible to consistently toggle the servo. You have seen it, I am sure, and now you know it is because the processor is very fast, and pushbuttons bounce, that is to say there is a brief period when they are in transition where the value read will go back and forth.
But not so fast or brief that a sketch doesn't have plenty of time to see in between values and make it right through your logic gate at the top.
But the logic gate idea is clever - so I added just a bit of delay to each part of the gate, so the bouncing gets absorbed or ignored.
This is a bad way to handle the problem, but I thought you deserved to see it work, with just a tiny fix.
Play with it here:
Your code, with the fix and some plausible extra stuff to make a complete sketch:
Another way to fix it is to use buttons that do not bounce. IRL these are hard to come by, not normal at all. In the simulator, you can turn off the bouncing that it simulates, and see perfect buttons validate your two step logic gate.
Try it for fun: replace the delays with your original do-nothing {}, and click on the pushbutton in the diagram and turn off bouncing in the dialog that pops up. When the skethc is not running.
to your setup() function, then use serial printing at various places to see your logic flow. It is a good way to see if the flow through your code is what you think... it should never be a surprise to find out how yuor code is working, but it happens.