Ezbutton jumps me out of a while loop

Can the ezButton functions be used as a while loop condition? I have a short program that I thought would print "In Loop" every second while holding a switch down. It only prints 1 time until the switch is released and than pressed again. If I comment out the sw.loop line inside the while loop it will print "In Loop" even after the switch is released.

#include <Arduino.h>
#include <ezButton.h>
#define     sw1 37 

ezButton sw(sw1);

void setup() 
{    
    Serial.begin(15200);
    Serial.println();
    Serial.println("Starting Serial");
    sw.setDebounceTime(50);        
}   

void loop() 
{    
    sw.loop();
    while (sw.isPressed()) 
    {    
      Serial.println("In Loop");      
      sw.loop(); // Update the button state 
      delay(1000);
    }
    Serial.println("out of loop");
    delay(1000);
}   
  • Are you sure you don’t mean 115200 ?

  • All you need for de-bouncing switches is to scan the switches every 20-50ms looking for a change in state.

ezButton is incompatible with the use of delay.

It only works well if you call its service method faster than the debounce interval.

Try a different button library or eliminate the delay.

a7

And… every time you call the service method loop(), you would need to press the button again to get isPressed() to return true.

So maybe it would work, but you not using it correctly.

a7

Thanks
I tried removing the delay but no change. Can you recommend a different library?

  • All you need for de-bouncing switches is to scan the switches every 20-50ms then look for a change in state.

Or use:

SwitchManager


// Class for managing switch presses
// Author: Nick Gammon
// Date: 18 December 2013
// Modified: 12 February 2015 to pass pin number to function


/*
 Example:
 
 #include <SwitchManager.h>
 
 SwitchManager mySwitch;  // declare
 
 // newState will be LOW or HIGH (the is the state the switch is now in)
 // interval will be how many mS between the opposite state and this one
 // whichPin will be which pin caused this change (so you can share the function amongst multiple switches)
 
 void handleSwitchPress (const byte newState, const unsigned long interval, const byte whichPin)
   {
   
   }
 
 void setup ()
   {
   mySwitch.begin (2, handleSwitchPress);
   }
 
 void loop ()
   {
   mySwitch.check ();  // check for presses
   }
 
 
 */

#include <Arduino.h>


class SwitchManager
  {
  enum { debounceTime = 10, noSwitch = -1 };
  typedef void (*handlerFunction) (const byte newState, 
                                   const unsigned long interval, 
                                   const byte whichSwitch);
  
  int pinNumber_;
  handlerFunction f_;
  byte oldSwitchState_;
  unsigned long switchPressTime_;  // when the switch last changed state
  unsigned long lastLowTime_;
  unsigned long lastHighTime_;
  
  public:
  
     // constructor
     SwitchManager () 
       {
       pinNumber_ = noSwitch;
       f_ = NULL;
       oldSwitchState_  = HIGH;
       switchPressTime_ = 0;
       lastLowTime_  = 0;
       lastHighTime_ = 0;
       }
       
     void begin (const int pinNumber, handlerFunction f)
       {
       pinNumber_ = pinNumber;
       f_ = f;
       if (pinNumber_ != noSwitch)
         pinMode (pinNumber_, INPUT_PULLUP);
       }  // end of begin
       
     void check ()
       {
       // we need a valid pin number and a valid function to call
       if (pinNumber_ == noSwitch || f_ == NULL)
         return;
        
        // see if switch is open or closed
        byte switchState = digitalRead (pinNumber_);
        
        // has it changed since last time?
        if (switchState != oldSwitchState_)
          {
          // debounce
          if (millis () - switchPressTime_ >= debounceTime)
             {
             switchPressTime_ = millis ();  // when we closed the switch 
             oldSwitchState_ =  switchState;  // remember for next time 
             if (switchState == LOW)
               {
               lastLowTime_ = switchPressTime_;
               f_ (LOW, lastLowTime_ -  lastHighTime_, pinNumber_);
               }
             else
               {
               lastHighTime_ = switchPressTime_;
               f_ (HIGH, lastHighTime_ - lastLowTime_, pinNumber_);
               }
             
             }  // end if debounce time up
          }  // end of state change
       }  // end of operator ()
       
  };  // class SwitchManager

1 Like

Thanks Much! I had started a reply but you bet me to it.

Here is an example:



#define CLOSED                 LOW
#define OPENED                 HIGH

/*SwitchManager skeleton
  LarryD

  This is sketch is to introduce new people to the SwitchManager library written by Nick Gammon

  The library handles switch de-bouncing and provides timing and state change information in your sketch.
  The SwitchManager.h file should be placed in your libraries folder, i.e.
  C:\Users\YouName\Documents\Arduino\libraries\SwitchManager\SwitchManager.h
  You can download the library at:
  http://gammon.com.au/Arduino/SwitchManager.zip    Thank you Nick!

  In this example we have 2 normally open (N.O.) switches connected to the Arduino - increment and decrement.
  The increment switch will also be used as a "Reset" switch if pressed for more than two seconds.
  The two switches are connected between GND (0 volts) and an Arduino input pin.
  The library enables pull-up resistors for your switch inputs.
  Pushing a switch makes its pin LOW. Releasing a switch makes its pin HIGH.

  The SwitchManager library provides 10ms de-bounce for switches.
  i.e. enum { debounceTime = 10, noSwitch = -1 };
  If you need more time, edit the SwitchManager.h file
  i.e. enum { debounceTime = 50, noSwitch = -1 }; //here it is changed to 50ms
*/

//#include <SwitchManager.h>

//                              C l a s s   S w i t c h M a n a g e r
//================================================^================================================
//
class SwitchManager
{
    enum { debounceTime = 10, noSwitch = -1 };
    typedef void (*handlerFunction) (const byte newState,
                                     const unsigned long interval,
                                     const byte whichSwitch);

    int pinNumber_;
    handlerFunction f_;
    byte oldSwitchState_;
    unsigned long switchPressTime_;  // when the switch last changed state
    unsigned long lastLowTime_;
    unsigned long lastHighTime_;

  public:

    // constructor
    SwitchManager ()
    {
      pinNumber_ = noSwitch;
      f_ = NULL;
      oldSwitchState_  = HIGH;
      switchPressTime_ = 0;
      lastLowTime_  = 0;
      lastHighTime_ = 0;
    }

    void begin (const int pinNumber, handlerFunction f)
    {
      pinNumber_ = pinNumber;
      f_ = f;
      if (pinNumber_ != noSwitch)
        pinMode (pinNumber_, INPUT_PULLUP);
    }  // end of begin

    void check ()
    {
      // we need a valid pin number and a valid function to call
      if (pinNumber_ == noSwitch || f_ == NULL)
        return;

      // see if switch is open or closed
      byte switchState = digitalRead (pinNumber_);

      // has it changed since last time?
      if (switchState != oldSwitchState_)
      {
        // debounce
        if (millis () - switchPressTime_ >= debounceTime)
        {
          switchPressTime_ = millis ();  // when we closed the switch
          oldSwitchState_ =  switchState;  // remember for next time
          if (switchState == LOW)
          {
            lastLowTime_ = switchPressTime_;
            f_ (LOW, lastLowTime_ -  lastHighTime_, pinNumber_);
          }
          else
          {
            lastHighTime_ = switchPressTime_;
            f_ (HIGH, lastHighTime_ - lastLowTime_, pinNumber_);
          }

        }  // end if debounce time up
      }  // end of state change
    }  // end of operator ()

};  // class SwitchManager


//object instantiations
SwitchManager myIncSwitch;
SwitchManager myDecSwitch;


//================================================^================================================
const byte heartBeatLED       = 13;
const byte incSwitch          = 4; //increment switch is on Arduino pin 4
const byte decSwitch          = 5; //decrement switch is on Arduino pin 5

int myCounter;

//timing stuff
unsigned long heartbeatTIMER;
unsigned long incShortPress   = 500UL; //1/2 second
unsigned long incLongPress    = 2000UL;//2 seconds
unsigned long decShortPress   = 500UL; //1/2 second


//                                          s e t u p ( )
//================================================^================================================
//
void setup()
{
  Serial.begin(115200);

  //gives a visual indication if the sketch is blocking
  pinMode(heartBeatLED, OUTPUT);

  //the handleSwitchPresses() function is called when a switch changes state
  myIncSwitch.begin (incSwitch, handleSwitchPresses);
  myDecSwitch.begin (decSwitch, handleSwitchPresses);

} //END of  setup()


//                                           l o o p ( )
//================================================^================================================
//
void loop()
{
  //===========================
  //some code to see if the sketch is blocking
  if (millis() - heartbeatTIMER >= 500ul)
  {
    //restart this TIMER
    heartbeatTIMER = millis();

    //toggle the heartBeatLED
    digitalWrite(heartBeatLED, !digitalRead(heartBeatLED));
  }

  //===========================
  //check to see what's happening with the switches
  //"Do not use delay()s" in your sketch as it will make switch changes unresponsive
  //Use BlinkWithoutDelay (BWD) techniques instead.
  myIncSwitch.check ();
  myDecSwitch.check ();


  //=================================
  //put other non-blocking stuff here
  //=================================

} //END of  loop()


//                               h a n d l e S w i t c h P r e s s e s( )
//================================================^================================================
//
void handleSwitchPresses(const byte newState, const unsigned long interval, const byte whichPin)
{
  //You get here "ONLY" if there has been a change in a switches state.
  //When a switch has changed state, SwitchManager passes this function 3 arguments:
  //"newState" this will be HIGH or LOW. This is the state the switch is in now.
  //"interval" the number of milliseconds the switch stayed in the previous state
  //"whichPin" is the switch pin that we are examining

  //which switch was operated ?
  switch (whichPin)
  {
    //===========================
    //are we dealing with this switch?
    case incSwitch:
      //has this switch gone from LOW to HIGH (gone from pressed to not pressed)
      //this happens with normally open switches wired as mentioned at the top of this sketch
      if (newState == OPENED)
      {
        //The incSwitch was just released
        //was this a short press followed by a switch release
        if (interval <= incShortPress)
        {
          Serial.print("My counter value is = ");
          myCounter++;
          
          //are we at the limit ?
          if (myCounter > 1000)
          {
            //limit the counter to a maximum of 1000
            myCounter = 1000;
          }
          Serial.println(myCounter);
        }

        //was this a long press followed by a switch release
        else if (interval >= incLongPress)
          //we could also have an upper limit
          //if incLongMillis was 2000UL; we could then have a window between 2-3 seconds
          //else if(interval >= incLongMillis && interval <= incLongMillis + 1000UL)
        {
          //this could be used to change states in a StateMachine
          //in this example however, we will just reset myCounter
          myCounter = 0;
          Serial.print("My counter value is = ");
          Serial.println(myCounter);
        }
      }

      //if the switch is a normally closed (N.C.) and opens on a press this section would be used
      //the switch must have gone from HIGH to LOW
      else
      {
        Serial.println("The incSwitch was just pushed");
      }

      break; //End of case incSwitch

    //===========================
    //are we dealing with this switch?
    case decSwitch:

      //has this switch gone from LOW to HIGH (gone from pressed to not pressed)
      //this happens with normally open switches wired as mentioned at the top of this sketch
      if (newState == HIGH)
      {
        //The decSwitch was just released
        //was this a short press followed by a switch release
        if (interval <= decShortPress)
        {
          Serial.print("My counter value is = ");
          myCounter--;
          if (myCounter < 0)
          {
            //don't go below zero
            myCounter = 0;
          }
          Serial.println(myCounter);
        }

      }
      break; //End of case decSwitch

  } //End of   switch/case

} //END of   handleSwitchPresses()

//================================================^================================================



1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.