211 lines
3.6 KiB
C++
211 lines
3.6 KiB
C++
|
|
/*
|
|
* Check Bounce2.h for licensing / authors.
|
|
*/
|
|
|
|
#include "Bounce2.h"
|
|
|
|
|
|
/*
|
|
* Debounce
|
|
*/
|
|
|
|
Debouncer::Debouncer():previous_millis(0)
|
|
, interval_millis(10)
|
|
, state(0) {}
|
|
|
|
void Debouncer::interval(uint16_t interval_millis){
|
|
this -> interval_millis = interval_millis;
|
|
}
|
|
|
|
|
|
void Debouncer::begin(){
|
|
|
|
state = 0;
|
|
|
|
if(readCurrentState())
|
|
setStateFlag(DEBOUNCED_STATE | UNSTABLE_STATE);
|
|
|
|
#ifdef BOUNCE_LOCK_OUT
|
|
previous_millis = 0;
|
|
#else
|
|
updateTime();
|
|
#endif
|
|
}
|
|
|
|
|
|
#ifdef BOUNCE_LOCK_OUT
|
|
|
|
|
|
bool Debouncer::update(){
|
|
|
|
unsetStateFlag(CHANGED_STATE);
|
|
|
|
// Ignore everything if we are locked out
|
|
|
|
if(thresholdPassed()){
|
|
|
|
bool currentState = readCurrentState();
|
|
|
|
if(currentState != getStateFlag(DEBOUNCED_STATE)){
|
|
updateTime();
|
|
changeState();
|
|
}
|
|
}
|
|
|
|
return changed();
|
|
}
|
|
|
|
|
|
#elif defined BOUNCE_WITH_PROMPT_DETECTION
|
|
|
|
|
|
bool Debouncer::update(){
|
|
|
|
unsetStateFlag(CHANGED_STATE);
|
|
|
|
|
|
/*
|
|
* Switch Port State 🠖 Temporary Variable
|
|
*/
|
|
|
|
bool readState = readCurrentState();
|
|
|
|
|
|
// Check if the button state has changed
|
|
|
|
if(readState != getStateFlag(DEBOUNCED_STATE)){
|
|
|
|
/*
|
|
* Enough time has passed
|
|
* ⤷ New state changes are allowed
|
|
*
|
|
* Set Flags:
|
|
* - STATE_CHANGED
|
|
* - DEBOUNCED_STATE
|
|
*/
|
|
|
|
if(thresholdPassed())
|
|
changeState();
|
|
}
|
|
|
|
|
|
/*
|
|
* If readState ≠ to it's previous state
|
|
* ⤷ Reset the debounce timer
|
|
*
|
|
* This is done, as input is still unstable
|
|
* and we want to prevent new button state
|
|
* changes until the previous state has
|
|
* remained stable for the timeout.
|
|
*/
|
|
|
|
if(readState != getStateFlag(UNSTABLE_STATE)){
|
|
|
|
// Update unstable bit to match readState
|
|
|
|
toggleStateFlag(UNSTABLE_STATE);
|
|
updateTime();
|
|
}
|
|
|
|
return changed();
|
|
}
|
|
|
|
|
|
#else
|
|
|
|
|
|
bool Debouncer::update(){
|
|
|
|
unsetStateFlag(CHANGED_STATE);
|
|
|
|
|
|
/*
|
|
* Switch Port State 🠖 Temporary Variable
|
|
*/
|
|
|
|
bool currentState = readCurrentState();
|
|
|
|
|
|
/*
|
|
* If the reading ≠ to it's previous state
|
|
* ⤷ Reset the debounce counter
|
|
*/
|
|
|
|
if(currentState != getStateFlag(UNSTABLE_STATE)){
|
|
updateTime();
|
|
toggleStateFlag(UNSTABLE_STATE);
|
|
} else
|
|
if(thresholdPassed()){
|
|
|
|
/*
|
|
* We have passed the threshold time
|
|
* ⤷ The input is now stable
|
|
*
|
|
* If it is ≠ to it's previous state
|
|
* ⤷ Set the STATE_CHANGED flag
|
|
*/
|
|
|
|
if(currentState != getStateFlag(DEBOUNCED_STATE)){
|
|
updateTime();
|
|
changeState();
|
|
}
|
|
}
|
|
|
|
return changed();
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
* Work In Progress
|
|
* HELD
|
|
*/
|
|
|
|
unsigned long Debouncer::previousDuration() const {
|
|
return durationOfPreviousState;
|
|
}
|
|
|
|
|
|
unsigned long Debouncer::currentDuration() const {
|
|
return millis() - stateChangeLastTime;
|
|
}
|
|
|
|
|
|
inline void Debouncer::changeState(){
|
|
|
|
toggleStateFlag(DEBOUNCED_STATE);
|
|
setStateFlag(CHANGED_STATE) ;
|
|
|
|
durationOfPreviousState = millis() - stateChangeLastTime;
|
|
stateChangeLastTime = millis();
|
|
}
|
|
|
|
|
|
bool Debouncer::read() const {
|
|
return getStateFlag(DEBOUNCED_STATE);
|
|
}
|
|
|
|
|
|
bool Debouncer::rose() const {
|
|
return getStateFlag(DEBOUNCED_STATE)
|
|
&& getStateFlag(CHANGED_STATE);
|
|
}
|
|
|
|
|
|
bool Debouncer::fell() const {
|
|
return ! getStateFlag(DEBOUNCED_STATE)
|
|
&& getStateFlag(CHANGED_STATE);
|
|
}
|
|
|
|
|
|
inline bool Debouncer::thresholdPassed(){
|
|
return millis() - previous_millis >= interval_millis;
|
|
}
|
|
|
|
inline void Debouncer::updateTime(){
|
|
previous_millis = millis();
|
|
} |