diff --git a/Button.cpp b/Button.cpp index 98df134..b998f22 100644 --- a/Button.cpp +++ b/Button.cpp @@ -59,7 +59,7 @@ uint8_t Button::read(void) ms = millis(); pinVal = digitalRead(_pin); if (_invert != 0) pinVal = !pinVal; - if (ms < _lastChange + _dbTime) { + if (ms - _lastChange < _dbTime) { _lastTime = _time; _time = ms; _changed = 0; diff --git a/Examples/LongPress/LongPress.pde b/Examples/LongPress/LongPress.pde new file mode 100644 index 0000000..1f51b56 --- /dev/null +++ b/Examples/LongPress/LongPress.pde @@ -0,0 +1,110 @@ +/*----------------------------------------------------------------------* + * Example sketch for Arduino Button Library by Jack Christensen * + * * + * An example that uses both short and long button presses. * + * * + * A simple state machine where a short press of the button turns the * + * Arduino pin 13 LED on or off, and a long press causes the LED to * + * blink rapidly. Once in rapid blink mode, another long press goes * + * back to on/off mode. * + * * + * This work is licensed under the Creative Commons Attribution- * + * ShareAlike 3.0 Unported License. To view a copy of this license, * + * visit http://creativecommons.org/licenses/by-sa/3.0/ or send a * + * letter to Creative Commons, 171 Second Street, Suite 300, * + * San Francisco, California, 94105, USA. * + *----------------------------------------------------------------------*/ + +#include //https://github.com/JChristensen/Button + +#define BUTTON_PIN 2 //Connect a tactile button switch (or something similar) + //from Arduino pin 2 to ground. +#define PULLUP true //To keep things simple, we use the Arduino's internal pullup resistor. +#define INVERT true //Since the pullup resistor will keep the pin high unless the + //switch is closed, this is negative logic, i.e. a high state + //means the button is NOT pressed. (Assuming a normally open switch.) +#define DEBOUNCE_MS 20 //A debounce time of 20 milliseconds usually works well for tactile button switches. + +#define LED_PIN 13 //The standard Arduino "Pin 13" LED. +#define LONG_PRESS 1000 //We define a "long press" to be 1000 milliseconds. +#define BLINK_INTERVAL 100 //In the BLINK state, switch the LED every 100 milliseconds. + +Button myBtn(BUTTON_PIN, PULLUP, INVERT, DEBOUNCE_MS); //Declare the button + +//The list of possible states for the state machine. This state machine has a fixed +//sequence of states, i.e. ONOFF --> TO_BLINK --> BLINK --> TO_ONOFF --> ONOFF +//Note that while the user perceives two "modes", i.e. ON/OFF mode and rapid blink mode, +//two extra states are needed in the state machine to transition between these modes. +enum {ONOFF, TO_BLINK, BLINK, TO_ONOFF}; +uint8_t STATE; //The current state machine state +boolean ledState; //The current LED status +unsigned long ms; //The current time from millis() +unsigned long msLast; //The last time the LED was switched + +void setup(void) +{ + pinMode(LED_PIN, OUTPUT); //Set the LED pin as an output +} + +void loop(void) +{ + ms = millis(); //record the current time + myBtn.read(); //Read the button + + switch (STATE) { + + //This state watches for short and long presses, switches the LED for + //short presses, and moves to the TO_BLINK state for long presses. + case ONOFF: + if (myBtn.wasReleased()) + switchLED(); + else if (myBtn.pressedFor(LONG_PRESS)) + STATE = TO_BLINK; + break; + + //This is a transition state where we start the fast blink as feedback to the user, + //but we also need to wait for the user to release the button, i.e. end the + //long press, before moving to the BLINK state. + case TO_BLINK: + if (myBtn.wasReleased()) + STATE = BLINK; + else + fastBlink(); + break; + + //The fast-blink state. Watch for another long press which will cause us to + //turn the LED off (as feedback to the user) and move to the TO_ONOFF state. + case BLINK: + if (myBtn.pressedFor(LONG_PRESS)) { + STATE = TO_ONOFF; + digitalWrite(LED_PIN, LOW); + ledState = false; + } + else + fastBlink(); + break; + + //This is a transition state where we just wait for the user to release the button + //before moving back to the ONOFF state. + case TO_ONOFF: + if (myBtn.wasReleased()) + STATE = ONOFF; + break; + } +} + +//Reverse the current LED state. If it's on, turn it off. If it's off, turn it on. +void switchLED() +{ + msLast = ms; //record the last switch time + ledState = !ledState; + digitalWrite(LED_PIN, ledState); +} + +//Switch the LED on and off every BLINK_INETERVAL milliseconds. +void fastBlink() +{ + if (ms - msLast >= BLINK_INTERVAL) + switchLED(); +} + diff --git a/Examples/SimpleOnOff/SimpleOnOff.pde b/Examples/SimpleOnOff/SimpleOnOff.pde new file mode 100644 index 0000000..81547bf --- /dev/null +++ b/Examples/SimpleOnOff/SimpleOnOff.pde @@ -0,0 +1,44 @@ +/*----------------------------------------------------------------------* + * Example sketch for Arduino Button Library by Jack Christensen * + * * + * The simplest example. Using a tactile button switch to turn * + * the Arduino's pin 13 LED on and off. Wire a switch from Arduino * + * pin 2 to ground. * + * * + * This work is licensed under the Creative Commons Attribution- * + * ShareAlike 3.0 Unported License. To view a copy of this license, * + * visit http://creativecommons.org/licenses/by-sa/3.0/ or send a * + * letter to Creative Commons, 171 Second Street, Suite 300, * + * San Francisco, California, 94105, USA. * + *----------------------------------------------------------------------*/ + +#include //https://github.com/JChristensen/Button + +#define BUTTON_PIN 2 //Connect a tactile button switch (or something similar) + //from Arduino pin 2 to ground. +#define PULLUP true //To keep things simple, we use the Arduino's internal pullup resistor. +#define INVERT true //Since the pullup resistor will keep the pin high unless the + //switch is closed, this is negative logic, i.e. a high state + //means the button is NOT pressed. (Assuming a normally open switch.) +#define DEBOUNCE_MS 20 //A debounce time of 20 milliseconds usually works well for tactile button switches. +#define LED_PIN 13 //The standard Arduino "Pin 13" LED + +Button myBtn(BUTTON_PIN, PULLUP, INVERT, DEBOUNCE_MS); //Declare the button +boolean ledState; //A variable that keeps the current LED status + +void setup(void) +{ + pinMode(LED_PIN, OUTPUT); //Set the LED pin as an output +} + +void loop(void) +{ + myBtn.read(); //Read the button + + if (myBtn.wasReleased()) { //If the button was released, change the LED state + ledState = !ledState; + digitalWrite(LED_PIN, ledState); + } +} + + diff --git a/Examples/UpDown/UpDown.pde b/Examples/UpDown/UpDown.pde new file mode 100644 index 0000000..80cf4b7 --- /dev/null +++ b/Examples/UpDown/UpDown.pde @@ -0,0 +1,87 @@ +/*----------------------------------------------------------------------* + * Example sketch for Arduino Button Library by Jack Christensen * + * * + * An example that uses both short and long button presses to adjust * + * a number up and down, between two limits. Short presses increment * + * or decrement by one, long presses repeat at a specified rate. * + * Every time the number changes, it is written to the serial monitor. * + * * + * This work is licensed under the Creative Commons Attribution- * + * ShareAlike 3.0 Unported License. To view a copy of this license, * + * visit http://creativecommons.org/licenses/by-sa/3.0/ or send a * + * letter to Creative Commons, 171 Second Street, Suite 300, * + * San Francisco, California, 94105, USA. * + *----------------------------------------------------------------------*/ + +#include //https://github.com/JChristensen/Button + +#define DN_PIN 2 //Connect two tactile button switches (or something similar) +#define UP_PIN 3 //from Arduino pin 2 to ground and from pin 3 to ground. +#define PULLUP true //To keep things simple, we use the Arduino's internal pullup resistor. +#define INVERT true //Since the pullup resistor will keep the pin high unless the + //switch is closed, this is negative logic, i.e. a high state + //means the button is NOT pressed. (Assuming a normally open switch.) +#define DEBOUNCE_MS 20 //A debounce time of 20 milliseconds usually works well for tactile button switches. + +#define REPEAT_FIRST 500 //ms required before repeating on long press +#define REPEAT_INCR 100 //repeat interval for long press +#define MIN_COUNT 0 +#define MAX_COUNT 59 + +Button btnUP(UP_PIN, PULLUP, INVERT, DEBOUNCE_MS); //Declare the buttons +Button btnDN(DN_PIN, PULLUP, INVERT, DEBOUNCE_MS); + +enum {WAIT, INCR, DECR}; //The possible states for the state machine +uint8_t STATE; //The current state machine state +int count; //The number that is adjusted +int lastCount = -1; //Previous value of count (initialized to ensure it's different when the sketch starts) +unsigned long rpt = REPEAT_FIRST; //A variable time that is used to drive the repeats for long presses + +void setup(void) +{ + Serial.begin(115200); +} + +void loop(void) +{ + btnUP.read(); //read the buttons + btnDN.read(); + + if (count != lastCount) { //print the count if it has changed + lastCount = count; + Serial.println(count, DEC); + } + + switch (STATE) { + + case WAIT: //wait for a button event + if (btnUP.wasPressed()) + STATE = INCR; + else if (btnDN.wasPressed()) + STATE = DECR; + else if (btnUP.wasReleased()) //reset the long press interval + rpt = REPEAT_FIRST; + else if (btnDN.wasReleased()) + rpt = REPEAT_FIRST; + else if (btnUP.pressedFor(rpt)) { //check for long press + rpt += REPEAT_INCR; //increment the long press interval + STATE = INCR; + } + else if (btnDN.pressedFor(rpt)) { + rpt += REPEAT_INCR; + STATE = DECR; + } + break; + + case INCR: //increment the counter + count = min(count++, MAX_COUNT); //but not more than the specified maximum + STATE = WAIT; + break; + + case DECR: //decrement the counter + count = max(count--, MIN_COUNT); //but not less than the specified minimum + STATE = WAIT; + break; + } +} + diff --git a/ReadMe.txt b/ReadMe.txt new file mode 100644 index 0000000..95d0adb --- /dev/null +++ b/ReadMe.txt @@ -0,0 +1,13 @@ +ReadMe file for Arduino Button Library v1.0 +https://github.com/JChristensen/Button +Jack Christensen Mar 2012 + +This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 +Unported License. To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative +Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA. + +-------------------------------------------------------------------------------- +Work in progress. +Please check back later. +Thanks! ... jc