diff --git a/.gitignore b/.gitignore index da48d73..07a5bf6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ examples/retrigger/Debug/Makefile *.atsuo examples/retrigger/retrigger.cppproj *.xml -examples/retrigger/Visual Micro/.retrigger.vsarduino.h \ No newline at end of file +examples/retrigger/Visual Micro/.retrigger.vsarduino.h +*.a \ No newline at end of file diff --git a/Bounce2.cpp b/Bounce2.cpp index 4e00a56..7fe2d7f 100644 --- a/Bounce2.cpp +++ b/Bounce2.cpp @@ -11,15 +11,17 @@ #define UNSTABLE_STATE 1 #define STATE_CHANGED 3 #define STATE_HELD_ON 4 +#define FIRSTUPDATE 5 Bounce::Bounce(int pin, uint16_t interval_millis, uint16_t interval_retrigger, uint16_t interval_hold) { - attach(pin); + this->pin = pin; interval(interval_millis); holdinterval(interval_hold); retriggerinterval(interval_retrigger); previous_millis_retrigger = 0; + state = _BV(FIRSTUPDATE); } void Bounce::attach(int pin) { @@ -53,77 +55,82 @@ void Bounce::retriggerinterval(uint16_t 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) { + // 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); - 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); + 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) { + // If the reading is different from last reading, reset the debounce counter + if ( currentState != (bool)(state & _BV(UNSTABLE_STATE)) ) { previous_millis = millis(); - state ^= _BV(DEBOUNCED_STATE); - state |= _BV(STATE_CHANGED); + 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) + #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))) { - 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); } - - - return state & _BV(STATE_CHANGED); - } bool Bounce::retrigger() @@ -131,19 +138,19 @@ bool Bounce::retrigger() // if button is being held if(this->held()) { - if(previous_millis_retrigger != 0) + if(previous_millis_state_changed != 0) { // Checks if it has been longer that retrigger time - if (millis() - previous_millis_retrigger >= interval_retrigger) + if (millis() - previous_millis_state_changed >= interval_retrigger) { - previous_millis_retrigger = millis(); + previous_millis_state_changed = millis(); return true; } } else { // sets the millis when first going into function - previous_millis_retrigger = millis(); + previous_millis_state_changed = millis(); return false; } diff --git a/Bounce2.h b/Bounce2.h index 8c1059b..a21e926 100644 --- a/Bounce2.h +++ b/Bounce2.h @@ -75,13 +75,12 @@ class Bounce // Returns 0 if not bool held(); - // After the button has been held down, retriggers every interval_repeat(default is 50 ms) + // 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; - unsigned long previous_millis_retrigger; uint16_t interval_hold; uint16_t interval_retrigger; uint16_t interval_millis; diff --git a/examples/retrigger/retrigger.ino b/examples/retrigger/retrigger.ino index 4604b74..527bd31 100644 --- a/examples/retrigger/retrigger.ino +++ b/examples/retrigger/retrigger.ino @@ -31,7 +31,6 @@ unsigned long buttonPressTimeStamp; unsigned char ledState = 0; void setup() { - Serial.begin(57600); // Setup the button @@ -47,15 +46,16 @@ void loop() { // Update the debouncer debouncer.update(); + // If button had a rising transition, turn on led. if(debouncer.rose()) { ledState = 1; digitalWrite(LED_PIN, ledState); - buttonPressTimeStamp = millis(); + buttonPressTimeStamp = millis(); Serial.print(buttonPressTimeStamp); Serial.println(" Button rose!"); } - // toggle led everytime it retriggers + // After holding down the button, retrigger returns a 1 every interval_hold (default = 50 ms) if (debouncer.retrigger()) { buttonPressTimeStamp = millis(); @@ -65,12 +65,12 @@ void loop() { ledState = !ledState; digitalWrite(LED_PIN, ledState); } - + // When button has a falling transition, turn off led. if(debouncer.fell()) { ledState = 0; digitalWrite(LED_PIN, ledState); - buttonPressTimeStamp = millis(); + buttonPressTimeStamp = millis(); Serial.print(buttonPressTimeStamp); Serial.println(" Button fell!"); }