Servo Control with three buttons. (resolved and working!!!)

Hello Arduino community,
I am building a project that includes 3 buttons, lets say “buttonA”, “buttonB”, and “buttonC.” My circuit will also include a servo.
I am attempting to write some code that says that “if buttonA is pressed, and if buttonB is pressed, than turn the servo in a specific pattern.” However, "if buttonA is pressed, and if buttonC is pressed, than turn the servo in a different pattern.
Obviously, I don’t want to have to press both buttons “A and B” or “A and C” at the same time, simultaneosly. I want to be able to press one button(A) and then press either of the other buttons (B or C) a few seconds later.

How could I go about being able to press button(A) and then press either of the other buttons (B or C) a few seconds later without having to press them simultaneouly?

Here is my code…

#include <Servo.h>

Servo myservo; // creating myservo object
int buttonA = 2; // one side of buttonA attached to pin 2 and 10K resistor to ground, while other is on +5V
int buttonB = 3; // one side of buttonB attached to pin 3 and 10K resistor to ground, while other is on +5V
int buttonC = 4;  // one side of buttonC attached to pin 4 and 10K resistor to ground, while other is on +5V
int servoPin = 11;  //servo attached to pin 11
int AState = 0; // set AState 
int BState = 0; // set BState
int CState = 0; // set CState

void setup()
{
myservo.attach(servoPin); 
pinMode(buttonA, INPUT); 
pinMode(buttonB, INPUT);
pinMode(buttonC, INPUT);
}


void loop()
{AState = digitalRead(buttonA); // read and save to the variable "AState" the actual state of button
{BState = digitalRead(buttonB); // read and save to the variable "BState" the actual state of button
{CState = digitalRead(buttonC); // read and save to the variable "CState" the actual state of button
if (AState == HIGH){
  if (BState == HIGH){
    myservo.write(50);
    delay(1000);
    myservo.write(111);
    delay(1000);
}
  }
else
myservo.write(90);

if (AState == HIGH){
  if(CState == HIGH){
    myservo.write(130);
    delay(1000);
    myservo.write(70);
    delay(1000);
}
}
else
myservo.write(90);

}
}
}

Here is my code...

..... but where is your question?

Make some changes to your code. Put every { on a new line. Put NOTHING else after the {. Use Tools +Auto Format. Then, explain WHY your code looks like this:

void loop()
{
  AState = digitalRead(buttonA); // read and save to the variable "AState" the actual state of button
  {
    BState = digitalRead(buttonB); // read and save to the variable "BState" the actual state of button
    {
      CState = digitalRead(buttonC); // read and save to the variable "CState" the actual state of button
      if (AState == HIGH)
      {
        if (BState == HIGH)
        {
          myservo.write(50);
          delay(1000);
          myservo.write(111);
          delay(1000);
        }
      }
      else
        myservo.write(90);

Why does moving myservo depend on the state of both switches?

Here is the auto formatted code…

#include <Servo.h>

Servo myservo; // creating myservo object
int buttonA = 2; // one side of buttonA attached to pin 2 and 10K resistor to ground, while other is on +5V
int buttonB = 3; // one side of buttonB attached to pin 3 and 10K resistor to ground, while other is on +5V
int buttonC = 4;  // one side of buttonC attached to pin 4 and 10K resistor to ground, while other is on +5V
int servoPin = 11;  //servo attached to pin 11
int AState = 0; // set AState 
int BState = 0; // set BState
int CState = 0; // set CState

void setup()
{
  myservo.attach(servoPin); 
  pinMode(buttonA, INPUT); 
  pinMode(buttonB, INPUT);
  pinMode(buttonC, INPUT);
}


void loop()
{
  AState = digitalRead(buttonA); // read and save to the variable "AState" the actual state of button
  {
    BState = digitalRead(buttonB); // read and save to the variable "BState" the actual state of button
    {
      CState = digitalRead(buttonC); // read and save to the variable "CState" the actual state of button
      if (AState == HIGH){
        if (BState == HIGH){
          myservo.write(50);
          delay(1000);
          myservo.write(111);
          delay(1000);
        }
      }
      else
        myservo.write(90);

      if (AState == HIGH){
        if(CState == HIGH){
          myservo.write(130);
          delay(1000);
          myservo.write(70);
          delay(1000);
        }
      }
      else
        myservo.write(90);

    }
  }
}

Here is the auto formatted code...

.... but you still haven't posed a question. So what do you expect members to do?

Here is the question... I have also edited my original post. Thank you for pointing out this error!

How could I go about being able to press button(A) and then press either of the other buttons (B or C) a few seconds later without having to press them simultaneouly? Currently, with the code that I am running, this is what I have to do.

I think you’re on the right track with the state idea, but you have a lot of extra {} pairs in there and I’m not personally sure what effect that’s having. See <<<<<< below.

void loop()
{    // this one is needed since it starts lopp() <<<<<<<<
  AState = digitalRead(buttonA); // read and save to the variable "AState" the actual state of button
  {     // this and its closing partner are a bit weird <<<<<<<<<<<
    BState = digitalRead(buttonB); // read and save to the variable "BState" the actual state of button
    {    // this and its closing partner are a bit weird <<<<<<<<<<<
      CState = digitalRe

As I said, I’m not sure what effect those have but I’m pretty sure you can lose them.

You might add Serial.print() in strategic places with a message to show where the logic is taking you.

You also need to reset the states to low once the moving is finished.

You seem to have a different interpretation of EVERY than the rest of us.

How could I go about being able to press button(A) and then press either of the other buttons (B or C) a few seconds later without having to press them simultaneouly? Currently, with the code that I am running, this is what I have to do.

You should separate detecting that the switches have been pressed from the code that takes action based on which switches are pressed.

You need to note when each switch is pressed. Make your decisions based on timing.

Of course, the real problem seems to be your difficulty in defining exactly what you want to do. "A few seconds later" is not something that you can write a program to deal with. If switch B or switch C is pressed within 5000 milliseconds of switch A being pressed, do..." is something that CAN be translated into a program.

Another thing to consider is that switches can be pressed and released. Do you want to take one action if switch 2 is pressed while switch 1 is pressed? Or, do you want to take action is switch 2 is pressed and released after switch 1 is pressed and released?

@PaulS... what's the effect of those extra {....} pairs?

JimboZA:
@PaulS... what's the effect of those extra {....} pairs?

It depends on what is inside of them. By themselves, extra { and } cause no problems.

Thanks... was just wondering they somehow might bundle some lines together. (In a way similar to the {} after an if, where without them, only the first xyz; gets recognised.)

In order to clear up what I am trying to do...
Just to make it clear what I am trying to do.
In the end I am going to build a coin operated salt and pepper dispenser. When a coin is put in the slot, it will trigger a momentary button (buttonA). After that, I want the customer to have the option to choose between salt and pepper (buttonB and buttonC). The problem is that the current code states that if the coin button (buttonA) is pressed, then the user needs to select their seasoning (buttonB or buttonC) simultaneously in order for the servo to turn. I would like to allow the user to insert a coin, and then take their own sweet time to choose from salt or pepper, similar to modern day pop machines. How could I do this?
Hopefully this clears it up. Thanks for your help.

Make the B and C buttons interrupts maybe?

(I can’t help but wonder why we’re going to have to pay for salt and pepper when most places have those annoying, but free, little packets 8) )

How would I implement interrupts? At our Junior High cafeteria, they give us utterly tasteless food, and don't supply any seasoning. I was hoping to make some cash off my peers by selling a dash of salt or pepper for a quarter. I am also building this project just to have some fun.

Thanks... was just wondering they somehow might bundle some lines together. (In a way similar to the {} after an if, where without them, only the first xyz; gets recognised.)

They can do that. That's why I wanted OP to fix his code, to see where that might be happening.

In the end I am going to build a coin operated salt and pepper dispenser. When a coin is put in the slot, it will trigger a momentary button (buttonA). After that, I want the customer to have the option to choose between salt and pepper (buttonB and buttonC). The problem is that the current code states that if the coin button (buttonA) is pressed, then the user needs to select their seasoning (buttonB or buttonC) simultaneously in order for the servo to turn. I would like to allow the user to insert a coin, and then take their own sweet time to choose from salt or pepper, similar to modern day pop machines. How could I do this?

Create a boolean variable, armed, initialized to false. Read the state of switch 1. If it is pressed, set armed to true.

Read the state of switches 2 and 3. If either is pressed and armed is true, move the servo, do whatever else needs to be done, AND set armed to false.

There is absolutely no need for interrupts - buttons are slow.

You have said you want to press BtnA and a short time later press BtnB or BtnC. It seems to me that BtnA is just an unnecessary complication. Why not reduce the code to just two buttons?

If there is a need for BtnA it makes the logic a great deal more complex. What happens if neither BtnB or BtnC is pressed?

Perhaps you need a program that ignores BtnB and BtnC if BtnA has not been pressed. Then a press of BtnA is recorded in a variable and that allows BtnB or BtnC to be recognized. However if neither B nor A is pressed within X seconds the variable set by A is unset and BtnA will need to be pressed again if anything is to happen.

But this all seems unnecessarily complicated.

...R

Yeah sorry I agree, my interrupt idea is crazy....

PaulS:
Create a boolean variable, armed, initialized to false. Read the state of switch 1. If it is pressed, set armed to true.

Read the state of switches 2 and 3. If either is pressed and armed is true, move the servo, do whatever else needs to be done, AND set armed to false.

That's basically what he has, come to think of it. Button A's state of high, is armed, and he's checking B and C only inside the if A is high part anyway, so the thinking is good I reckon.

Just cheat and add a couple of delays for now, between the state checks, else button B will be false becasue the user was too slow. As I said earlier, remember to set them low once the move is done.

And you already have them set low at the beginning.

For real life you might want a coin return if the money is inserted but they change their mind. So have a button D that forces button A's state low when pressed, and cancels the transaction.

EDIT.... but take those extra { } pairs out just in case

Robin2:
Perhaps you need a program that ignores BtnB and BtnC if BtnA has not been pressed. Then a press of BtnA is recorded in a variable and that allows BtnB or BtnC to be recognized.

That's basically what he has: B and C are only tested inside an if, when A's state is high.

I'm thinking his problem right now is a combination of no delays to give time to press B or C, and not resetting the states after the servo moves..... and maybe those extra {} pairs.

You mean like this?

if (AState == HIGH){
    delay(1000);
        if (BState == HIGH){
          myservo.write(50);
          delay(1000);
          myservo.write(111);
          delay(1000);
         
        }
      }
      else
        myservo.write(90);