Files
thomasfredericks_Bounce2/Bounce2.cpp
T
Albert Phan d75d7d0bba Many updates including held() and retrigger()
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.
2015-03-26 17:34:10 -07:00

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));
}