Having problems with a button

Hi, what my project does is, when sensor1 is activated it starts a timer and when sensor 2 is activated it stops the timer. Lcd displays this calculation 10/..(time between sensors)....=.........
So I added a push button. Every time someone pushes it "10" in the calculation increments by 10. My project works fine until here. Here is my 2 problem:

After I press the button and the value 10 becomes 20, I want it to find the result of the new operation like I push the button 2 times and then activated the sensors for 10 seconds the output on the lcd should be 30/10=3. My code at the moment can add 10 to 10 but it doesn't calculate the operation it looks like 20/10s= 10 did you get it? It still calculates the operation as if 10/10=1 like I didnt push the button.

Second problem I have is; when I press the button more than 5 times and the lcd displays 60, what I want is if i press the key again i want it to go back to 10 and not to 70. I write it like this;

if (buttonPushcounter>5)
   ten=10;
   lcd.Setcursor(0,1);
   lcd.print(ten);

But it didn't work so I deleted it from my code. Here is the rest of my code:

#include <LiquidCrystal_I2C.h>
#include <Wire.h>

int startPin = 3;
int stopPin  = 4;
const int Up_buttonPin = 2 ;
LiquidCrystal_I2C lcd(0x27, 16, 2);

unsigned long startTime;
unsigned long stopTime;
unsigned long screenTime;
float elapsedTimes = 0.0;
float time = 0.0;

bool start = false;
bool lastStart = false;
bool stop = false;
bool lastStop = false;
bool stateRunning = false;

int ten = 10;

int buttonPushCounter = 0;   // counter for the number of button presses
int up_buttonState = 0;         // current state of the up button
int up_lastButtonState = 0;     // previous state of the up button

void setup() {
  
  pinMode(startPin, INPUT_PULLUP);
  pinMode(stopPin, INPUT_PULLUP);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(Up_buttonPin, INPUT_PULLUP);
 
  lcd.begin();
  lcd.backlight();
  lcd.clear();

  lcd.setCursor(1,1);
  lcd.print(buttonPushCounter);
}
void loop() {

  checkUp();
  checkDown();
  
  lastStart = start;
  lastStop = stop;
  start = digitalRead(startPin);
  stop = digitalRead(stopPin);
  
  // Start Timer
  if (!start && lastStart) {
    startTime  = micros();
    stateRunning = true;
    digitalWrite(LED_BUILTIN, HIGH);
    lcd.setCursor(0,1);
    lcd.print((micros()-startTime)/1000000.0);
  }

  // Stop Timer
  if (!stop && lastStop) {
    
    stateRunning = false;
    digitalWrite(LED_BUILTIN, LOW);
    lcd.setCursor(0,1);
    lcd.print("10/     =");
    lcd.setCursor(5, 1);
    lcd.print((stopTime - startTime)/1000000.0);
    lcd.setCursor(9, 1);
    lcd.print("s");
  }
  if (stateRunning) {
    stopTime  = micros();
  }
  // LCD Update
  if ( micros() - screenTime  >= 100000) {
    screenTime = micros();
    elapsedTimes = (stopTime - startTime) / 1000000.0;
    lcd.setCursor(11,1);
    lcd.print(ten/elapsedTimes);}
} 

  void checkUp(){
  up_buttonState = digitalRead(Up_buttonPin);
  // compare the buttonState to its previous state

  if (up_buttonState != up_lastButtonState) {
    // if the state has changed, increment the counter

    if (up_buttonState == LOW) {
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter=buttonPushCounter+10;
      
      lcd.setCursor(0,1);
      lcd.print(buttonPushCounter);

    } else {
      // if the current state is LOW then the button went from on to off:
      //lcd.setCursor(0,1);
      //lcd.print("10");
    }
    delay(50);
  }
  // saving the current state as the last state, for next time through the loop
  up_lastButtonState = up_buttonState;
}

Your code is scrolling off my screen because of all the spaces - can you take them out where they are superfluous please?
image

If you are using micros for timing do you really want delay(50); (milliseconds)

do you need to reset buttonPushcounter to zero?

1 Like

what should I write instead of 50 in delay(?);


If I reset the buttonPushcounter to zero will the value in the calculation changes too? Will it go back to 10?

are you just having problems with reseting a value back to zero
consider

const byte PinBut = A1;
      byte butLst;

const byte ButCntMax = 6;
      byte butCnt;

void
loop (void)
{
    byte but = digitalRead (PinBut);
    if (butLst != but)  {
        butLst = but;
        delay (20);     // debounce

        if (LOW == but)  {
            if (ButCntMax <= ++butCnt)
                butCnt = 0;
            Serial.println (butCnt);
        }
    }
}

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

    pinMode (PinBut, INPUT_PULLUP);
    butLst = digitalRead (PinBut);
}
1 Like

Thanks I do have problems on that, I will check the code you send right now. :smile:

Do you have any idea how to fix the first problem
( After I press the button and the value 10 becomes 20, I want it to find the result of the new operation like I push the button 2 times and then activated the sensors for 10 seconds the output on the lcd should be 30/10=3 . My code at the moment can add 10 to 10 but it doesn't calculate the operation it looks like 20/10s= 10 did you get it? It still calculates the operation as if 10/10=1 like I didnt push the button.)

The code says more than 6 times, not more than 5 times!

Please post the code you want help to fix, not some earlier code that does not even have the problem.

1 Like

i don't see where the calculation is done in the code you posted.

here:

  // LCD Update
  if ( micros() - screenTime  >= 100000) {
    screenTime = micros();
    elapsedTimes = (stopTime - startTime) / 1000000.0;
    lcd.setCursor(11,1);
    lcd.print(ten/elapsedTimes);}
} 

if you start printing with the fixed text "10"

lcd.print("10/     =");

how shall this ever print
30/... ??

But maybe I'm misunderstand what you really want.

You should write down an example of the wanted behaviour with
example-numbers for everything including the numbers that are inside the function micros()
and the variables startTime, stopTime

best regards Stefan

3 Likes

where is buttonPushCounter being used?

Thank you so much Stefan. I didn't realize the fixed text was the problem. I don't get how I didn't saw it before. :thinking:

Just deleted the fixed text and it worked. Thank you
This is the updated version of my code:

#include <LiquidCrystal_I2C.h>
#include <Wire.h>

int startPin = 3;
int stopPin  = 4;
const int Up_buttonPin = 2 ;
LiquidCrystal_I2C lcd(0x27, 16, 2);

unsigned long startTime;
unsigned long stopTime;
unsigned long screenTime;
float elapsedTimes = 0.0;
float time = 0.0;

bool start = false;
bool lastStart = false;
bool stop = false;
bool lastStop = false;
bool stateRunning = false;

int buttonPushCounter = 0;   // counter for the number of button presses
int up_buttonState = 0;         // current state of the up button
int up_lastButtonState = 0;     // previous state of the up button

bool bPress = false;

void setup() {
  pinMode(startPin, INPUT_PULLUP);
  pinMode(stopPin, INPUT_PULLUP);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(Up_buttonPin, INPUT_PULLUP);
  lcd.begin();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0,1);
  lcd.print(buttonPushCounter);
  lcd.setCursor(2,1);
  lcd.print("/");
  lcd.setCursor(10,1);
  lcd.print("=");  }
  
void loop() {
  lastStart = start;
  lastStop = stop;
  start = digitalRead(startPin);
  stop = digitalRead(stopPin);
  
   if( bPress){
      bPress = false;}
  // Start Timer
  if (!start && lastStart) {
    startTime  = micros();
    stateRunning = true;
    digitalWrite(LED_BUILTIN, HIGH);
    lcd.setCursor(5,1);
    lcd.print((micros()-startTime)/1000000.0);
    lcd.setCursor(0,1);
    lcd.print(buttonPushCounter);
  }
  // Stop Timer
  if (!stop && lastStop) {
    
    stateRunning = false;
    digitalWrite(LED_BUILTIN, LOW);
    lcd.setCursor(5, 1);
    lcd.print((stopTime - startTime)/1000000.0);
    lcd.setCursor(9, 1);
    lcd.print("s");  
  }

  if (stateRunning) {
    stopTime  = micros(); }

  // LCD Update
  if ( micros() - screenTime  >= 100000) {
    screenTime = micros();
    elapsedTimes = (stopTime - startTime) / 1000000.0;
    lcd.setCursor(11,1);
    lcd.print(buttonPushCounter/elapsedTimes);}
    //uint32_t speedTemp = (distance / elapsedTimes);
 
  up_buttonState = digitalRead(Up_buttonPin);

  if (up_buttonState != up_lastButtonState) {
    // if the state has changed, increment the counter
    if (up_buttonState == LOW) {
        bPress = true;
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter=buttonPushCounter+10;
      lcd.setCursor(0,1);
      lcd.print(buttonPushCounter);

    }else {
      // if the current state is LOW then the button went from on to off:
    }
    // Delay a little bit to avoid bouncing
    delay(50);}
  // save the current state as the last state, for next time through the loop
  up_lastButtonState = up_buttonState;
 }

Do you know how can I reset my button after I push it for 5 times?
I found a very similar discussion about my problem,
Reseting a button counter when pressed 3 times - #3 by Koepel
I tried to do the same thing on my project too but it didn't work. In the other discussion, someone wrote an if statement inside an if statement

  if (buttonPushCounter >= 3)
      {
        Serial.println("The button has been pressed three times");
        tone(buzzer, 1000);
        Serial.println("resetting the counter");
        buttonPushCounter = 0;
      }

I added something similar to my code and run it. Here the part of my code, the rest of it is the same as the above code :

 if (up_buttonState != up_lastButtonState) {
    // if the state has changed, increment the counter
    if (up_buttonState == LOW) {
        bPress = true;
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter=buttonPushCounter+10;
      lcd.setCursor(0,1);
      lcd.print(buttonPushCounter);

            if(buttonPushCounter >5){  //This if statement is the one I added
               buttonPushCounter = 0;
               lcd.print(buttonPushCounter); }
    }else {
    }

The problem is with this new code, when I press the button its jumps from 0 to 100 and when I push it one more time nothing change I pressed it a couple of times more and again nothing changed, normally before it, whenever I pressed the button it increment by 10, it was jumping from 0 to 10 to 20 etc(every time I pressed the button).

...

1 Like

I tried the code and it kinda worked. When I push the button for 5 times it went back to 0. Just what I wanted. But when I press the button 5 more times(10 in total) lcd displayed this: 000 and when I pressed it again (11 in total) lcd displayed: 110. it went from 2 digits to 3 digits
this is how it went on the lcd:
0
10(first time pressing it)
20
30
40
00
10
20
30
40
000 something happend here
110
220
330
.....

What sketch are you currently using ?

Make sure you erase old characters prior to updating text.

This is the updated version of it but it still does this:
this is how it went on the lcd:
0
10(first time pressing it)
20
30
40
00
10
20
30
40
000 something happend here
110
220

#include <LiquidCrystal_I2C.h>
#include <Wire.h>

int startPin = 3;
int stopPin  = 4;
const byte Up_buttonPin = 2 ;

const byte ButCntMax = 5;
      byte butCnt;

LiquidCrystal_I2C lcd(0x27, 16, 2);

unsigned long startTime;
unsigned long stopTime;
unsigned long screenTime;
float elapsedTimes = 0.0;
float time = 0.0;

bool start = false;
bool lastStart = false;
bool stop = false;
bool lastStop = false;
bool stateRunning = false;

int buttonPushCounter = 0;   // counter for the number of button presses
int up_buttonState = 0;         // current state of the up button
int up_lastButtonState = 0;     // previous state of the up button

bool bPress = false;

void setup() {
  pinMode(startPin, INPUT_PULLUP);
  pinMode(stopPin, INPUT_PULLUP);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(Up_buttonPin, INPUT_PULLUP);
  lcd.begin();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0,1);
  lcd.print(buttonPushCounter);
  lcd.setCursor(2,1);
  lcd.print("/");
  lcd.setCursor(10,1);
  lcd.print("=");  }
  
void loop() {
  lastStart = start;
  lastStop = stop;
  start = digitalRead(startPin);
  stop = digitalRead(stopPin);
  
   if( bPress){
      bPress = false;}
  // Start Timer
  if (!start && lastStart) {
    startTime  = micros();
    stateRunning = true;
    digitalWrite(LED_BUILTIN, HIGH);
    lcd.setCursor(5,1);
    lcd.print((micros()-startTime)/1000000.0);
    lcd.setCursor(0,1);
    lcd.print(buttonPushCounter);}
  // Stop Timer
  if (!stop && lastStop) {
    
    stateRunning = false;
    digitalWrite(LED_BUILTIN, LOW);
    lcd.setCursor(5, 1);
    lcd.print((stopTime - startTime)/1000000.0);
    lcd.setCursor(9, 1);
    lcd.print("s");  }

  if (stateRunning) {
    stopTime  = micros(); }

  // LCD Update
  if ( micros() - screenTime  >= 100000) {
    screenTime = micros();
    elapsedTimes = (stopTime - startTime) / 1000000.0;
    lcd.setCursor(11,1);
    lcd.print(buttonPushCounter/elapsedTimes);}
 
  up_buttonState = digitalRead(Up_buttonPin);

  if (up_buttonState != up_lastButtonState) {
    // if the state has changed, increment the counter
delay(20);
    if (up_buttonState == LOW) {
        bPress = true;
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter=buttonPushCounter+10;
      lcd.setCursor(0,1);
      lcd.print(buttonPushCounter);
                if(ButCntMax <= ++butCnt)
                butCnt = 0;
                lcd.setCursor(0, 1);
                lcd.print(butCnt);
    }else { }
    delay(50);}
  up_lastButtonState = up_buttonState;
 }```

I realized something, so this is what lcd displays right when I push the button multiple times? :0, 10, 20, 30, 40, 00, 10, 20, 30, 40, 000, 110, 220, 330, 440, 050, 160, 270... If you look carefully you will realize that the first digit works fine. It's the second digit where the problem is

Have not looked too closely, however, do something similar to this wherever you are printing a variable:

    lcd.setCursor(0,1);
    lcd.print(”          “);
    lcd.setCursor(0,1);
    lcd.print(buttonPushCounter);}

Hey Larry, I did what you said and unfortunately it still prints the same way as before.

Did you do the same here

When I did the same thing there, this was displaying on the lcd when I pressed the button multiple times:
0
1
2
3
4
0
1
2
3
4
0
1
2
3......
But I want numbers to be like this : 0, 10, 20, 30, 40, 0, 10,20,30,40,0,10,20....

I added like this:

  if(ButCntMax <= ++butCnt)
                butCnt = 0;
                lcd.setCursor(0, 1); 
                lcd.print("         "); <——<<<<  
                 lcd.setCursor(0,1);
                lcd.print(butCnt);