Many updates including new held() and retrigger() #15

Open
AlbertPhan wants to merge 8 commits from AlbertPhan/master into master
8 changed files with 311 additions and 135 deletions
+13
View File
@@ -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
+139 -53
View File
@@ -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){
@@ -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);
// 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);
}
}
// 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
#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));
}
+19 -3
View File
@@ -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);
@@ -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();
@@ -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;
+9 -6
View File
@@ -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);
+10 -7
View File
@@ -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);
+9 -6
View File
@@ -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);
+57
View File
@@ -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 );
}
}
+55 -60
View File
@@ -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 button had a rising transition, turn on led.
if(debouncer.rose())
{
ledState = 1;
digitalWrite(LED_PIN, ledState);
buttonPressTimeStamp = millis();
Serial.print(buttonPressTimeStamp);
Serial.println(" Button rose!");
}
// After holding down the button, retrigger returns a 1 every interval_hold (default = 50 ms)
if (debouncer.retrigger())
{
buttonPressTimeStamp = millis();
Serial.print(buttonPressTimeStamp);
Serial.println(" Button retriggered!");
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();
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");
}
}
}