├── .gitignore ├── keywords.txt ├── library.json ├── src ├── BasicButton │ ├── BasicButton.cpp │ └── BasicButton.h ├── BasicButton.h ├── ButtonEventCallback.h ├── Button.h └── Button │ ├── ButtonEventCallback.cpp │ └── Button.cpp ├── library.properties ├── LICENSE.md ├── .travis.yml ├── examples ├── SerialBasicButton │ └── SerialBasicButton.ino └── SimpleBasicButton │ └── SimpleBasicButton.ino └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | Debug/ 2 | Visual Micro/ 3 | *.atsln 4 | *.atsuo 5 | *.cppproj 6 | Button.ino -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | Button KEYWORD1 2 | is KEYWORD2 3 | isPressed KEYWORD2 4 | onHold KEYWORD2 5 | onHoldRepeat KEYWORD2 6 | onPress KEYWORD2 7 | onRelease KEYWORD2 8 | update KEYWORD2 9 | BasicButton KEYWORD1 10 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "r89m Buttons", 3 | "keywords": "button", 4 | "description": "Handle different types of buttons and button events easily (touch, capacitive, push)", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/r89m/Button.git" 8 | }, 9 | "version": "2.0.1", 10 | "frameworks": "arduino", 11 | "platforms": "*" 12 | } 13 | -------------------------------------------------------------------------------- /src/BasicButton/BasicButton.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * BasicButton.cpp 3 | * 4 | * Created: 18/11/2014 19:33:02 5 | * Author: Richard 6 | */ 7 | 8 | #include 9 | 10 | BasicButton::BasicButton(uint8_t pin){ 11 | 12 | _pin = pin; 13 | pinMode(_pin, INPUT); 14 | } 15 | 16 | boolean BasicButton::_update_button_state(){ 17 | 18 | return (digitalRead(_pin) == HIGH); 19 | } -------------------------------------------------------------------------------- /src/BasicButton.h: -------------------------------------------------------------------------------- 1 | /* 2 | * BasicButton.h 3 | * 4 | * Created: 18/11/2014 19:33:02 5 | * Author: Richard 6 | */ 7 | 8 | #include 9 | 10 | #ifndef BASICBUTTON_H_ 11 | #define BASICBUTTON_H_ 12 | 13 | class BasicButton : public Button{ 14 | 15 | private: 16 | uint8_t _pin; 17 | 18 | protected: 19 | boolean _update_button_state(); 20 | 21 | public: 22 | BasicButton(uint8_t); 23 | 24 | }; 25 | 26 | #endif /* BASICBUTTON_H_ */ -------------------------------------------------------------------------------- /src/BasicButton/BasicButton.h: -------------------------------------------------------------------------------- 1 | /* 2 | * BasicButton.h 3 | * 4 | * Created: 18/11/2014 19:33:02 5 | * Author: Richard 6 | */ 7 | 8 | #include 9 | 10 | #ifndef BASICBUTTON_H_ 11 | #define BASICBUTTON_H_ 12 | 13 | class BasicButton : public Button{ 14 | 15 | private: 16 | uint8_t _pin; 17 | 18 | protected: 19 | boolean _update_button_state(); 20 | 21 | public: 22 | BasicButton(uint8_t); 23 | 24 | }; 25 | 26 | #endif /* BASICBUTTON_H_ */ -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=r89m Buttons 2 | version=2.0.1 3 | author=Richard Miles 4 | maintainer=Richard Miles 5 | sentence=A library that makes working with buttons simple. 6 | paragraph=Supports several different types of buttons (PushButton, CapacitiveButton, MPR121Button) and several button events (Press, Hold, Release). 7 | category=Signal Input/Output 8 | url=https://github.com/r89m/Button 9 | architectures=* 10 | license=CC-BY-SA-3.0 11 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # r89m Buttons Library v2.0.0 2 | https://github.com/r89m/Button 3 | 4 | 5 | Richard Miles April 2016 6 | 7 | ![CC BY-SA](http://mirrors.creativecommons.org/presskit/buttons/88x31/png/by-sa.png) 8 | 9 | ## CC BY-SA 10 | r89m Buttons Library by Richard Miles 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: 11 | Creative Commons 12 | 444 Castro Street, Suite 900 13 | Mountain View, CA 94041 14 | -------------------------------------------------------------------------------- /src/ButtonEventCallback.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Button.h 3 | * 4 | * Created: 18/11/2014 19:33:02 5 | * Author: Richard 6 | */ 7 | 8 | 9 | #ifndef BUTTONEVENTCALLBACK_H 10 | #define BUTTONEVENTCALLBACK_H 11 | 12 | #include 13 | #if (ARDUINO >= 100) 14 | #include 15 | #else 16 | #include 17 | #endif 18 | 19 | #include 20 | 21 | class ButtonEventCallback{ 22 | 23 | private: 24 | EventType _type; 25 | uint16_t _delay; 26 | uint16_t _max_delay; 27 | uint16_t _repeat_period; 28 | uint8_t _execution_count; 29 | 30 | void calculateNextExecutionTime(); 31 | 32 | // Callbacks 33 | ButtonOnEventCallback _callback; 34 | ButtonOnEventRepeatCallback _callback_repeating; 35 | 36 | // Keep track of when the callback should be executed 37 | uint16_t _next_execution_time; 38 | 39 | public: 40 | ButtonEventCallback(); 41 | 42 | EventType getType(); 43 | 44 | void setType(EventType); 45 | void setDelay(uint16_t); 46 | void setMaxDelay(uint16_t); 47 | void setRepetitionPeriod(uint16_t); 48 | void setCallback(ButtonOnEventCallback); 49 | void setRepeatingCallback(ButtonOnEventRepeatCallback); 50 | 51 | void executeCallbackIfTime(uint16_t, boolean, Button&); 52 | void reset(); 53 | 54 | }; 55 | 56 | #endif // BUTTONEVENTCALLBACK_H -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Travis.yml 2 | # Shamelessly stolen from: https://github.com/rlogiacco/MicroDebug/blob/master/.travis.yml 3 | # and from https://github.com/tzapu/WiFiManager/blob/master/.travis.yml via the blog post at: 4 | # https://tzapu.com/automate-arduino-ide-esp8266-build-testing-travisci/ 5 | 6 | language: cpp 7 | 8 | sudo: required 9 | 10 | addons: 11 | apt: 12 | sources: 13 | # - ubuntu-toolchain-r-test 14 | packages: 15 | # - gcc-4.8 16 | # - g++-4.8 17 | 18 | before_install: 19 | # Setup Test Environment 20 | # - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 90 21 | # - sudo update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-4.8 90 22 | 23 | # Get travis-scripts 24 | - git clone https://github.com/r89m/travis-scripts.git 25 | - source $TRAVIS_BUILD_DIR/travis-scripts/arduino.sh 26 | 27 | # Setup Arduino Environment 28 | - setup_env 29 | 30 | # Install coveralls 31 | # - pip install --user cpp-coveralls 32 | 33 | install: 34 | # Check versions 35 | # - g++ --version 36 | # - gcov --version 37 | 38 | # Install Libraries 39 | - install_repo_as_library 40 | 41 | script: 42 | # Run tests 43 | # - cd ${TRAVIS_BUILD_DIR} 44 | # - make test 45 | 46 | # Upload code coverage report 47 | # - coveralls --exclude tests/ --exclude examples/ --gcov-options '\-lp' 48 | 49 | # Check that examples compile 50 | - build_examples 51 | 52 | notifications: 53 | email: 54 | on_success: change 55 | on_failure: change -------------------------------------------------------------------------------- /examples/SerialBasicButton/SerialBasicButton.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // Create an instance of BasicButton reading digital pin 5 6 | BasicButton button = BasicButton(5); 7 | 8 | void setup(){ 9 | 10 | // Open up the serial port so that we can write to it 11 | Serial.begin(9600); 12 | 13 | // When the button is first pressed, call the function onButtonPressed 14 | button.onPress(onButtonPressed); 15 | // Once the button has been held for 1 second (1000ms) call onButtonHeld. Call it again every 0.5s (500ms) until it is let go 16 | button.onHoldRepeat(1000, 500, onButtonHeld); 17 | // When the button is released, call onButtonReleased 18 | button.onRelease(onButtonReleased); 19 | } 20 | 21 | void loop(){ 22 | // Check the state of the button 23 | button.update(); 24 | } 25 | 26 | // btn is a reference to the button that fired the event. That means you can use the same event handler for many buttons 27 | void onButtonPressed(Button& btn){ 28 | 29 | Serial.println("button pressed"); 30 | } 31 | 32 | // duration reports back how long it has been since the button was originally pressed. 33 | // repeatCount tells us how many times this function has been called by this button. 34 | void onButtonHeld(Button& btn, uint16_t duration, uint16_t repeatCount){ 35 | 36 | Serial.print("button has been held for "); 37 | Serial.print(duration); 38 | Serial.print(" ms; this event has been fired "); 39 | Serial.print(repeatCount); 40 | Serial.println(" times"); 41 | } 42 | 43 | // duration reports back the total time that the button was held down 44 | void onButtonReleased(Button& btn, uint16_t duration){ 45 | 46 | Serial.print("button released after "); 47 | Serial.print(duration); 48 | Serial.println(" ms"); 49 | } -------------------------------------------------------------------------------- /src/Button.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Button.h 3 | * 4 | * Created: 18/11/2014 19:33:02 5 | * Author: Richard 6 | */ 7 | 8 | 9 | #ifndef BUTTON_H_ 10 | #define BUTTON_H_ 11 | 12 | #include 13 | #if (ARDUINO >= 100) 14 | #include 15 | #else 16 | #include 17 | #endif 18 | 19 | // The maximum number of callbacks available to each button. A higher number will use more memory and be (slightly) slower 20 | #define MAX_CALLBACKS_PER_BUTTON 3 21 | 22 | // Forward reference 23 | class Button; 24 | 25 | // Define callback types 26 | typedef void (*ButtonOnPressCallback)(Button&); 27 | typedef void (*ButtonOnEventCallback)(Button&, uint16_t); 28 | typedef void (*ButtonOnEventRepeatCallback)(Button&, uint16_t, uint16_t); 29 | 30 | typedef enum {evtUninitialised, evtRelease, evtHold, evtHoldRepeat} EventType; 31 | typedef enum {attSuccessful, attNoMoreRoom} CallbackAttachedResponse; 32 | 33 | #include "ButtonEventCallback.h" 34 | 35 | class Button{ 36 | 37 | private: 38 | uint32_t _button_pressed_timestamp; // When the button was originally pressed 39 | boolean _is_pressed; // Whether or not the button is currently pressed 40 | 41 | ButtonOnPressCallback _on_press_callback; // A callback for when the button is initially pressed 42 | ButtonEventCallback _eventCallbacks[MAX_CALLBACKS_PER_BUTTON]; // An array of callbacks for Release, Hold and HoldRepeat events 43 | 44 | void _button_pressed(); 45 | void _button_released(); 46 | void _button_held(); 47 | uint16_t _button_time_elapsed(); 48 | void _execute_callbacks(boolean); 49 | ButtonEventCallback* getNextAvailableCallback(); 50 | 51 | protected: 52 | virtual boolean _update_button_state()=0; 53 | 54 | public: 55 | Button(); 56 | void onPress(ButtonOnPressCallback); 57 | CallbackAttachedResponse onRelease(ButtonOnEventCallback); 58 | CallbackAttachedResponse onRelease(uint16_t, ButtonOnEventCallback); 59 | CallbackAttachedResponse onRelease(uint16_t, uint16_t, ButtonOnEventCallback); 60 | CallbackAttachedResponse onHold(uint16_t, ButtonOnEventCallback); 61 | CallbackAttachedResponse onHoldRepeat(uint16_t, uint16_t, ButtonOnEventRepeatCallback); 62 | 63 | boolean update(); 64 | boolean is(Button&); 65 | boolean isPressed(); 66 | }; 67 | 68 | #endif /* BUTTON_H_ */ -------------------------------------------------------------------------------- /examples/SimpleBasicButton/SimpleBasicButton.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * BasicButton example. This shows a very basic example of how to register events with a button. 3 | * 4 | * I don't recommend anybody actually use the BasicButton class as it doesn't provide any debouncing facilities or the 5 | * ability to enable internal pullups. It is just to give a very simple demonstration with no additional dependencies. 6 | * For a better option use the PushButton library from the Libraries menu 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | // Create an instance of BasicButton reading digital pin 5 14 | BasicButton button = BasicButton(5); 15 | 16 | void setup(){ 17 | 18 | // Open up the serial port so that we can write to it 19 | Serial.begin(9600); 20 | 21 | // When the button is first pressed, call the function onButtonPressed (further down the page) 22 | button.onPress(onButtonPressed); 23 | // Once the button has been held for 1 second (1000ms) call onButtonHeld. Call it again every 0.5s (500ms) until it is let go 24 | button.onHoldRepeat(1000, 500, onButtonHeld); 25 | // When the button is released, call onButtonReleased 26 | button.onRelease(onButtonReleased); 27 | } 28 | 29 | void loop(){ 30 | // Check the state of the button 31 | button.update(); 32 | } 33 | 34 | // btn is a reference to the button that fired the event. That means you can use the same event handler for many buttons 35 | void onButtonPressed(Button& btn){ 36 | 37 | Serial.println("button pressed"); 38 | } 39 | 40 | // duration reports back how long it has been since the button was originally pressed. 41 | // repeatCount tells us how many times this function has been called by this button. 42 | void onButtonHeld(Button& btn, uint16_t duration, uint16_t repeatCount){ 43 | 44 | Serial.print("button has been held for "); 45 | Serial.print(duration); 46 | Serial.print(" ms; this event has been fired "); 47 | Serial.print(repeatCount); 48 | Serial.println(" times"); 49 | } 50 | 51 | // duration reports back the total time that the button was held down 52 | void onButtonReleased(Button& btn, uint16_t duration){ 53 | 54 | Serial.print("button released after "); 55 | Serial.print(duration); 56 | Serial.println(" ms"); 57 | } 58 | -------------------------------------------------------------------------------- /src/Button/ButtonEventCallback.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ButtonEventCallback.cpp 3 | * 4 | * Created: 18/11/2014 19:33:09 5 | * Author: Richard 6 | */ 7 | 8 | #include "Button.h" 9 | #include "ButtonEventCallback.h" 10 | 11 | // Empty default constructor 12 | ButtonEventCallback::ButtonEventCallback(){ 13 | 14 | // Initialise variables 15 | _type = evtUninitialised; 16 | _delay = 0; 17 | _max_delay = 0; 18 | _repeat_period = 0; 19 | _execution_count = 1; 20 | 21 | _next_execution_time = 0; 22 | } 23 | 24 | EventType ButtonEventCallback::getType(){ 25 | 26 | return _type; 27 | } 28 | 29 | void ButtonEventCallback::setType(EventType type){ 30 | 31 | _type = type; 32 | } 33 | 34 | void ButtonEventCallback::setDelay(uint16_t delay){ 35 | 36 | _delay = delay; 37 | } 38 | 39 | void ButtonEventCallback::setMaxDelay(uint16_t max_delay){ 40 | 41 | _max_delay = max_delay; 42 | } 43 | 44 | void ButtonEventCallback::setRepetitionPeriod(uint16_t repeat_period){ 45 | 46 | _repeat_period = repeat_period; 47 | } 48 | 49 | void ButtonEventCallback::setCallback(ButtonOnEventCallback callback){ 50 | 51 | _callback = callback; 52 | } 53 | 54 | void ButtonEventCallback::setRepeatingCallback(ButtonOnEventRepeatCallback callback_repeating){ 55 | 56 | _callback_repeating = callback_repeating; 57 | } 58 | 59 | void ButtonEventCallback::executeCallbackIfTime(uint16_t elapsedTime, boolean release_event, Button& btn){ 60 | 61 | // Only process callbacks that have been initialised 62 | if(_type != evtUninitialised){ 63 | if (release_event && _type == evtRelease){ // Only check release callbacks at the right time. 64 | if(elapsedTime > _next_execution_time && elapsedTime < _max_delay && _execution_count == 1){ 65 | if(_callback){ 66 | _callback(btn, elapsedTime); 67 | } 68 | _execution_count++; 69 | } 70 | } else if (_type == evtHold){ 71 | if(elapsedTime > _next_execution_time && _execution_count == 1){ 72 | if(_callback){ 73 | _callback(btn, elapsedTime); 74 | } 75 | _execution_count++; 76 | } 77 | } else if (_type == evtHoldRepeat){ 78 | if(elapsedTime > _next_execution_time){ 79 | if(_callback_repeating){ 80 | _callback_repeating(btn, elapsedTime, _execution_count); 81 | } 82 | calculateNextExecutionTime(); 83 | _execution_count++; 84 | } 85 | } 86 | } 87 | } 88 | 89 | void ButtonEventCallback::calculateNextExecutionTime(){ 90 | 91 | _next_execution_time += _repeat_period; 92 | } 93 | 94 | void ButtonEventCallback::reset(){ 95 | 96 | _execution_count = 1; 97 | _next_execution_time = _delay; 98 | } -------------------------------------------------------------------------------- /src/Button/Button.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Button.cpp 3 | * 4 | * Created: 18/11/2014 19:33:09 5 | * Author: Richard 6 | */ 7 | 8 | #include "Button.h" 9 | #include "ButtonEventCallback.h" 10 | 11 | Button::Button(){ 12 | 13 | // Initialise variables 14 | _button_pressed_timestamp = 0; 15 | _is_pressed = 0; 16 | } 17 | 18 | void Button::_button_pressed(){ 19 | 20 | // Set the button pressed state to true 21 | _is_pressed = true; 22 | 23 | // Record when the button was originally pressed 24 | _button_pressed_timestamp = millis(); 25 | 26 | // Fire the onPress callback if one has been specified 27 | if(_on_press_callback){ 28 | _on_press_callback(*this); 29 | } 30 | 31 | // Reset all callbacks 32 | for(uint8_t i = 0; i < MAX_CALLBACKS_PER_BUTTON; i++){ 33 | _eventCallbacks[i].reset(); 34 | } 35 | } 36 | 37 | void Button::_button_released(){ 38 | 39 | // Set the button pressed state to false 40 | _is_pressed = false; 41 | 42 | _execute_callbacks(true); 43 | } 44 | 45 | void Button::_button_held(){ 46 | 47 | _execute_callbacks(false); 48 | } 49 | 50 | void Button::_execute_callbacks(boolean release_event){ 51 | 52 | uint16_t button_time_elapsed = _button_time_elapsed(); 53 | 54 | // Iterate over all callbacks 55 | for(uint8_t i = 0; i < MAX_CALLBACKS_PER_BUTTON - 1; i++){ 56 | _eventCallbacks[i].executeCallbackIfTime(button_time_elapsed, release_event, *this); 57 | } 58 | 59 | } 60 | 61 | uint16_t Button::_button_time_elapsed(){ 62 | 63 | return millis() - _button_pressed_timestamp; 64 | } 65 | 66 | boolean Button::update(){ 67 | 68 | // Record the previous and new state of the button 69 | boolean _previous_button_state = isPressed(); 70 | boolean _new_button_state = _update_button_state(); 71 | 72 | // Record the new state of the button 73 | _is_pressed = _new_button_state; 74 | 75 | //Serial.println("Button Update"); 76 | 77 | // If the state of the button has changed 78 | if(_previous_button_state != _new_button_state){ 79 | // If the button is now pressed 80 | if(_new_button_state){ 81 | _button_pressed(); 82 | } else { 83 | // Otherwise if it has just been let go 84 | _button_released(); 85 | } 86 | return true; // State has changed 87 | // If the state hasn't changed but the button is pressed - ie it is being held 88 | } else if(_new_button_state){ 89 | _button_held(); 90 | } 91 | return false; // State hasn't changed 92 | } 93 | 94 | void Button::onPress(ButtonOnPressCallback callback){ 95 | 96 | _on_press_callback = callback; 97 | } 98 | 99 | CallbackAttachedResponse Button::onRelease(ButtonOnEventCallback callback){ 100 | 101 | return onRelease(0, callback); 102 | } 103 | 104 | CallbackAttachedResponse Button::onRelease(uint16_t wait, ButtonOnEventCallback callback){ 105 | 106 | return onRelease(wait, -1, callback); 107 | } 108 | 109 | CallbackAttachedResponse Button::onRelease(uint16_t wait, uint16_t max_wait, ButtonOnEventCallback callback){ 110 | 111 | ButtonEventCallback* nextCallback = getNextAvailableCallback(); 112 | 113 | if(nextCallback){ 114 | nextCallback->setType(evtRelease); 115 | nextCallback->setDelay(wait); 116 | nextCallback->setMaxDelay(max_wait); 117 | nextCallback->setCallback(callback); 118 | 119 | // Now that we're done, let the user know 120 | return attSuccessful; 121 | } 122 | 123 | // If we get this far, there was no more space to add a handler 124 | return attNoMoreRoom; 125 | } 126 | 127 | CallbackAttachedResponse Button::onHold(uint16_t duration, ButtonOnEventCallback callback){ 128 | 129 | ButtonEventCallback* nextCallback = getNextAvailableCallback(); 130 | 131 | if(nextCallback){ 132 | nextCallback->setType(evtHold); 133 | nextCallback->setDelay(duration); 134 | nextCallback->setCallback(callback); 135 | 136 | // Now that we're done, let the user know 137 | return attSuccessful; 138 | } 139 | 140 | // If we get this far, there was no more space to add a handler 141 | return attNoMoreRoom; 142 | } 143 | 144 | CallbackAttachedResponse Button::onHoldRepeat(uint16_t duration, uint16_t repeat_every, ButtonOnEventRepeatCallback callback){ 145 | 146 | ButtonEventCallback* nextCallback = getNextAvailableCallback(); 147 | 148 | if(nextCallback){ 149 | nextCallback->setType(evtHoldRepeat); 150 | nextCallback->setDelay(duration); 151 | nextCallback->setRepetitionPeriod(repeat_every); 152 | nextCallback->setRepeatingCallback(callback); 153 | 154 | // Now that we're done, let the user know 155 | return attSuccessful; 156 | } 157 | 158 | // If we get this far, there was no more space to add a handler 159 | return attNoMoreRoom; 160 | } 161 | 162 | ButtonEventCallback* Button::getNextAvailableCallback(){ 163 | 164 | for(uint8_t i = 0; i < MAX_CALLBACKS_PER_BUTTON - 1; i++){ 165 | // If this callback handler has not be initialised, we can use it 166 | if(_eventCallbacks[i].getType() == evtUninitialised){ 167 | return &_eventCallbacks[i]; 168 | } 169 | } 170 | 171 | return NULL; 172 | } 173 | 174 | boolean Button::is(Button &btn){ 175 | 176 | return (this == &btn); 177 | } 178 | 179 | boolean Button::isPressed(){ 180 | 181 | return _is_pressed; 182 | } 183 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # r89m Buttons 2 | This library makes working with buttons easy. 3 | 4 | Easily handle button events such as ```onPress```, ```onHold```, ```onHoldRepeat``` and ```onRelease```. The same callback functions can be used with multiple buttons, helping to keep your code cleaner and more manageable. 5 | 6 | Swap button types whenever you want - there's currently 3 supported types - 7 | [```PushButton```](https://github.com/r89m/PushButton), 8 | [```CapacitiveButton```](https://github.com/r89m/CapacitiveButton) and 9 | [```MPR121Button```](https://github.com/r89m/MPR121Button) but it is easy to create your own. 10 | 11 | ## Examples 12 | Here's some basic examples to show you just how easy using this library is! 13 | 14 | ```c++ 15 | #include 16 | #include 17 | #include 18 | 19 | // Create an instance of BasicButton reading digital pin 5 20 | BasicButton button = BasicButton(5); 21 | 22 | void setup(){ 23 | 24 | // When the button is first pressed, call the function onButtonPressed 25 | button.onPress(onButtonPressed); 26 | } 27 | 28 | void loop(){ 29 | // Check the state of the button 30 | button.update(); 31 | } 32 | 33 | void onButtonPressed(Button& btn){ 34 | 35 | // The button was pressed - do something! 36 | } 37 | ``` 38 | 39 | ```c++ 40 | #include 41 | #include 42 | #include 43 | 44 | // Create an instance of BasicButton reading digital pin 5 45 | BasicButton button = BasicButton(5); 46 | 47 | void setup(){ 48 | 49 | // Open up the serial port so that we can write to it 50 | Serial.begin(9600); 51 | 52 | // When the button is first pressed, call the function onButtonPressed 53 | button.onPress(onButtonPressed); 54 | // Once the button has been held for 1 second (1000ms) call onButtonHeld. Call it again every 0.5s (500ms) until it is let go 55 | button.onHoldRepeat(1000, 500, onButtonHeld); 56 | // When the button is released, call onButtonReleased 57 | button.onRelease(onButtonReleased); 58 | } 59 | 60 | void loop(){ 61 | // Check the state of the button 62 | button.update(); 63 | } 64 | 65 | // btn is a reference to the button that fired the event. That means you can use the same event handler for many buttons 66 | void onButtonPressed(Button& btn){ 67 | 68 | Serial.println("button pressed"); 69 | } 70 | 71 | // duration reports back how long it has been since the button was originally pressed. 72 | // repeatCount tells us how many times this function has been called by this button. 73 | void onButtonHeld(Button& btn, uint16_t duration, uint16_t repeatCount){ 74 | 75 | Serial.print("button has been held for "); 76 | Serial.print(duration); 77 | Serial.print(" ms; this event has been fired "); 78 | Serial.print(repeatCount); 79 | Serial.println(" times"); 80 | } 81 | 82 | // duration reports back the total time that the button was held down 83 | void onButtonReleased(Button& btn, uint16_t duration){ 84 | 85 | Serial.print("button released after "); 86 | Serial.print(duration); 87 | Serial.println(" ms"); 88 | } 89 | 90 | ``` 91 | 92 | ## Built-in Button Types 93 | 94 | ### [PushButton](https://github.com/r89m/PushButton) 95 | A simple push button debounced using the Bounce library 96 | 97 | Check out the [examples!](https://github.com/r89m/PushButton/tree/master/examples) 98 | 99 | ### [CapacitiveButton](https://github.com/r89m/CapacitiveButton) 100 | A capacitive touch button utilising the CapSense library 101 | 102 | Check out the [examples!](https://github.com/r89m/CapacitiveButton/tree/master/examples) 103 | 104 | ### [MPR121Button](https://github.com/r89m/MPR121Button) 105 | A capacitive touch button utilising the MPR121 touch switch IC 106 | 107 | Check out the [examples!](https://github.com/r89m/MPR121Button/tree/master/examples) 108 | 109 | ### BasicButton (not recommended!) 110 | A simple button using digitalRead() to determine the state of the button. Does not perform any kind of debouncing, so false positives and multiple calls are likely. Use PushButton instead for a simple button. 111 | 112 | This is only included so that you can get an example up-and-running quickly without needing any other dependencies. 113 | 114 | ## Methods 115 | ### ```boolean update()``` 116 | Update the button state - this will call any callbacks that are necessary. Returns ```true``` if the state changes. 117 | 118 | ### ```boolean is(Button& btn)``` 119 | Return whether or not the button is the same as the ```btn``` passed 120 | 121 | ### ```boolean isPressed()``` 122 | Return whether or not the button is currently pressed. 123 | 124 | ## Callbacks 125 | ### ```CallbackAttachedResponse onPress(onPressCallbackFunction)``` 126 | ```onPressCallbackFunction``` is a function which will be called as soon as the button is pressed. It must be defined with the parameters shown below 127 | ```c++ 128 | void callThisFunctionOnPress(Button& btn){ 129 | // btn is a reference to the button that was pressed. 130 | } 131 | ``` 132 | 133 | 134 | ### ```CallbackAttachedResponse onRelease``` 135 | There are 3 variations of onRelease: 136 | 137 | #### ```CallbackAttachedResponse onRelease(onReleaseCallbackFunction)``` 138 | 139 | ```onReleaseCallbackFunction``` is a function which is called when the button is released. It must be defined with the parameters shown below 140 | ```c++ 141 | void callThisFunctionOnRelease(Button& btn, uint_16t duration){ 142 | // btn is a reference to the button that was pressed 143 | // duration is how long the button was pressed for 144 | } 145 | ``` 146 | 147 | #### ```CallbackAttachedResponse onRelease(uint_16t wait, onReleaseCallbackFunction)``` 148 | 149 | As above, plus: 150 | 151 | ```wait``` if the button is held for at-least ```wait```ms ```onReleaseCallbackFunction``` will be called. 152 | 153 | #### ```CallbackAttachedResponse onRelease(uint_16t wait, uint_16t max_wait, onReleaseCallbackFunction)``` 154 | 155 | As above, plus: 156 | 157 | ```max_wait``` if the button is held for more than ```max_wait```ms ```onReleaseCallbackFunction``` will not be called. 158 | 159 | 160 | ### ```CallbackAttachedResponse onHold(uint_16t duration, onHoldCallbackFunction)``` 161 | 162 | ```duration``` how long the button must be held before ```onHoldCallbackFunction``` is called. 163 | ```onHoldCallbackFunction``` is a function which is called when the button is held. It must be defined with the parameters shown below 164 | 165 | ```c++ 166 | void callThisFuntionOnHold(Button& btn, uint_16t duration){ 167 | // btn is a reference to the button that was held 168 | // duration is how long the button was held for 169 | } 170 | ``` 171 | 172 | ### ```CallbackAttachedResponse onHoldAndRepeat(uint_16t duration, uint_16t repeat_every, onHoldAndRepeatCallbackFunction)``` 173 | 174 | ```duration``` how long the button must be held before ```onHoldAndRepeatCallbackFunction``` is called. 175 | ```repeat_every``` how long to wait before ```onHoldAndRepeatCallbackFunction``` is called repeatedly. 176 | ```onHoldAndRepeatCallbackFunction``` is a function which is called repeatedly when the button is held. It must be defined with the parameters shown below 177 | 178 | ```c++ 179 | void callThisFunctionOnHoldAndRepeat(Button& btn, uint16_t duration, uint8_t repeat_count){ 180 | // btn is a reference to the button that was held 181 | // duration is how long the button has been held for 182 | // repeat_count is the number of times the callback has been called 183 | } 184 | ``` 185 | 186 | ## Enums 187 | 188 | ### ```CallbackAttachedResponse``` 189 | ```attSuccessful``` returned when a callback has successfully been attached 190 | 191 | ```attNoMoreRoom``` returned when a callback could not be attached because there is not enough room. Check ```MAX_CALLBACKS_PER_BUTTON```. 192 | 193 | ## Constants 194 | 195 | ### ```MAX_CALLBACKS_PER_BUTTON (default=3)``` 196 | Defines the maximum number of callbacks per button. Increasing this number will allow more callbacks but will use marginally more memory and processing power. This can be changed on a sketch by sketch basis, simply define ```#MAX_CALLBACKS_PER_BUTTON``` before your ```#include```s. 197 | --------------------------------------------------------------------------------