Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
examples/retrigger/Debug/Makefile
*.atsuo
examples/retrigger/retrigger.cppproj
*.xml
examples/retrigger/Visual Micro/.retrigger.vsarduino.h
*.a
*.eep
examples/held/Debug/held.elf
*.hex
examples/held/held.cppproj
examples/retrigger/Debug/retrigger.elf
*.atsln
examples/held/Visual Micro/.held.vsarduino.h
196 changes: 141 additions & 55 deletions Bounce2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,32 @@
#define DEBOUNCED_STATE 0
#define UNSTABLE_STATE 1
#define STATE_CHANGED 3
#define STATE_HELD_ON 4
#define FIRSTUPDATE 5


Bounce::Bounce()
: previous_millis(0)
, interval_millis(10)
, state(0)
, pin(0)
{}
Bounce::Bounce(int pin, uint16_t interval_millis, uint16_t interval_retrigger, uint16_t interval_hold)
{
this->pin = pin;
interval(interval_millis);
holdinterval(interval_hold);
retriggerinterval(interval_retrigger);
previous_millis_state_changed = 0;
state = _BV(FIRSTUPDATE);
}

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
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::attach(int pin, int mode){
Expand All @@ -41,58 +46,139 @@ void Bounce::attach(int pin, int mode){

void Bounce::interval(uint16_t interval_millis)
{
this->interval_millis = 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);
}
}

return state & _BV(STATE_CHANGED);
#endif
// Attaches the pin the first time update is called
if(state & _BV(FIRSTUPDATE))
{
attach(pin);
state &= ~_BV(FIRSTUPDATE);
}
else
{
#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_state_changed != 0)
{
// Checks if it has been longer that retrigger time
if (millis() - previous_millis_state_changed >= interval_retrigger)
{
previous_millis_state_changed = millis();
return true;
}
}
else
{
// sets the millis when first going into function
previous_millis_state_changed = millis();
}
}
return false;
}


bool Bounce::read()
{
return state & _BV(DEBOUNCED_STATE);
return state & _BV(DEBOUNCED_STATE);
}

bool Bounce::rose()
{
return ( state & _BV(DEBOUNCED_STATE) ) && ( state & _BV(STATE_CHANGED));
return ( state & _BV(DEBOUNCED_STATE) ) && ( state & _BV(STATE_CHANGED));
}

bool Bounce::fell()
{
return !( state & _BV(DEBOUNCED_STATE) ) && ( state & _BV(STATE_CHANGED));
return !( state & _BV(DEBOUNCED_STATE) ) && ( state & _BV(STATE_CHANGED));
}

bool Bounce::held()
{
return (state & _BV(STATE_HELD_ON));
}
22 changes: 19 additions & 3 deletions Bounce2.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

/* * * * * * * * * * * * * * * * * * * * * * * * * * * *
Main code by Thomas O Fredericks (tof@t-o-f.info)
Previous contributions by Eric Lowry, Jim Schimpf and Tom Harkaway
Previous contributions by Eric Lowry, Jim Schimpf and Tom Harkaway, Albert Phan
* * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#ifdef BOUNCE_LOCK
Expand All @@ -43,7 +43,7 @@ class Bounce
{
public:
// Create an instance of the bounce library
Bounce();
Bounce(int pin, uint16_t interval_millis = 10, uint16_t interval_retrigger = 50, uint16_t interval_hold = 500);

// Attach to a pin (and also sets initial state)
void attach(int pin);
Expand All @@ -54,7 +54,13 @@ class Bounce
// Sets the debounce interval
void interval(uint16_t interval_millis);

// Updates the pin
// Changes the interval for held()
void holdinterval(uint16_t interval_hold);

// Changes the retrigger interval for retrigger()
void retriggerinterval(uint16_t interval_retrigger);

// Updates the pin
// Returns 1 if the state changed
// Returns 0 if the state did not change
bool update();
Expand All @@ -67,9 +73,19 @@ class Bounce

// Returns the rising pin state
bool rose();

// Returns 1 if state has been held for held interval (default is 500ms)
// Returns 0 if not
bool held();

// After the button has been held down, returns a 1 every interval_repeat(default is 50 ms)
bool retrigger();

protected:
unsigned long previous_millis;
unsigned long previous_millis_state_changed;
uint16_t interval_hold;
uint16_t interval_retrigger;
uint16_t interval_millis;
uint8_t state;
uint8_t pin;
Expand Down
15 changes: 9 additions & 6 deletions examples/bounce/bounce.ino
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,21 @@
#define BUTTON_PIN 2
#define LED_PIN 13

// Instantiate a Bounce object
Bounce debouncer = Bounce();
#define DEBOUNCE_TIME 5
#define HOLD_TIME 1000
#define RETRIGGER_TIME 100

// Instantiate a Bounce object with default values
Bounce debouncer(BUTTON_PIN);

// Or set your own values when instantiating Bounce object
// Bounce debouncer(BUTTON_PIN,DEBOUNCE_TIME, RETRIGGER_TIME, HOLD_TIME);

void setup() {

// Setup the button with an internal pull-up :
pinMode(BUTTON_PIN,INPUT_PULLUP);

// After setting up the button, setup the Bounce instance :
debouncer.attach(BUTTON_PIN);
debouncer.interval(5); // interval in ms

//Setup the LED :
pinMode(LED_PIN,OUTPUT);

Expand Down
17 changes: 10 additions & 7 deletions examples/change/change.ino
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,23 @@
#define BUTTON_PIN 2
#define LED_PIN 13

#define DEBOUNCE_TIME 5
#define HOLD_TIME 1000
#define RETRIGGER_TIME 100

int ledState = LOW;

// Instantiate a Bounce object with default values
Bounce debouncer(BUTTON_PIN);

// Or set your own values when instantiating Bounce object
// Bounce debouncer(BUTTON_PIN,DEBOUNCE_TIME, RETRIGGER_TIME, HOLD_TIME);

// Instantiate a Bounce object :
Bounce debouncer = Bounce();

void setup() {

// Setup the button with an internal pull-up :
pinMode(BUTTON_PIN,INPUT_PULLUP);

// After setting up the button, setup the Bounce instance :
debouncer.attach(BUTTON_PIN);
debouncer.interval(500);
pinMode(BUTTON_PIN,INPUT);

// Setup the LED :
pinMode(LED_PIN,OUTPUT);
Expand Down
15 changes: 9 additions & 6 deletions examples/duration/duration.ino
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,15 @@ a button press (transition from HIGH to LOW).
#define BUTTON_PIN 2
#define LED_PIN 13

// Instantiate a Bounce object :
Bounce debouncer = Bounce();
#define DEBOUNCE_TIME 5
#define HOLD_TIME 1000
#define RETRIGGER_TIME 100

// Instantiate a Bounce object with default values
Bounce debouncer(BUTTON_PIN);

// Or set your own values when instantiating Bounce object
// Bounce debouncer(BUTTON_PIN,DEBOUNCE_TIME, RETRIGGER_TIME, HOLD_TIME);

unsigned long buttonPressTimeStamp;

Expand All @@ -26,10 +33,6 @@ void setup() {
// Setup the button with an internal pull-up :
pinMode(BUTTON_PIN,INPUT_PULLUP);

// After setting up the button, setup the Bounce instance :
debouncer.attach(BUTTON_PIN);
debouncer.interval(5);

// Setup the LED :
pinMode(LED_PIN,OUTPUT);

Expand Down
Loading