Debounce button and delays

Hello forum!!!

I keep losing my nerves... I try to find out why my debounced button gets hardly recognized after pushing. Well after 20hrs of troubleshooting I find out my debounce is absolutely correct and fast recognized when erasing anything else in my loop program, especially all delays I set for other reasons.
Is this normal? Any delay or longer code makes it harder to recognize a debounced button? Any solution?? Thank you!!!

You should not use delay to debounce a switch. Use non blocking millis() instead.

Does the switch really need to be denounced?

We can better help if you post your code. Use autoformat and post the code in code tags.

1 Like

Thank you so much for answering! No I do not use delay within the debounce function. I use the delay for other purposes. But, even when I do not use any delay at all and I just use my debounce with the rest of the code, it seems like the code slows down so the debounce may take more time and therefore my button needs to be pressed longer to be recognized and sometimes the program doesn't recognize the button push at all. Any idea on that?

In the Arduino IDE, use Ctrl T or CMD T to format your code then copy the complete sketch.

Use the </> icon from the ‘reply menu’ to attach the copied sketch.


Show us a good schematic of your circuit.
Show us a good image of your ‘actual’ wiring.
Give links to components.

1 Like

@tarabas05, your topic has been moved to a more suitable location on the forum. Installation and Troubleshooting is not for problems with your project :wink: See About the Installation & Troubleshooting category.

Without seeing your code I cannot comment.

I’m guessing the OP is using delay() elsewhere in his loop code, and when he presses the input, the processor is off twiddling it’s thumbs in a delay somewhere.

Lose all of the delays, and use millis for all your timing.

Isn’t it nice how we are constantly kept in a nervous and excited state anticipating what will happen.

:slight_smile:

OMG, unexpected! you guys are staying in line to help out! THANK YOU ALL
i think the user "lastchancename" may hit it on the nail. however, to my shame, i didnt post a code yet, because it looks like a mess and i have to clean it up and through a lot of other stuff out first, from a project i started 4 years ago as a beginner. I am still a beginner and i am in my own way. please give me a day or so to respond with a code.

1 Like

Hello
For debouncing buttons, I use a timer function that queries the current switching state of the button and derives the further measures from this. A button object is used as a basis that contains all the necessary information, such as the pin address, status, times and so on.

So you know the answer: You have to eliminate delay() and anything else that keeps loop() from repeating hundreds of times per second.

Hello to all of you!
I found the issue: i started from scratch with a new file. So its not the delays as i thought, my buttonsystemon/off switch seems to be bounced ok, and my 2 added buttons for temp adjust up and down work too.
Here is my find: the debounced button and the up/down buttons are recognized super fast, and the up and down buttons run the numbers super fast too, UNLESS I added what i forgotten in the code, (since my temp reading wasnt coming in):
under the loop i added sensors.requestTemperatures();

and that is my issue making the buttons so slow. why is that? what could be the fix?

also, (before I added sensors.requestTemperatures); i found out once I change my temps settings over/under 100, the arduino does mess up the numbers and count wrong. why?

#include <LiquidCrystal_I2C.h> //from new ldc
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 20 chars and 4 line display, without that characters cant be set to specific lines at specific places

//stage 2 after buttonsystemonoff and lcd setup - beginn
#include <IRLibSendBase.h> //from new sucessful code from internet, this is the base
#include <IRLib_P01_NEC.h> //from new sucessful code from internet, this is the actual protocol
//IRsend mySender; //from new sucessful code from internet, no idea how that matters
#include <DallasTemperature.h> //library from temp sensor 18b20
#include <OneWire.h> //library communication from temp sensor 18b20
// Data wire is plugged into pin 2 on the Arduino //im not sure about that, had to tinker and
#define ONE_WIRE_BUS 2 // when plugged data wire in pin 2 and opened serial mon. temp came in...
// Pass our oneWire reference to Dallas Temperature.
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

float settemp=25;
float settemphyst;
int ledforactualcooling=12;
int buttondown=8;
int buttonup=10;
//stage 2 after buttonsystemonoff and lcd setup - end

const int buttonsystemonoff = 9; // the number of the pushbutton pin

int storedState; // not sure what that actually does in the code
int Thermostatstate = LOW; // needed for debouncing
int lastButtonState = HIGH; // needed for debouncing
int currentstate; // needed for debouncing
long lastDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 100; // the debounce time; increase if the output flickers

void setup() // SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP
{
//stage 2 after buttonsystemonoff and lcd setup - beginn
sensors.begin(); //from temp sensor 18b20
pinMode(buttondown, INPUT);
pinMode(buttonup, INPUT);
pinMode(ledforactualcooling,OUTPUT);
//stage 2 after buttonsystemonoff and lcd setup - end

pinMode(buttonsystemonoff, INPUT);
Serial.begin(9600); // start serial communication to Pc program
lcd.begin(); // initialize the lcd
lcd.print("Hello guys");
lcd.setCursor(0, 1);
lcd.print("MY Invention");
delay(2000);
lcd.clear();

lcd.print("Swamp Cooler");
lcd.setCursor(0, 1);
lcd.print("Thermostat");
lcd.setCursor(0, 2);
lcd.print("Room T.");
lcd.setCursor(19, 2);
lcd.print("C");
lcd.setCursor(0, 3);
lcd.print("Set T.");
lcd.setCursor(11, 2);
lcd.print("C /");
lcd.setCursor(19, 2);
lcd.print("F");
}
void loop() // LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP
{
currentstate = digitalRead(buttonsystemonoff); // my own new interpretation of these three lines of code:
if (currentstate != lastButtonState) { // button state just changed and still bounces over and over, (lastButtonState = currentState)
lastDebounceTime = millis(); // keeps changing. both ongoing until it settles. then, we need the following 2nd action to make final comparison to inital state
lastButtonState = currentstate;
}
if ((millis() - lastDebounceTime) > debounceDelay) { //debounce thermostat on/off button and write status in LCD
if (Thermostatstate != lastButtonState) {
Thermostatstate = lastButtonState;
if (Thermostatstate == HIGH) {
storedState = !storedState; //for now i assume the thermostat on/off button turned into a storedstate
lcd.setCursor(16,1); // this here clears the "OFF" writing from prior, written in storedState==low
lcd.print(" "); // interesting: had in prior code the whole line written, so in loop the word thermostatstate was also refreshed
lcd.setCursor(16,1); // since this is different: whenever off will be written, it now changes AFTER releasing the button... = )
lcd.print("ON");
}
else{if (storedState==LOW){
lcd.setCursor(16,1);
lcd.print("OFF");
}
}
}
}
//stage 3 button up and down settemp - beginn

if(digitalRead(buttonup)== 1 ) { // if we se the switch reading on 1 or 5 volts
settemp ++; // add one to the settemp, the settemp is the ideal temperature for you
}
else{// other wise do nothing
}

if(digitalRead(buttondown)== 1 ){ // if we se the switch reading on 1 or 5 volts
settemp --; // add one to the settemp, the settemp is the ideal temperature for you
}
else{// other wise do nothing
}
//stage 3 button up and down settemp - end

//stage 4 print temps and settemps - beginn
sensors.requestTemperatures();

lcd.setCursor(7,3);
lcd.print (settemp,0); //behind the comma means number of digits behind comma shown on lCD
lcd.setCursor(11,3);
lcd.print ("C / ");
lcd.print(settemp*1.8+32,0); //behind the comma means number of digits behind comma shown on lCD
lcd.setCursor(19,3);
lcd.print("F");

lcd.setCursor(7, 2);
lcd.print(sensors.getTempCByIndex(0),1); //behind the comma means number of digits behind comma shown on lCD
lcd.setCursor(15, 2);
lcd.print(sensors.getTempCByIndex(0)*1.8+32,1); //behind the comma means number of digits behind comma shown on lCD

Serial.println(sensors.getTempCByIndex(0),1);
settemphyst = (settemp-1.5);
lcd.setCursor(14,0);
lcd.print (settemphyst,1);
//stage 4 print temps and settemps - end

Why won't you use auto format and code tags when posting code?

It shouldn't be too much to ask people to format their sketches.


There is no closing brace at the bottom so we do not know if we have the whole sketch

#include <LiquidCrystal_I2C.h> //from new ldc
LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 20 chars and 4 line display

//stage 2 after buttonsystemonoff and lcd setup - beginn
#include <IRLibSendBase.h> //from new sucessful code from internet, this is the base
#include <IRLib_P01_NEC.h> //from new sucessful code from internet, this is the actual protocol
//IRsend mySender; //from new sucessful code from internet, no idea how that matters
#include <DallasTemperature.h> //library from temp sensor 18b20
#include <OneWire.h> //library communication from temp sensor 18b20
// Data wire is plugged into pin 2 on the Arduino //im not sure about that, had to tinker and
#define ONE_WIRE_BUS 2 // when plugged data wire in pin 2 and opened serial mon. temp came in...
// Pass our oneWire reference to Dallas Temperature.
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

float settemp = 25;
float settemphyst;
int ledforactualcooling = 12;
int buttondown = 8;
int buttonup = 10;
//stage 2 after buttonsystemonoff and lcd setup - end

const int buttonsystemonoff = 9; // the number of the pushbutton pin

int storedState; // not sure what that actually does in the code
int Thermostatstate = LOW; // needed for debouncing
int lastButtonState = HIGH; // needed for debouncing
int currentstate; // needed for debouncing
long lastDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 100; // the debounce time; increase if the output flickers

//***************************************************************************
void setup()
{
  //stage 2 after buttonsystemonoff and lcd setup - beginn
  sensors.begin(); //from temp sensor 18b20
  pinMode(buttondown, INPUT);
  pinMode(buttonup, INPUT);
  pinMode(ledforactualcooling, OUTPUT);
  //stage 2 after buttonsystemonoff and lcd setup - end

  pinMode(buttonsystemonoff, INPUT);
  Serial.begin(9600); // start serial communication to Pc program
  lcd.begin(); // initialize the lcd
  lcd.print("Hello guys");
  lcd.setCursor(0, 1);
  lcd.print("MY Invention");
  delay(2000);
  lcd.clear();

  lcd.print("Swamp Cooler");
  lcd.setCursor(0, 1);
  lcd.print("Thermostat");
  lcd.setCursor(0, 2);
  lcd.print("Room T.");
  lcd.setCursor(19, 2);
  lcd.print("C");
  lcd.setCursor(0, 3);
  lcd.print("Set T.");
  lcd.setCursor(11, 2);
  lcd.print("C /");
  lcd.setCursor(19, 2);
  lcd.print("F");
}

//***************************************************************************
void loop()
{
  currentstate = digitalRead(buttonsystemonoff); // my own new interpretation of these three lines of code:
  if (currentstate != lastButtonState)   // button state just changed and still bounces over and over, (lastButtonState = currentState)
  {
    lastDebounceTime = millis(); // keeps changing. both ongoing until it settles. then, we need the following 2nd action to make final comparison to inital state
    lastButtonState = currentstate;
  }
  if ((millis() - lastDebounceTime) > debounceDelay)   //debounce thermostat on/off button and write status in LCD
  {
    if (Thermostatstate != lastButtonState)
    {
      Thermostatstate = lastButtonState;
      if (Thermostatstate == HIGH)
      {
        storedState = !storedState; //for now i assume the thermostat on/off button turned into a storedstate
        lcd.setCursor(16, 1); // this here clears the "OFF" writing from prior, written in storedState==low
        lcd.print(" "); // interesting: had in prior code the whole line written, so in loop the word thermostatstate was also refreshed
        lcd.setCursor(16, 1); // since this is different: whenever off will be written, it now changes AFTER releasing the button... = )
        lcd.print("ON");
      }
      else
      {
        if (storedState == LOW)
        {
          lcd.setCursor(16, 1);
          lcd.print("OFF");
        }
      }
    }
  }
  //stage 3 button up and down settemp - beginn

  if (digitalRead(buttonup) == 1 ) // if we se the switch reading on 1 or 5 volts
  {
    settemp ++; // add one to the settemp, the settemp is the ideal temperature for you
  }
  else // other wise do nothing
  {
  }

  if (digitalRead(buttondown) == 1 ) // if we se the switch reading on 1 or 5 volts
  {
    settemp --; // add one to the settemp, the settemp is the ideal temperature for you
  }
  else // other wise do nothing
  {
  }
  //stage 3 button up and down settemp - end

  //stage 4 print temps and settemps - beginn
  sensors.requestTemperatures();

  lcd.setCursor(7, 3);
  lcd.print (settemp, 0); //behind the comma means number of digits behind comma shown on lCD
  lcd.setCursor(11, 3);
  lcd.print ("C / ");
  lcd.print(settemp * 1.8 + 32, 0); //behind the comma means number of digits behind comma shown on lCD
  lcd.setCursor(19, 3);
  lcd.print("F");

  lcd.setCursor(7, 2);
  lcd.print(sensors.getTempCByIndex(0), 1); //behind the comma means number of digits behind comma shown on lCD
  lcd.setCursor(15, 2);
  lcd.print(sensors.getTempCByIndex(0) * 1.8 + 32, 1); //behind the comma means number of digits behind comma shown on lCD

  Serial.println(sensors.getTempCByIndex(0), 1);
  settemphyst = (settemp - 1.5);
  lcd.setCursor(14, 0);
  lcd.print (settemphyst, 1);
  //stage 4 print temps and settemps - end


1 Like

thank you, yes you are right, i forgot that, sorry. i took a bottom comment out, but other than this bracket nothing is missing. i sent the whole code. thank you

This is a common issue. Depending on the resolution you pick for the sensors, requestTemperatures may take as long as 750mS because it blocks until they are ready.

Fortunately, the library offers you the option to submit the request, keep doing your thing, and go back and collect the temperature(s) later.

BTW how are your button switches wired ?

thank you a lot for this info. but how do i put this in practise? I consider myself still a beginner. a detailed help but be greatly appreciated. thank you a lot!

5volt (pos) goes to all the momentary push buttons. the push buttons are normally open. the other side of each switch is pulled down with an4,7k-ohm resistor. when pushed, 5 volt overcomes the pull down potential and sends 5 volt to the arduino. i am pretty sure my problem is not on the button hardware. thank you for helping