This is my first time using ardunio and c++. I am trying to move a servo to multiple positions 70, 100, 110 with three buttons and always have servo return to 90 when a button is not pressed. I do not want a sweep but rather if I hold button it stays at angle till I release the button. I have had success with this with one button but when I add a second or third button my code fights it's self. I understand this is because the code has buttons all trying to return to 90 currently. So I need to figure out how to make buttons ignored or have return to 90 set earlier in code perhaps.
This was one button that was successful.
#include <Servo.h>
// Define servo and button pins
const int servoPin = 9; // Pin connected to the servo's control signal
const int buttonPin = 2; // Pin connected to the button
// Create servo object
Servo myServo;
void setup() {
// Attach the servo to the specified pin
myServo.attach(servoPin);
// Set the button pin as an input
pinMode(buttonPin, INPUT_PULLUP);
}
void loop() {
// Check if the button is pressed
if (digitalRead(buttonPin) == LOW) { // Assuming button is active LOW
// Move the servo to 110 degrees while the button is pressed
myServo.write(110);
// Wait for the servo to reach the position
delay(5); // Adjust delay as needed
} else {
// Move servo back to 90 degrees when button is released
myServo.write(90);
delay(5); // Adjust delay as needed
}
}
This is two button code that has buttons not holding servo in position.
#include <Servo.h>
// Define servo and button pins
const int servoPin = 9; // Pin connected to the servo's control signal
const int buttonPin1 = 2;
const int buttonPin2 = 4;
// Create servo object
Servo myServo;
void setup() {
// Attach the servo to the specified pin
myServo.attach(servoPin);
pinMode(buttonPin1, INPUT_PULLUP);
pinMode(buttonPin2, INPUT_PULLUP);
}
void loop() {
// Check if the button is pressed
if (digitalRead(buttonPin1) == LOW) { // Assuming button is active LOW
// Move the servo to 30 degrees while the button is pressed
myServo.write(120);
// Wait for the servo to reach the position
delay(5); // Adjust delay as needed
} else {
// Move servo back to 0 degrees when button is released
myServo.write(90);
delay(5); // Adjust delay as needed
}
// Check if the button is pressed
if (digitalRead(buttonPin2) == LOW) { // Assuming button is active LOW
// Move the servo to -30 degrees while the button is pressed
myServo.write(60);
// Wait for the servo to reach the position
delay(5); // Adjust delay as needed
} else {
// Move servo back to 0 degrees when button is released
myServo.write(90);
delay(5); // Adjust delay as needed
}
}
The code will always execute the check for the second button being pressed and hence will always move the servo to 60 or 90 even if the first button is pressed
You need to change the program logic so that the servo is moved to the appropriate angle if any of the buttons is pressed or, if not, then move it to 90
#include <Servo.h>
// Define servo and button pins
const int servoPin = 9; // Pin connected to the servo's control signal
const int buttonPin1 = 2;
const int buttonPin2 = 4;
const int buttonPin3 = 8;
// Create servo object
Servo myServo;
void setup() {
// Attach the servo to the specified pin
myServo.attach(servoPin);
pinMode(buttonPin1, INPUT_PULLUP);
pinMode(buttonPin2, INPUT_PULLUP);
pinMode(buttonPin3, INPUT_PULLUP);
}
void loop() {
// Check if the button is pressed
if (digitalRead(buttonPin1) == LOW) { // Assuming button is active LOW
// Move the servo to 110 degrees while the button is pressed
myServo.write(110);
// Wait for the servo to reach the position
delay(5); // Adjust delay as needed
}
// Check if the button is pressed
else if (digitalRead(buttonPin2) == LOW) { // Assuming button is active LOW
// Move the servo to 70 degrees while the button is pressed
myServo.write(70);
// Wait for the servo to reach the position
delay(5); // Adjust delay as needed
}
// Check if the button is pressed
else if (digitalRead(buttonPin3) == LOW) { // Assuming button is active LOW
// Move the servo to 100 degrees while the button is pressed
myServo.write(100);
// Wait for the servo to reach the position
delay(5); // Adjust delay as needed
} else {
// Move servo back to 0 degrees when button is released
myServo.write(90);
delay(5); // Adjust delay as needed
}
}
Personally I would prefer a more data driven sketch in order to cut down code and prevent "magic" numbers being scattered through the code. This comes at the expense of needing to know about arrays and structs but it does make the code more maintainable and easier to expand if/when needs change
Something like this (untested !)
#include <Servo.h>
struct dataLayout //data needed for each button and servo angle
{
const byte buttonPin;
const byte servoAngle;
};
dataLayout data[] = {
{ 2, 110 }, //button pin, corresponding servo angle
{ 4, 70 },
{ 8, 180 } //add more button pins and angles if needed
};
// Define servo pin
const int servoPin = 9; // Pin connected to the servo's control signal
const byte buttonCount = sizeof(data) / sizeof(data[0]); //calculate number of buttons even if more have been added
// Create servo object
Servo myServo;
void setup()
{
// Attach the servo to the specified pin
myServo.attach(servoPin);
for (int b = 0; b < buttonCount; b++)
{
pinMode(data[b].buttonPin, INPUT_PULLUP); //pinMode for each input
}
}
void loop()
{
// Check each button to see whether it is pressed
for (int b = 0; b < buttonCount; b++)
{
if (digitalRead(data[b].buttonPin) == LOW) //test button state
{
myServo.write(data[b].servoAngle); //write corresponding angle to servo
delay(5); // Adjust delay as needed
}
else
{
// Move servo back to 90 degrees when no button is pressed
myServo.write(90);
delay(5); // Adjust delay as needed
}
}
}
else
{
// Move servo back to 90 degrees when no button is pressed
myServo.write(90);
delay(5); // Adjust delay as needed
}
looks like it will tell the servo to move back for each button that is not pressed.
Untested:
#include <Servo.h>
struct dataLayout //data needed for each button and servo angle
{
const byte buttonPin;
const byte servoAngle;
};
dataLayout data[] = {
{ 2, 110 }, //button pin, corresponding servo angle
{ 4, 70 },
{ 8, 180 } //add more button pins and angles if needed
};
// Define servo pin
const int servoPin = 9; // Pin connected to the servo's control signal
const byte buttonCount = sizeof(data) / sizeof(data[0]); //calculate number of buttons even if more have been added
// Create servo object
Servo myServo;
void setup()
{
// Attach the servo to the specified pin
myServo.attach(servoPin);
for (int b = 0; b < buttonCount; b++)
{
pinMode(data[b].buttonPin, INPUT_PULLUP); //pinMode for each input
}
}
void loop()
{
bool anyButton = false;
// Check each button to see whether it is pressed
for (int b = 0; b < buttonCount; b++)
{
if (digitalRead(data[b].buttonPin) == LOW) //test button state
{
myServo.write(data[b].servoAngle); //write corresponding angle to servo
delay(5); // Adjust delay as needed
anyButton = true;
// break; // stop looking at the other buttons?
}
}
if (not anyButton)
{
// Move servo back to 90 degrees when no button is pressed
myServo.write(90);
delay(5); // Adjust delay as needed
}
}
Move to any pressed button's position. Move back if no buttons were seen as pushed.
void loop()
{
int servoPosition = 90; // unless we learn otherwise
// Check each button to see whether it is pressed
for (int b = 0; b < buttonCount; b++)
{
if (digitalRead(data[b].buttonPin) == LOW) //test button state
{
servoPosition = data[b].servoAngle); // set corresponding angle for servo
// break; // stop looking at the other buttons?
}
}
myServo.write(servoPosition);
delay(5); // Adjust delay as needed
}