Totally new and need 3 button help

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
  }
}

Any help would be great

Welcome to the forum

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

Remove the first else.
substitute the second if for button2 with else if

Thanks everyone. I have it working now.

Please post the updated code for the benefit of others

This is my three button code is now working.

#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
  }
}

Thank you

Looks simple and good.

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
        }
    }
}

I did not test it either.

This, however briefly

        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.

a7

You are right and your suggestion to use a boolean to flag the fact that none of the buttons are pressed will deal with that

Different way:

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
}

a7

Hello sm08_jb

Welcome to the best Arduino forum ever.

Here is a simple example for your project.

The sketch is not tested as I have no servos in the workshop.

Just try it out and play with it to learn.

// https://forum.arduino.cc/t/totally-new-and-need-3-button-help/1368340
// make names
enum Numbers {One, Two, Three, Four};
enum ButtonState {Pressed, Released};
//make variables
const uint16_t Angels[] {70, 100, 110, 90};
const uint8_t ServoPins[] {9, 10, 11};
const uint8_t ButtonPins[] {A0, A1, A2};
// include libary and create servo objects
#include <Servo.h>
Servo myServo[sizeof(ServoPins)];

void setup()
{
  uint8_t index = 0;
  for (auto ServoPin : ServoPins)
  {
    myServo[index].attach(ServoPin);
    index++;
  }
  for (auto ButtonPin : ButtonPins) pinMode (ButtonPin, INPUT_PULLUP);
}
void loop()
{
  uint8_t index = 0;
  for (auto ButtonPin : ButtonPins) 
  {
    digitalRead(ButtonPin) == Pressed ? myServo[index].write(Angels[index]): myServo[index].write(Angels[Four]);
    index++;
  }
  delay (10); 
}