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.
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
examples/retrigger/Debug/Makefile
|
||||
*.atsuo
|
||||
examples/retrigger/retrigger.cppproj
|
||||
*.xml
|
||||
examples/retrigger/Visual Micro/.retrigger.vsarduino.h
|
||||
+133
-53
@@ -10,83 +10,163 @@
|
||||
#define DEBOUNCED_STATE 0
|
||||
#define UNSTABLE_STATE 1
|
||||
#define STATE_CHANGED 3
|
||||
#define STATE_HELD_ON 4
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
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;
|
||||
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);
|
||||
#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);
|
||||
}
|
||||
}
|
||||
// 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);
|
||||
|
||||
return state & _BV(STATE_CHANGED);
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
@@ -51,7 +51,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();
|
||||
@@ -64,9 +70,20 @@ 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, retriggers 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;
|
||||
uint8_t state;
|
||||
uint8_t pin;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
====================
|
||||
Example of the held() function for the Bounce 2 library
|
||||
The held() function returns a 1 when the button has been held for a minimum of the hold interval or 500ms which is the default
|
||||
|
||||
An example of using this is in a menu where a user must hold a key down before he/she can edit something.
|
||||
|
||||
*/
|
||||
// Include the Bounce2 library found here :
|
||||
// https://github.com/thomasfredericks/Bounce-Arduino-Wiring
|
||||
#include <Bounce2.h>
|
||||
|
||||
#define BUTTON_PIN 2
|
||||
#define LED_PIN 13
|
||||
|
||||
#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);
|
||||
pinMode(BUTTON_PIN, INPUT);
|
||||
|
||||
//Setup the LED :
|
||||
pinMode(LED_PIN,OUTPUT);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Update the Bounce instance :
|
||||
debouncer.update();
|
||||
|
||||
// Get the updated value :
|
||||
int value = debouncer.held();
|
||||
|
||||
// Turn on or off the LED as determined by the state :
|
||||
if (value) {
|
||||
digitalWrite(LED_PIN, HIGH );
|
||||
}
|
||||
else {
|
||||
digitalWrite(LED_PIN, LOW );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,86 +1,81 @@
|
||||
|
||||
/*
|
||||
/*
|
||||
DESCRIPTION
|
||||
====================
|
||||
Example of the bounce library that shows how to retrigger an event when a button is held down.
|
||||
In this case, the debug LED will blink every 500 ms as long as the button is held down.
|
||||
Example of the retrigger() function of the Bounce 2 library. This function will retrigger a HIGH value after
|
||||
the button has been held on for at least the hold interval (default 500 ms) and then retrigger every retrigger_interval afterwards (default 50ms)
|
||||
This function is great for editing values without repeatedly pressing the button.
|
||||
Open the Serial Monitor (57600 baud) for debug messages.
|
||||
|
||||
*/
|
||||
|
||||
// Include the Bounce2 library found here :
|
||||
// https://github.com/thomasfredericks/Bounce-Arduino-Wiring
|
||||
#include <Bounce2.h>
|
||||
|
||||
#include <Bounce2.h>
|
||||
|
||||
#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);
|
||||
|
||||
int buttonState;
|
||||
unsigned long buttonPressTimeStamp;
|
||||
|
||||
int ledState;
|
||||
unsigned char ledState = 0;
|
||||
|
||||
void setup() {
|
||||
|
||||
Serial.begin(57600);
|
||||
|
||||
// Setup the button
|
||||
pinMode(BUTTON_PIN,INPUT);
|
||||
// Activate internal pull-up
|
||||
digitalWrite(BUTTON_PIN,HIGH);
|
||||
|
||||
// After setting up the button, setup debouncer
|
||||
debouncer.attach(BUTTON_PIN);
|
||||
debouncer.interval(5);
|
||||
|
||||
//Setup the LED
|
||||
pinMode(LED_PIN,OUTPUT);
|
||||
digitalWrite(LED_PIN,ledState);
|
||||
|
||||
|
||||
Serial.begin(57600);
|
||||
|
||||
// Setup the button
|
||||
pinMode(BUTTON_PIN,INPUT);
|
||||
|
||||
//Setup the LED
|
||||
pinMode(LED_PIN,OUTPUT);
|
||||
digitalWrite(LED_PIN,LOW);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Update the debouncer and get the changed state
|
||||
boolean changed = debouncer.update();
|
||||
// Update the debouncer
|
||||
debouncer.update();
|
||||
|
||||
if(debouncer.rose())
|
||||
{
|
||||
ledState = 1;
|
||||
digitalWrite(LED_PIN, ledState);
|
||||
buttonPressTimeStamp = millis();
|
||||
Serial.print(buttonPressTimeStamp);
|
||||
Serial.println(" Button rose!");
|
||||
}
|
||||
// toggle led everytime it retriggers
|
||||
if (debouncer.retrigger())
|
||||
{
|
||||
buttonPressTimeStamp = millis();
|
||||
Serial.print(buttonPressTimeStamp);
|
||||
Serial.println(" Button retriggered!");
|
||||
|
||||
ledState = !ledState;
|
||||
digitalWrite(LED_PIN, ledState);
|
||||
}
|
||||
|
||||
if(debouncer.fell())
|
||||
{
|
||||
ledState = 0;
|
||||
digitalWrite(LED_PIN, ledState);
|
||||
buttonPressTimeStamp = millis();
|
||||
Serial.print(buttonPressTimeStamp);
|
||||
Serial.println(" Button fell!");
|
||||
}
|
||||
|
||||
|
||||
if ( changed ) {
|
||||
// Get the update value
|
||||
int value = debouncer.read();
|
||||
if ( value == HIGH) {
|
||||
ledState = LOW;
|
||||
digitalWrite(LED_PIN, ledState );
|
||||
|
||||
buttonState = 0;
|
||||
Serial.println("Button released (state 0)");
|
||||
|
||||
} else {
|
||||
ledState = HIGH;
|
||||
digitalWrite(LED_PIN, ledState );
|
||||
|
||||
buttonState = 1;
|
||||
Serial.println("Button pressed (state 1)");
|
||||
buttonPressTimeStamp = millis();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ( buttonState == 1 ) {
|
||||
if ( millis() - buttonPressTimeStamp >= 500 ) {
|
||||
buttonPressTimeStamp = millis();
|
||||
if ( ledState == HIGH ) ledState = LOW;
|
||||
else if ( ledState == LOW ) ledState = HIGH;
|
||||
digitalWrite(LED_PIN, ledState );
|
||||
Serial.println("Retriggering button");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user