Updated Constructors to do all the pin() and interval() setups. All the setup can now be done in one step when instantiating the object. Added held() and retrigger(). See examples. Updated other examples to use the new constructor.
173 lines
3.9 KiB
C++
173 lines
3.9 KiB
C++
// Please read Bounce2.h for information about the liscence and authors
|
|
|
|
#if defined(ARDUINO) && ARDUINO >= 100
|
|
#include "Arduino.h"
|
|
#else
|
|
#include "WProgram.h"
|
|
#endif
|
|
#include "Bounce2.h"
|
|
|
|
#define DEBOUNCED_STATE 0
|
|
#define UNSTABLE_STATE 1
|
|
#define STATE_CHANGED 3
|
|
#define STATE_HELD_ON 4
|
|
|
|
|
|
Bounce::Bounce(int pin, uint16_t interval_millis, uint16_t interval_retrigger, uint16_t interval_hold)
|
|
{
|
|
attach(pin);
|
|
interval(interval_millis);
|
|
holdinterval(interval_hold);
|
|
retriggerinterval(interval_retrigger);
|
|
previous_millis_retrigger = 0;
|
|
}
|
|
|
|
void Bounce::attach(int pin) {
|
|
this->pin = pin;
|
|
bool read = digitalRead(pin);
|
|
state = 0;
|
|
if (digitalRead(pin)) {
|
|
state = _BV(DEBOUNCED_STATE) | _BV(UNSTABLE_STATE);
|
|
}
|
|
#ifdef BOUNCE_LOCK_OUT
|
|
previous_millis = 0;
|
|
#else
|
|
previous_millis = millis();
|
|
#endif
|
|
}
|
|
|
|
void Bounce::interval(uint16_t interval_millis)
|
|
{
|
|
this->interval_millis = interval_millis;
|
|
}
|
|
|
|
void Bounce::holdinterval(uint16_t interval_hold)
|
|
{
|
|
this->interval_hold = interval_hold;
|
|
}
|
|
|
|
void Bounce::retriggerinterval(uint16_t interval_retrigger)
|
|
{
|
|
this->interval_retrigger = interval_retrigger;
|
|
}
|
|
|
|
bool Bounce::update()
|
|
{
|
|
#ifdef BOUNCE_LOCK_OUT
|
|
state &= ~_BV(STATE_CHANGED);
|
|
// Ignore everything if we are locked out
|
|
if (millis() - previous_millis >= interval_millis) {
|
|
bool currentState = digitalRead(pin);
|
|
if ((bool)(state & _BV(DEBOUNCED_STATE)) != currentState) {
|
|
previous_millis = millis();
|
|
state ^= _BV(DEBOUNCED_STATE);
|
|
state |= _BV(STATE_CHANGED);
|
|
}
|
|
}
|
|
return state & _BV(STATE_CHANGED);
|
|
#else
|
|
// Read the state of the switch in a temporary variable.
|
|
bool currentState = digitalRead(pin);
|
|
state &= ~_BV(STATE_CHANGED);
|
|
|
|
// If the reading is different from last reading, reset the debounce counter
|
|
if ( currentState != (bool)(state & _BV(UNSTABLE_STATE)) ) {
|
|
previous_millis = millis();
|
|
state ^= _BV(UNSTABLE_STATE);
|
|
} else
|
|
if ( millis() - previous_millis >= interval_millis ) {
|
|
// We have passed the threshold time, so the input is now stable
|
|
// If it is different from last state, set the STATE_CHANGED flag
|
|
if ((bool)(state & _BV(DEBOUNCED_STATE)) != currentState) {
|
|
previous_millis = millis();
|
|
state ^= _BV(DEBOUNCED_STATE);
|
|
state |= _BV(STATE_CHANGED);
|
|
}
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
//code for checking if state has been held on >= 500ms or interval_hold
|
|
|
|
// If state has changed and has not been held on previously
|
|
if(state & _BV(STATE_CHANGED) && !(state & _BV(STATE_HELD_ON)))
|
|
{
|
|
//If state has been changed before 500ms since last change, reset state change timer
|
|
if(millis() - previous_millis_state_changed < interval_hold)
|
|
{
|
|
previous_millis_state_changed = 0;
|
|
}
|
|
else
|
|
{
|
|
previous_millis_state_changed = millis();
|
|
}
|
|
|
|
}
|
|
// If state has changed and has been held on previously
|
|
else if(state & _BV(STATE_CHANGED) && (state & _BV(STATE_HELD_ON)))
|
|
{
|
|
// Immediately turn off held on state
|
|
state &= ~_BV(STATE_HELD_ON);
|
|
previous_millis_state_changed = 0;
|
|
}
|
|
else if(previous_millis_state_changed != 0)
|
|
{
|
|
//if button has been at a debounced state for >= 500ms
|
|
if(millis() - previous_millis_state_changed >= interval_hold)
|
|
{
|
|
state |= _BV(STATE_HELD_ON);
|
|
previous_millis_state_changed = 0;
|
|
}
|
|
}
|
|
|
|
|
|
return state & _BV(STATE_CHANGED);
|
|
|
|
}
|
|
|
|
bool Bounce::retrigger()
|
|
{
|
|
// if button is being held
|
|
if(this->held())
|
|
{
|
|
if(previous_millis_retrigger != 0)
|
|
{
|
|
// Checks if it has been longer that retrigger time
|
|
if (millis() - previous_millis_retrigger >= interval_retrigger)
|
|
{
|
|
previous_millis_retrigger = millis();
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// sets the millis when first going into function
|
|
previous_millis_retrigger = millis();
|
|
return false;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
bool Bounce::read()
|
|
{
|
|
return state & _BV(DEBOUNCED_STATE);
|
|
}
|
|
|
|
bool Bounce::rose()
|
|
{
|
|
return ( state & _BV(DEBOUNCED_STATE) ) && ( state & _BV(STATE_CHANGED));
|
|
}
|
|
|
|
bool Bounce::fell()
|
|
{
|
|
return !( state & _BV(DEBOUNCED_STATE) ) && ( state & _BV(STATE_CHANGED));
|
|
}
|
|
|
|
bool Bounce::held()
|
|
{
|
|
return (state & _BV(STATE_HELD_ON));
|
|
}
|