Push button counter to add 1 only once every time the button is pressed

i am working on a push button counter that displays count on a lcd using the following code:

#include <LiquidCrystal_I2C.h>
const int buttonPin1 = 2, buttonPin2 = 3;    
int button1_State = 0, button2_State = 0;
int count_value =0;
int prestate =0;
LiquidCrystal_I2C lcd(0x27,16,2);
void setup() 
{
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  lcd.init();
  lcd.backlight();
  lcd.setCursor(4,0);
  lcd.print("Count:");
  lcd.setCursor(2,1);
  lcd.print(count_value);
}
void loop() 
{
  button1_State = digitalRead(buttonPin1);
  button2_State = digitalRead(buttonPin2);
  if (button1_State == HIGH && prestate == 0) 
  {
    count_value++;  
  lcd.setCursor(0,1);
  lcd.print("> ");
  lcd.print(count_value);
  lcd.print(" ");
    prestate = 1;
  } 
 else if(button1_State == LOW && button2_State == LOW) 
  {
    prestate = 0;
  }
}


here, instead of a push button though, i am using a toggle switch(not by choice, i was asked to use a toggle switch instead of a push button) but every time i press it, one starts to get added rapidly non stop until i change the state of the switch. so i want to change it to so that 1 gets added only once every time the switch is pressed, what should i add/change in my code?

You need to detect when the switch becomes closed rather than when it is closed
See the StateChangeDetection example in the IDE

thank you. but i want it to be so that no matter what kind of switch is used, every time i press the button, 1 gets added only once. will State Change Detection work regardless for it all?

yes

you will only react to the transition

(mind bouncing)

buttons library could make your life much easier

ok thanks

Yes.

Normally with state change of a push button, you would increase the counter when the state changes either from high to low, or from low to high, but not both. With a toggle switch you would increment the counter when the switch state changes from high to low and from low to high.

Sorry Paul, but I don't understand that

Thanks @UKHeliBob I've attempted to clarify by amending previous post. Any better?

I think that I can see what you are getting at but @cryptotinkerer says

So, depending on what he/she means and the exact switch type (spring loaded in one direction, maybe) he/she has different requirements

I know that you and I know what we are talking about but we don't have enough detail to provide a definitive answer as yet

@cryptotinkerer exactly what type of switch are you using and when do you want to add 1 to the count ?

With your toggle swich connected at DPin-4 with external pull-down resistor, you read the switch for closed condition, wait for the bouncing time and read it again to see that it is still closed and them add 1 with your counter.

Now, check that the swtch is opened and wait until the switch is settled at opened condition.

Repaet.

Exercise the following sketch to understand the above principle: (You must make the sketch non-blocking if you have some other tasks to do simultaneously.)

byte count = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(4, INPUT);  //with 2k externalpull-down
  while (true)
  {
    while (digitalRead(4) != HIGH)
    {
      ; //wait
    }
    delay(20);   //bouncing time, theoretically it is 20 - 50 ms
    if (digitalRead(4) == HIGH)
    {
      Serial.print(++count);
    }

    while (digitalRead(4) != LOW)
    {
      ; //wait
    }
  }
}
void loop() {}

Output:

12345678
void loop()
{
    byte but = digitalRead(buttonPin1);

    if (button1_State != but) {
        button1_State = but;
        delay (20);

        if (LOW == but)  {
            count_value++;
            lcd.setCursor(0,1);
            lcd.print("> ");
            lcd.print(count_value);
            lcd.print(" ");
            Serial.println (count_value);
        }
    }
}
1 Like

or with a button library - here Toggle from @dlloyd.

#include <Toggle.h>

Toggle button;
unsigned long cptr = 0;

void setup() {
  Serial.begin(115200);
  button.begin(2);
}

void loop() {
  button.poll();
  if (button.onPress()) Serial.println(cptr++);
}

1 Like

This is the output of your sketch:

1
2
3
4
5

This is the output of your sketch:

0
1
2
3
4
5

The Toggle.h Library hides everything to the user. It might be a good resource for the Product Developer -- how good it is for a learner?

sure, it depends where you place the bar...

OP uses an LCD. should he also skip the library? setup and loop versus main()? pinMode() and digitalRead() versus port registers?

it's good to understand how to deal with buttons, bouncing, state change detection etc... But once you know, it's great to leverage a library for this

There are many libraries for the buttons

if you take Button from easyRun the code looks similar.

#include "easyRun.h"
button btn(2);
unsigned long cptr = 0;

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

void loop() {
  easyRun();
  if (btn) Serial.println(cptr++);
}

or with a call back

#include "easyRun.h"
unsigned long cptr = 0;

void click() {Serial.println(cptr++);}

clickButton btn(2, click);

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

void loop() {easyRun();}

OneButton is also a callback driven one

#include "OneButton.h"
OneButton btn(2);
unsigned long cptr = 0;

void click() {Serial.println(cptr++);}

void setup() {
  Serial.begin(115200);
  btn.attachClick(click);
}

void loop() {btn.tick();}

they all keep the code pretty simple to read

1 Like

Once I believed that programming is both an art and a science, but now it seems to me that programming is only a science.

I think it's an art and a science

it's like mathematics, you'll know when you see beautiful mathematical proof of something and you know when you see a great OO approach or code.

2 Likes

That's a good point. For old timers, among whom I must now think seriously about numbering myself cough!, there's lotsa stuff that should be learned and struggled with before (if ever) switching to someone else's code or library.

State change detection and switch debouncing may not need to be struggled with, but both do drag you over some of the things that will come up in many disgraces with this kind of small scale or embedded programming.

Where programmers who know all there is to need to know about some things but are baffled at turning on and off an LED with a pushbutton.

a7

a toggle switch and a pedal switch

thanks