Two button inputs

Hi, I know this is a very basic question but I am hang truble trying to figure it out. I am trying to do a piece of code where if button one is hit then go to house 1, button 2 house 2, and both buttons house 3. I am having trouble trying to figure out a way where even if the two buttons are hit a not exactly simultaneously then it will still read house three. Here's what I have so far:

while (button1 == LOW && button2 == LOW) { //Repeats code until button is pressed
  
  read1 = digitalRead (12);//Scans for what button or buttons is pressed
  delay (25);
  read2 = digitalRead (13);//To set the destintion
  
  if (read1 == HIGH && read2 == HIGH) { //Sets desination to house 3
    y = 3;
  }
  
  if (read1 == HIGH && read2 == LOW) {//Sets destination to house 1
    y = 1;
  }
  
if (read1 == LOW && read2 == HIGH){//Sets destination to house 2
  y = 2;
}
}

Thanks for any help you can other

Can you please post your whole program.

It is a line following robot that will stop at certain "houses" based off the button press

/*
 * Name : The Post Man Robot
 * By : Jacob Hill
 * Date : Monday, January 11th, 2015
 * Purpose : This robot will follow a designated line towards
   three houses.  The house that the robot turns into, where
   it will deliver the mail, will be selected by pressing button 
   one for house one, two for house two and both for house 3.
   The robot will go the the selected house and "deliver the mail".
 * Version 1.4
 */
 
// Constants and Variables

int read1;
int read2;
byte y;
byte z;
byte x = 1;
int sensor1;
int sensor2;
int button1;
int button2;

void setup() {
  DDRB = B00001111; //Sets my desired pins to inputs/outputs
  pinMode (5, INPUT);
  pinMode (4, INPUT);

while (button1 == LOW && button2 == LOW) { //Repeats code until button is pressed
  
  read1 = digitalRead (12);//Scans for what button or buttons is pressed
  delay (25);
  read2 = digitalRead (13);//To set the destintion
  
  if (read1 == HIGH && read2 == HIGH) { //Sets desination to house 3
    y = 3;
  }
  
  if (read1 == HIGH && read2 == LOW) {//Sets destination to house 1
    y = 1;
  }
  
if (read1 == LOW && read2 == HIGH){//Sets destination to house 2
  y = 2;
}
}
}

void loop() {
  
  sensor1 = analogRead (5); //Gathers readings from sensors
  sensor2 = analogRead (4);
  
  if (sensor1 < 450 && sensor2 < 450){ //Checks to see if both are reading white
    forward();//Goes to subroutine "forward"
  }
  if (sensor1 < 450 && sensor2 > 450) {//Checks to see if right is black and left is white
    right(); //Goes to subroutine "right"
  }
  if (sensor1 > 450 && sensor2 < 450) {//Checks to see if left is black and right is white
    left(); //Goes to subroutine "left"
  }
  if (sensor1 > 451 && sensor2 > 451) {//Checks to see if both are black
    x = x ++; //Determines the house number
 if (x == y && stop1 == 0 ) { //Checks to see if at the correct house
  turncomeback();//Goes to subroutine "turncomeback"
  stop1 = 1; //Tells robot that stop is complete
 }
 else{ //If not correct house
  forward();
 }
  }
}

void forward() {
 PORTB = B00001001;//Turns both motors forward
  delay (25); //delays for 25 milliseconds
 PORTB = B00000000; //Turns motors off
}

void right() {
PORTB = B00001010; //Makes slight turn right
  delay(25);
PORTB = B00000000;
}

void left() {
 PORTB = B00000101;//Makes slight turn left
  delay(25);
 PORTB = B00000000;
}

void turncomeback() { //Turns into house, then turns around and comes back
nineturnright();//Does 90 degree right turn
forward();
forward();
eightturn();//Does 180 degree right turn
forward();
forward();
nineturnleft(); //Does 90 degree left turn
}

void nineturnleft() {
 PORTB = B00000101;//Starts left turn
  delay (400);//delays for .4 seconds
 PORTB = B00000000; //Stops turn 
}


void eightturn() {
 PORTB = B00001010; //Starts right turn
  delay (800); //delays .8 seconds
 PORTB = B00000000; //Stops turn
}

void nineturnright(){
PORTB = B00000101;//starts right turn
  delay (400);//delays .4 seconds
PORTB = B00000000; //Finishes right turn
}

while (button1 == LOW && button2 == LOW) { //Repeats code until button is pressedWhat changes the value of the button1 and button2 variables ?

oh sorry I just added that and never tested it it needs to be

while (read1 == LOW && read2 == LOW) { //Repeats code until button is pressed

robotics3U1:
oh sorry I just added that and never tested it it needs to be

while (read1 == LOW && read2 == LOW) { //Repeats code until button is pressed

So what is your latest code?

/*
 * Name : The Post Man Robot
 * By : Jacob Hill
 * Date : Monday, January 11th, 2015
 * Purpose : This robot will follow a designated line towards
   three houses.  The house that the robot turns into, where
   it will deliver the mail, will be selected by pressing button 
   one for house one, two for house two and both for house 3.
   The robot will go the the selected house and "deliver the mail" and
   then return to its home position.
 * Version 1.4
 */
 
// Constants and Variables

int read1;
int read2;
byte y;
byte z;
byte x = 1;
int sensor1;
int sensor2;

void setup() {
  DDRB = B00001111; //Sets my desired pins to inputs/outputs
  pinMode (5, INPUT);
  pinMode (4, INPUT);

while (read1 == LOW && read2 == LOW) { //Repeats code until button is pressed
  
  read1 = digitalRead (12);//Scans for what button or buttons is pressed
  read2 = digitalRead (13);//To set the destintion
  
  if (read1 == HIGH && read2 == HIGH) { //Sets desination to house 3
    y = 3;
  }
  
  if (read1 == HIGH && read2 == LOW) {//Sets destination to house 1
    y = 1;
  }
  
if (read1 == LOW && read2 == HIGH){//Sets destination to house 2
  y = 2;
}
}
}

void loop() {
  
  sensor1 = analogRead (5); //Gathers readings from sensors
  sensor2 = analogRead (4);
  
  if (sensor1 < 450 && sensor2 < 450){ //Checks to see if both are reading white
    forward();//Goes to subroutine "forward"
  }
  if (sensor1 < 450 && sensor2 > 450) {//Checks to see if right is black and left is white
    right(); //Goes to subroutine "right"
  }
  if (sensor1 > 450 && sensor2 < 450) {//Checks to see if left is black and right is white
    left(); //Goes to subroutine "left"
  }
  if (sensor1 > 451 && sensor2 > 451) {//Checks to see if both are black
    x = x ++; //Determines the house number
 if (x == y && stop1 == 0 ) { //Checks to see if at the correct house
  turncomeback();//Goes to subroutine "turncomeback"
  stop1 = 1; //Tells robot that stop is complete
 }
 else{ //If not correct house
  forward();
 }
  }
}

void forward() {
 PORTB = B00001001;//Turns both motors forward
  delay (25); //delays for 25 milliseconds
 PORTB = B00000000; //Turns motors off
}

void right() {
PORTB = B00001010; //Makes slight turn right
  delay(25);
PORTB = B00000000;
}

void left() {
 PORTB = B00000101;//Makes slight turn left
  delay(25);
 PORTB = B00000000;
}

void turncomeback() { //Turns into house, then turns around and comes back
nineturnright();//Does 90 degree right turn
forward();
forward();
eightturn();//Does 180 degree right turn
forward();
forward();
nineturnleft(); //Does 90 degree left turn
}

void nineturnleft() {
 PORTB = B00000101;//Starts left turn
  delay (400);//delays for .4 seconds
 PORTB = B00000000; //Stops turn 
}


void eightturn() {
 PORTB = B00001010; //Starts right turn
  delay (800); //delays .8 seconds
 PORTB = B00000000; //Stops turn
}

void nineturnright(){
PORTB = B00000101;//starts right turn
  delay (400);//delays .4 seconds
PORTB = B00000000; //Finishes right turn
}

Well, this is obviously only going to allow a selection of house 3 at the moment, since you only finish the loop if both buttons are HIGH (i.e.: house 3 is selected)

while (read1 == LOW && read2 == LOW) { //Repeats code until button is pressed

    read1 = digitalRead (12);//Scans for what button or buttons is pressed
    read2 = digitalRead (13);//To set the destintion

    if (read1 == HIGH && read2 == HIGH) { //Sets desination to house 3
        y = 3;
    }

    if (read1 == HIGH && read2 == LOW) {//Sets destination to house 1
        y = 1;
    }

    if (read1 == LOW && read2 == HIGH){//Sets destination to house 2
        y = 2;
    }
}

What you want to do is detect when either button is pressed, then start a timer. When the timer expires, check both buttons, and set your house number based on that.

Have a look at millis() which you can use to time things.

I would look to decide the state when a button becomes un-pressed.

something like this:

compiles but not tested

enum State{
  READY,
  HOUSE_ONE,
  HOUSE_TWO,
  BOTH_HOUSES
};

State robotState = READY;
State lastRobotState = READY;

byte buttonPin[2] = {4,5};

byte lastButtonState[2] = {HIGH, HIGH};

void setup() 

{
  Serial.begin(9600);
  for (int i = 0; i < 2; i++)
  {
    pinMode(buttonPin[i], INPUT_PULLUP);
  }
  Serial.println("READY");
}

void loop() 
{
  if(robotState == READY) // wait for button press
  {
    if (lastRobotState != READY)
    {
      Serial.println("READY");
      lastRobotState = READY;
    }
    for(int i = 0; i < 2; i++)
    {
      byte buttonState = digitalRead(buttonPin[i]);
      {
        if (buttonState != lastButtonState[i])
        {
          if (lastButtonState[i] == LOW)
          {
            if (lastButtonState[i?0:1] == LOW) // released while other is pressed
            {
              robotState = BOTH_HOUSES;
            }
            else
            {
              robotState = i? HOUSE_ONE : HOUSE_TWO;
            }
          }
        }
        lastButtonState[i] = buttonState;
      } 
    } 
    delay(30);  //crude debounce
  }
  else if(robotState == HOUSE_ONE)
  {
    Serial.println("House1");
    // do House1 stuff
    robotState = READY;
  }
  else if(robotState == HOUSE_TWO)
  {
    Serial.println("House2");
    // do House2 stuff
    robotState = READY;
  }
  else if(robotState == BOTH_HOUSES)
  {
    Serial.println("Both Houses");
    // do both house stuff
    robotState = READY;
  }
}

BulldogLowell:
I would look to decide the state when a button becomes un-pressed.

That might work for the OP, but the problem with waiting for buttons to become unpressed is that it feels different to the fingers than waiting for buttons to be pressed.

arduinodlb:
... it feels different to the fingers than waiting for buttons to be pressed.

I can't imagine how that could feel any different.

in any case, its worth trying, plus creating a state machine for the three options allows this to run without resetting the arduino every time (i.e. getting button presses out of setup() ).

BulldogLowell:
I can't imagine how that could feel any different.

in any case, its worth trying, plus creating a state machine for the three options allows this to run without resetting the arduino every time (i.e. getting button presses out of setup() ).

They feel different because when you press the button, nothing happens until you release them. So, if you hold the buttons for say 1 second, nothing happens until 1+n seconds, which feels quite odd since we are used to things happening when we press buttons, not when we release them. Now, that may be what the OP wants, but it's definitely a very different feeling.

I agree that moving the button logic into the loop() is a good step forward for the OP.

arduinodlb:
They feel different because when you press the button, nothing happens until you release them. So, if you hold the buttons for say 1 second, nothing happens until 1 second, which feels quite odd since we are used to things happening when we press buttons, not when we release them.

Not to be argumentative, but that you don't have to sit there and hold them down is kind of the point. Using an algorithm with timers waiting for a second press to occur could result in un-natural feeling button presses too, I guess.

I use COMMAND + C, shift keys, and a bunch of two button presses probably thousands of times per day, and i never felt odd (unless I coincidentally saw something that made me feel odd at the same time :wink: )

BulldogLowell:
Not to be argumentative, but that you don't have to sit there and hold them down is kind of the point. Using an algorithm with timers waiting for a second press to occur could result in un-natural feeling button presses too, I guess.

I use COMMAND + C, shift keys, and a bunch of two button presses probably thousands of times per day, and i never felt odd (unless I coincidentally saw something that made me feel odd at the same time :wink: )

I feel odd every day.

BulldogLowell:
I can't imagine how that could feel any different.

I can. It would feel like "sluggishness".

The OP's problem is just the part about buttons "pushed together". That is a colloquial description of how things work. But people can't push buttons with femtosecond accuracy. There will be a delay between them. It will vary. At some point, the delay could increase to the point where we could have an argument about whether they were pushed together or not. Obviously the definition of "pushed together" must include the specification of the maximum interval between them. It is up to the designer to choose an acceptable value. Too short, and nobody can push them accurately enough. Too long, and it might be considered as separate presses, which in this case have to be interpreted as two single presses on different buttons.

So the design has to be thought out carefully before coding. It's not really a code issue.

BulldogLowell:
I use COMMAND + C, shift keys, and a bunch of two button presses probably thousands of times per day, and i never felt odd (unless I coincidentally saw something that made me feel odd at the same time :wink:

Shift keys are different. There is no requirement that they be concurrent. In fact, there is no maximum time that the shift key must be held down before the second key is depressed.

Even the "three finger salute" will patiently wait for all three keys to be depressed before it registers.

aarg:
Shift keys are different. There is no requirement that they be concurrent. In fact, there is no maximum time that the shift key must be held down before the second key is depressed.

Even the "three finger salute" will patiently wait for all three keys to be depressed before it registers.

It's an analogy...

Did you even try the code I posted with two tactile switches?

Or, rather than just sh*tting on someone's suggested code, post yours.

And holding the shift key to get a capital letter on my Mac is a requirement.

BulldogLowell:
Did you even try the code I posted with two tactile switches?

No. I don't disbelieve that it works. It also seems to me that the OP can code, so I feel no need to post a code solution here, because I don't see anything tricky about it. But it is fair to ask what I am proposing. It would be like this:

Poll the keys.
If a key becomes pressed, start the 2-key interval timer.
Poll the other key until the 2-key timer expires.
If the other key is pressed during the timer interval, then record a 2-button press.
Else, record a 1-button press.

With this approach, the maximum response delay is the 2-key timer interval, plus any debounce delays.