Button up/down counter HELP!!!

Dear all,

Hello there! :slight_smile: I’m a beginner on Arduino and also a newer in this forum.

I’m currently working on a project and now I’m stuck on the button adjustment function. Within the following code, I can make a counter, countering up and down, from a range of 0-999. If the figure is 0 or 999, the screen will directly show ‘OFF’ or ‘MAX’. However, without the delay() function in the main loop (cuz it will delay the whole program and I don’t want to use it), the figures will increase/decrease a lot within one press. I need a accurate adjustment system, which means all I need is to count once up/down within one press. That is, from the time I press till release, I the counter will only count for one no matter how long I pressed!!!

Here is the code:

#include <LiquidCrystal.h>

LiquidCrystal lcd(22,24,26,28,30,32);
const int  buttonPinDown = 5;    // down
const int  buttonPinUp = 6;    // up
//with an inverting schmitt trigger, so in the code ButtonDown will in 

a increase loop while the ButtonUp in a decrease loop
 
// Variables will change:
 int buttonPushCounter = 0;   // counter up/down
 int buttonState5 = 0;         // current state button down
 int buttonState6 = 0;         // current state button up
 int lastButtonState = 0;     // previous state of the button


 void setup() {
  // initialize the button pin as a input:   
   pinMode(buttonPinDown, INPUT);   
   pinMode(buttonPinUp, INPUT);      
   lcd.begin(16,2);  
   lcd.setCursor(0,1);  
   lcd.print("Volume:0");   
 }
 
void loop() { 
   // read the pushbutton down input pin:   
   buttonState5 = digitalRead(buttonPinDown);
  // compare the buttonState to its previous state
   if (buttonState5 != lastButtonState) {    
     // if the state has changed, decrement the counter     
     if (buttonState5 == LOW && buttonPushCounter<999)         
     buttonPushCounter=buttonPushCounter+1;   
     lcd.setCursor(7,1);
     lcd.print(buttonPushCounter);
     lastButtonState = buttonState5; 
      //delay(150);
   } 
        
  // read the pushbutton up input pin:   
   buttonState6 = digitalRead(buttonPinUp);
  // compare the buttonState to its previous state 
   if (buttonState6 != lastButtonState) {     
     // if the state has changed, increment the counter    
     if (buttonState6 == LOW && buttonPushCounter>0)
      buttonPushCounter=buttonPushCounter-1;
      lcd.setCursor(7,1);
      lcd.print(buttonPushCounter); 
      lastButtonState = buttonState6;
      //delay(150);       
   }  
   
   

//Limitations added   
         if (buttonPushCounter < 10)         
         {
             lcd.setCursor(8,1);          
              lcd.print("  ");
              //Serial.print("  ");
         }
         if (buttonPushCounter < 100)        
         {
             lcd.setCursor(9,1);         
              lcd.print("  ");
              //Serial.print("  ");
         }         
         if (buttonPushCounter < 1)         
         {  //buttonPushCounter=0;                    
            lcd.setCursor(7,1);            
            lcd.print("OFF");
            //Serial.print("OFF");
            buttonPushCounter=0;  
         }                           
         if (buttonPushCounter >998)         
         { //buttonPushCounter=999;          
           lcd.setCursor(7,1);            
           lcd.print("MAX ");
           //Serial.print("MAX");
           buttonPushCounter=999;
         }   
         if (buttonPushCounter <1000)        
         {
              lcd.setCursor(10,1);         
              lcd.print("  ");
              //Serial.print("  ");
         }
}

Anyone can help???

Many thanks!!!

Sharon.

the figures will increase/decrease a lot within one press.

I suspect that you want the value to increase or decrease ONCE each time the corresponding switch BECOMES pressed (or released), not when the switch IS pressed.

Look at the state change detection example.

Hi

You are using only one "LastButtonState", maybe you should use a "LastButtonUpState" and a "LastButtonDownState". Like this you can keep track of the last state of each button.

You can also have some bouncing problems. How does it work when you uncomment the

delay(150);

Do you still get more than one increment per press?

If you don't want to use the delay() function, you can achieve the same by using millis() and checking for how long has passed: http://arduino.cc/en/Tutorial/BlinkWithoutDelay

Another thought... how are you connecting your buttons to the Arduino? Are you using any pull-up (or pull-down) resistors? It would also help you to get a "cleaner" result.

Good luck with your project! =)

Yeah, that’s what I want. I will try to find the related info. THX!

PaulS:

the figures will increase/decrease a lot within one press.

I suspect that you want the value to increase or decrease ONCE each time the corresponding switch BECOMES pressed (or released), not when the switch IS pressed.

Look at the state change detection example.

Hi, I'm using hardware button debounce so the connection is fine. I don't want to use the mills() function cuz it may still delay my program. What I want is a checking loop for the button status, that is to make the counter work only when there is a rising/ falling signal. THX for your reply!

boguz: Hi

You are using only one "LastButtonState", maybe you should use a "LastButtonUpState" and a "LastButtonDownState". Like this you can keep track of the last state of each button.

You can also have some bouncing problems. How does it work when you uncomment the

delay(150);

Do you still get more than one increment per press?

If you don't want to use the delay() function, you can achieve the same by using millis() and checking for how long has passed: http://arduino.cc/en/Tutorial/BlinkWithoutDelay

Another thought... how are you connecting your buttons to the Arduino? Are you using any pull-up (or pull-down) resistors? It would also help you to get a "cleaner" result.

Good luck with your project! =)

I don't want to use the mills() function cuz it may still delay my program.

Bullshit! Use it right, and it won't.

What I want is a checking loop for the button status, that is to make the counter work only when there is a rising/ falling signal.

The state change detection example shows you how.

Hey Paul, I'm reading those infos but still not got a clear picture. Can you please modify with my posted code to show me how? THX!!!

PaulS:

I don't want to use the mills() function cuz it may still delay my program.

Bullshit! Use it right, and it won't.

What I want is a checking loop for the button status, that is to make the counter work only when there is a rising/ falling signal.

The state change detection example shows you how.

Can you please modify with my posted code to show me how?

No. The state change detection example shows you how.

You are so NiCE! THX

PaulS:

Can you please modify with my posted code to show me how?

No. The state change detection example shows you how.

sharonq15: I don't want to use the mills() function cuz it may still delay my program.

i don't see why it should delay your program. the delay() function actually "pauses" your sketches, but with the millis() function your sketch keeps running normally, and on each pass you can check if a certain amount of time as passed (by compared the "old millis()" with the "current millis()".

sharonq15: What I want is a checking loop for the button status, that is to make the counter work only when there is a rising/ falling signal.

I think PaulS is right. the Button State Change Detection is a very good basis to start from. It is very well commented, so you can follow up what each line of code is doing. You can find it here: http://arduino.cc/en/Tutorial/ButtonStateChange

You just need to change it so it works with all your buttons and to have each of them do what you like.

If you can post some code we can help you further... ;)