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);
}
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
#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()
//================================================^================================================