Using TWO buttons, and switch statements?

Hi all!

This may be a silly question, so sorry in advance. I used to be very good at C a long time ago, but haven't used it in about a decade. Slowly getting back into thanks to Arduino.

  1. I have TWO momentary push buttons which I need to use to control two different aspects of a program - display mode and alert mode. Display mode reads a temperature sensor and each mode converts the value into various formats (F, C, F&C, min/max). Alert mode simply turns on various outputs (display only, LED, buzzer, LED & Buzzer).

I have two problems. I can obviously get one button to operate properly and toggle through the various modes in EITHER the display modes OR the alert modes. However, I can not figure out how to monitor two separate buttons. If I use two Switch statements, the program only sees the first switch statement and seems to ignore the second. I have tried to put both switch statements into various loops, but I just can't figure out how to get this to work. I suppose I could use just ONE button to switch between all the various modes, but I don't want to have to press a button 20 times to get to the correct mode.

I have one button connected to digital 0, and one connected to digital 1. How can I have the program monitor both buttons and react accordingly depending on which is pressed? I would need one button to control one aspect of the program, and the second to update another aspect of the program. The user would press either button at random (i.e. - the user wouldn't necessarily press the first button and then the second, nor would they have to press the second button first then the first.)

  1. The second problem is that once in the switch statement, the sensor does not update within the code. I have put the code in the case statements, I have put the code within loops within the case statements, I have done everything I can think of. If I go through all the modes, each case switch (button press) WILL update the sensor reading once, but it does not continuously update multiple times per second as it does when NOT in a switch statement just in the regular loop(). Any insight into this issue???

Thank you all in advance!!

-Dave

I have one button connected to digital 0, and one connected to digital 1.

Those are the serial port pins. Hard to debug stuff when the serial port is not available.

How can I have the program monitor both buttons and react accordingly depending on which is pressed?

Let's turn that question around. How are you doing it now? Are you using delay() in your switch statements?

How can I have the program monitor both buttons and react accordingly depending on which is pressed?

Except post your code.

I currently have no code of value to post... just snippets I have been playing around with. I used the example code from the Arduino package to test the functionality of a single button, which worked as it should.

I am wondering how to monitor TWO button presses, each button should control its own case/switch statement. As I mentioned in the original post, one button will control four display modes on an LCD (temp F, temp C, etc.), and the second button will control four alert modes (buzzer, LED, etc.). The user will need to be able to press either button at any given time to toggle between the various display and alert modes.

I can obviously get ONE button to work using the built-in sample code, but I can not get the same logic to work with two buttons.

ANY contributions of code would be greatly appreciated! Thanks so much!!

-Dave

I currently have no code of value to post

If it was of value you wouldn't need to post it. We need to see what you have tried so we can say where you are going wrong.

OK - here is basically what I was trying. I have stripped out the majority of the control code for you to simply focus on the logic of what I am trying to do. I need to monitor both buttons all the time. I am not saying that the user will push both buttons at the SAME TIME... just that the user will push one or the other at random throughout the operation of the program, so the two monitoring sections have to be independent of one another and constantly running.

I have tried the code as shown, I have put one section or the other in nested loops within loop(), I have tried to break them into functions and call them from loop(), I have tried an assortment of different things. The one constant is that whichever button is represented by the outermost level of code is the one that functions (it will allow me to switch between those four modes), though the other button remains lifeless.

I should mentioned that I have tried the buttons on different Digital pins with no difference. As it stands right now all I have left are pins 0 and 1. The program is being displayed on a connected LCD, so I don't need the serial communication ability. However, like I said, I have stripped out much of that code to simply focus on the structure of what I am hoping to accomplish.

Thank you all! -Dave

//constants that won't change:
const int  buttonPin = 0;    // the pin that the pushbutton1 is attached to
const int  buttonPin2 = 1;   // the pin that the pushbutton2 is attached to

// Variables will change:
int buttonPushCounter = 0;   // counters for the number of button presses
int buttonPushCounter2 = 0;

int buttonState = 0;         // current states of the buttons
int buttonState2 = 0;

int lastButtonState = 0;     // previous states of the buttons
int lastButtonState2 = 0;


void setup() {

  // initialize the button pins as inputs:
  pinMode(buttonPin, INPUT);
  pinMode(buttonPin2, INPUT);

  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);

  // initialize serial communication:
  //Serial.begin(9600);
  //pinMode(6, OUTPUT);
 }


void loop() {


 // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);
  buttonState2 = digitalRead(buttonPin2);


//ALERT OPTIONS

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      //Serial.println("Button 1: on");
      //Serial.print("number of button-1 pushes:  ");
      //Serial.println(buttonPushCounter, DEC);
      
      switch (buttonPushCounter)
{
  case 1:
  //Serial.println("display Only");
  digitalWrite(6, LOW);
  digitalWrite(13, LOW);
   //etc...
  break;
  
  case 2:
  //Serial.println("LED");
  digitalWrite(6, LOW);
  digitalWrite(13, HIGH);
   //etc...
  break;
  
  case 3:
  //Serial.println("audio");
  digitalWrite(6, HIGH);
  digitalWrite(13, LOW);
   //etc...
  break;
  
  case 4:
  //Serial.println("LED/audio");
   digitalWrite(6, HIGH);
   digitalWrite(13, HIGH);
   //etc...
  break;
}
  delay(2);  
  } 
  

//DISPLAY OPTIONS

 // compare the buttonState to its previous state
  if (buttonState2 != lastButtonState2) {
    // if the state has changed, increment the counter
    if (buttonState2 == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      //Serial.println("Button 2: on");
      //Serial.print("number of button-2 pushes:  ");
      //Serial.println(buttonPushCounter2, DEC);
      
      switch (buttonPushCounter2)
{
  case 1:
  //Serial.println("Degrees Farenheit");
    break;
  
  case 2:
 // Serial.println("Degrees Celcius");
    break;
  
  case 3:
  //Serial.println("F & C");
    break;
  
  case 4:
 // Serial.println("Min / Max");
     break;
}
  delay(2);  
  } 

  }




  // save the current state as the last state, 
  //for next time through the loop
  lastButtonState = buttonState;
  lastButtonState2 = buttonState2;




  if (buttonPushCounter == 4)
    buttonPushCounter=0;

  if (buttonPushCounter2 == 4(
    buttonPushCounter2=0;
    
 }

Looks like there is a missing closing brace there somewhere. Consequently, it's hard to say what's wrong, but from the symptom - Is the code for second button only executed it the first has changed? Obviously not your intent, but may be the problem.

Yeah, there are some closing braces missing, which are putting the if statement to detect the second button press inside the if statement for the first button press--so the second button will only register if the first button has been pressed at exactly the same time. There's another missing at the end that I imagine would prevent the sketch from compiling.

I'm guessing that you want another end brace either before or after the delay( 2 ) statements.

Sidenote: your code for the second button is also incrementing the wrong buttonPushCounter variable.

WildBill and Ryschwith, thank you both for your comments, however the issues that you both pointed out were a result of my pasting the code into this forum and removing some of the control code for ease of viewing. I accidentally deleted a bracket in the process and incremented a wrong variable. My original code does compile and runs fine with no errors. It just doesn't do what I need it to do.

I am not so much looking for a critique of my own code since I know that for what I am trying to do it is not the correct approach. This code compiles and does "something", but it does not do what I am looking for so it is ultimately a dead-end approach.

I am looking for anyone who has successfully implemented two buttons to control two different physical parameters idependently, throughout the entire course of a program. I am looking for a snippet of code which has already worked, which can achieve what I am trying to achieve. I have tried all different approaches - this particular code is simply my most recent attempt. Unfortunately none have functioned correctly.

ANY guidance would be appreciated! Thanks!

-Dave

Your button code is quite basic. There is no debounce. We don’t know whether you use pull-up or pull-down resistor either. From what I read, if you didn’t put the second if statement inside the first one, there is no reason it won’t work. To get you right to the place you want to be, you should use a buttons library to create two buttons from it and just do button1.sense() and see if the button is pressed. That will take care of debounce and also expandable to say 3 buttons. I’m sure you will need extra buttons as soon as you make 2 buttons work.

Take a look at my buttons library. It’s pretty simple and many use it in their projects:

The following code will sense 6 buttons and report any released buttons.

#include <phi_buttons.h>

#define btn_u 5
#define btn_d 10
#define btn_l 11
#define btn_r 4
#define btn_b 14
#define btn_a 15
phi_buttons btn_1(btn_u, LOW);
phi_buttons btn_2(btn_d, LOW);
phi_buttons btn_3(btn_l, LOW);
phi_buttons btn_4(btn_r, LOW);
phi_buttons btn_5(btn_b, LOW);
phi_buttons btn_6(btn_a, LOW);

void setup(){

Serial.begin(9600);

}

void loop(){

int temp=sense_all();

if (temp!=0) Serial.println(temp);

}

int sense_all()

{

byte temp1, temp2, temp3, temp4, temp5, temp6;
do
{
temp1=btn_1.sense();
temp2=btn_2.sense();
temp3=btn_3.sense();
temp4=btn_4.sense();
temp5=btn_5.sense();
temp6=btn_6.sense();

if((temp1==buttons_released)||(temp1==buttons_held))
{
return(1);
}
if((temp2==buttons_released)||(temp2==buttons_held))
{
return(2);
}
if((temp3==buttons_released)||(temp3==buttons_held))
{
return(3);
}
if ((temp4==buttons_released)||(temp4==buttons_held))
{
return(4);
}
if((temp5==buttons_released)||(temp5==buttons_held))
{
return(5);
}
if((temp6==buttons_released)||(temp6==buttons_held))
{
return(6);
}
}   while (1);

return (0);
}

The buttons are all connecting their digital pins to gnd when pushed.

Liudr, thank you very much for providing that information! That is definitely an approach that I would like to try out. Unfortunately, here at work, I do not have access to Wordpress websites, but I will have to download it when I get home this evening.

So I am looking at your code. I am still trying to figure out how to arrange my code so that whenever someone presses a button the appropriate actions will take place. It looks like I will still need two switch statements to control the desired behaviors within the software of the two button presses. Based on your example code I have revised some of my own code, and I have put the two switch statements into an IF loop. In your opinion, does it look as if this might work? I don’t have the library to play around with right now, so I’m trying to make the best use of my time.

The thing is within each case statement I am going to having a pretty substantial loop to continuously read sensor data. The exit out of each loop will have to be a button press. So I am still unsure of what action, if any, a button press on either button from within the individual case statements will have on the operation of the program.

Any thoughts??

-Dave

#include <phi_buttons.h>

//button 1 on digital pin 2
#define btn_a 2

//button 2 on digital pin 3
#define btn_b 3

phi_buttons btn_1(btn_a, LOW);
phi_buttons btn_2(btn_b, LOW);
int buttonPresses1 = 0;
int buttonPresses2 = 0;

void setup()
{
  Serial.begin(9600);
}


void loop()
{
  int temp=sense_all();
  if (temp!=0) Serial.println(temp);

if (temp = 1)
{
//Button1 was pushed so modify alert properties
buttonPresses1 = buttonpresses1 +1; 

switch (buttonPresses1)
{
  case 1:
  //Serial.println("display Only");
   //etc...
  break;
  
  case 2:
  //Serial.println("LED");
   //etc...
  break;
  
  case 3:
  //Serial.println("audio");
   //etc...
  break;
  
  case 4:
  //Serial.println("LED/audio");
  //etc...
  break;
}
If (buttonPresses1 = 4)
buttonPresses1 = 0;
}

else if (temp = 2)
{
//Button2 was pushed so modify display properties
buttonPresses2 = buttonpresses2 +1; 
 switch (temp)
{
  case 1:
  //Serial.println("temp - C");
   //etc...
  break;
  
  case 2:
  //Serial.println("temp - F");
   //etc...
  break;
  
  case 3:
  //Serial.println("temp – C & F");
   //etc...
  break;
  
  case 4:
  //Serial.println("whatever other properties I need to display…");
  //etc...
  break;
}
If (buttonPresses2 = 4)
buttonPresses2 = 0;

}


}

}




int sense_all()
{

byte temp1, temp2;
do
{
temp1=btn_1.sense();
temp2=btn_2.sense();


if((temp1==buttons_released)||(temp1==buttons_held))
{
return(1);
}
if((temp2==buttons_released)||(temp2==buttons_held))
{
return(2);
}

}   while (1);

return (0);
}

Pretty much it!

Here is mistake I spotted:

if (temp = 1)

Should be if (temp == 1) with double equal signs

This re-occurs a few times:

If (buttonPresses1 = 4)

and

else if (temp = 2)

and

If (buttonPresses2 = 4)

Ahh.. yes - typo on my part. Sorry.

OK - I will give it a shot! I hope this ultimately works. For such a simple topic (button presses), I can't tell you how much time I have spent trying to get it correct.

If you don't mind may I ask another question.... you mentioned pull-up or pull-down resistors. I have heard of them, specifically of some being built-in to the Arduino, however I have never used them in any button application. I simply connect one button pin to a digital pin and the other to a gnd pin. Could you elaborate on these special resistors and how/why they are important??

THANKS!

:-)

-Dave

however I have never used them in any button application. I simply connect one button pin to a digital pin and the other to a gnd pin.

Which is one reason why no matter what code you used it would never work. Your inputs are floating. read this:- http://www.thebox.myzen.co.uk/Tutorial/Inputs.html

THANK YOU, GrumpyMike - that is a perfect explanation. I found an old example in the Arduino tutorials online that experimented with two switches on the same data pin. I spent about 15 minutes modifying it, ADDED SOME RESISTORS, and just tested it. It does what I need it to do perfectly!!! Now I just have to integrate it into the rest of my code!

Again, I thank you!

-Dave