├── .gitignore ├── AlphaLicense.txt ├── Button.cpp ├── Button.h ├── Examples ├── Button │ ├── .DS_Store │ └── Button.ino ├── Callbacks │ └── Callbacks.ino ├── Debounce │ └── Debounce.ino ├── StateChanged │ └── StateChanged.ino └── UniquePress │ └── UniquePress.ino ├── keywords.txt └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | build 3 | include 4 | lib 5 | share 6 | *.pyc 7 | .DS_Store 8 | .svn -------------------------------------------------------------------------------- /AlphaLicense.txt: -------------------------------------------------------------------------------- 1 | /* 2 | || 3 | || @file AlphaLicense.txt 4 | || @version 1.0 5 | || @author Alexander Brevig 6 | || @contact alexanderbrevig@gmail.com 7 | || 8 | || @description 9 | || | Describe the rights and expectations when using my code 10 | || # 11 | || 12 | || @license 13 | || | Copyright (c) 2009 Alexander Brevig. All rights reserved. 14 | || | http://www.gnu.org/licenses/lgpl.html 15 | || # 16 | 17 | updated for Arduino 1.0 by Tom Igoe, 27 April 2011 18 | 19 | || 20 | */ 21 | 22 | 23 | All content is released into the public domain, under the terms of the GNU LGPL (latest version). 24 | All code is intellectual property, unless stated otherwise. 25 | All usage of my code is permitted, as long as the headers stay intact ( from /* to */ ) or comply to these rules: 26 | *) You are not permitted to change any of these fields, and they should stay as is: 27 | @file 28 | @version 29 | @author 30 | @contact 31 | @licence 32 | *) You are permitted to modify the @description field, remember to update the changelog 33 | *) You are permitted to add these fields 34 | @contribution 35 | This field has to be inserted immediatly after the @contact with a 'blank' line above and below (blank as in '||') 36 | The changelog should indicate what is contributed 37 | @dependencies 38 | This field has to be inserted immediatly after the @description with a 'blank' line above and below (blank as in '||') 39 | @configuration 40 | This field has to be inserted immediatly after the @description or, if existant, the @dependencies with a 'blank' line above and below (blank as in '||') 41 | *) You are permitted and expected to add to the changelog, if changes or contributions are made. 42 | 43 | Example Header (the header to this file modified according to rules) 44 | /* 45 | || 46 | || @file AlphaLicense.txt 47 | || @version 1.0 48 | || @author Alexander Brevig 49 | || @contact alexanderbrevig@gmail.com 50 | || 51 | || @contribution 52 | || | Name Surname - www.domain.com - contact@domain.com 53 | || # 54 | || 55 | || @description 56 | || | Descripbe the rights and expectations when using my code 57 | || # 58 | || 59 | || @dependencies 60 | || | This file depends on the user having accsess to the internet, in order to read the LGPL 61 | || # 62 | || 63 | || @configuration 64 | || | No configuration needed 65 | || # 66 | || 67 | || @license 68 | || | Copyright (c) 2009 Alexander Brevig. All rights reserved. 69 | || | http://www.gnu.org/licenses/lgpl.html 70 | || # 71 | || 72 | */ 73 | -------------------------------------------------------------------------------- /Button.cpp: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | || 3 | || @file Button.cpp 4 | || @author Alexander Brevig 5 | || @url http://alexanderbrevig.com 6 | || 7 | || @description 8 | || | This is a Hardware Abstraction Library for Buttons 9 | || | It provides an easy way of handling buttons 10 | || # 11 | || 12 | || @license LICENSE_REPLACE 13 | || 14 | */ 15 | 16 | #include 17 | #include "Button.h" 18 | 19 | // bit positions in the state byte 20 | #define CURRENT 0 21 | #define PREVIOUS 1 22 | #define CHANGED 2 23 | 24 | /* 25 | || @constructor 26 | || | Set the initial state of this button 27 | || # 28 | || 29 | || @parameter buttonPin sets the pin that this switch is connected to 30 | || @parameter buttonMode indicates BUTTON_PULLUP or BUTTON_PULLDOWN resistor 31 | */ 32 | Button::Button(uint8_t buttonPin, uint8_t buttonMode, bool _debounceMode, int _debounceDuration){ 33 | pin=buttonPin; 34 | pinMode(pin,INPUT); 35 | 36 | debounceMode = _debounceMode; 37 | debounceDuration = _debounceDuration; 38 | debounceStartTime = millis(); 39 | 40 | buttonMode==BUTTON_PULLDOWN ? pulldown() : pullup(buttonMode); 41 | state = 0; 42 | bitWrite(state,CURRENT,!mode); 43 | 44 | cb_onPress = 0; 45 | cb_onRelease = 0; 46 | cb_onClick = 0; 47 | cb_onHold = 0; 48 | 49 | numberOfPresses = 0; 50 | triggeredHoldEvent = true; 51 | } 52 | 53 | /* 54 | || @description 55 | || | Prepare logic for a pullup button. 56 | || | If mode is internal set pin HIGH as default 57 | || # 58 | */ 59 | void Button::pullup(uint8_t buttonMode) 60 | { 61 | mode=BUTTON_PULLUP; 62 | if (buttonMode == BUTTON_PULLUP_INTERNAL) 63 | { 64 | #ifdef ESP8266 65 | pinMode(pin, INPUT_PULLUP); 66 | #else 67 | digitalWrite(pin,HIGH); 68 | #endif 69 | } 70 | } 71 | 72 | /* 73 | || @description 74 | || | Set pin LOW as default 75 | || # 76 | */ 77 | void Button::pulldown(void) 78 | { 79 | mode=BUTTON_PULLDOWN; 80 | } 81 | 82 | /* 83 | || @description 84 | || | Read and write states; issue callbacks 85 | || # 86 | || 87 | || @return true if button is pressed 88 | */ 89 | void Button::process(void) 90 | { 91 | //save the previous value 92 | bitWrite(state,PREVIOUS,bitRead(state,CURRENT)); 93 | 94 | //get the current status of the pin 95 | if (digitalRead(pin) == mode) 96 | { 97 | //currently the button is not pressed 98 | bitWrite(state,CURRENT,false); 99 | } 100 | else 101 | { 102 | //currently the button is pressed 103 | bitWrite(state,CURRENT,true); 104 | } 105 | 106 | //handle state changes 107 | if (bitRead(state,CURRENT) != bitRead(state,PREVIOUS)) 108 | { 109 | unsigned int interval = millis() - debounceStartTime; 110 | // if(debounceMode){ 111 | // Serial.print("debounceStartTime: "); 112 | // Serial.print(debounceStartTime); 113 | // Serial.print("\tdebounceDuration: "); 114 | // Serial.println(debounceDuration); 115 | // Serial.println(interval); 116 | // } 117 | if(debounceMode && interval < debounceDuration){ 118 | // not enough time has passed; ignore 119 | return; 120 | } 121 | // Serial.println("state changed"); 122 | debounceStartTime = millis(); 123 | //the state changed to PRESSED 124 | if (bitRead(state,CURRENT) == true) 125 | { 126 | numberOfPresses++; 127 | if (cb_onPress) { cb_onPress(*this); } //fire the onPress event 128 | pressedStartTime = millis(); //start timing 129 | triggeredHoldEvent = false; 130 | } 131 | else //the state changed to RELEASED 132 | { 133 | if (cb_onRelease) { cb_onRelease(*this); } //fire the onRelease event 134 | if (cb_onClick) { cb_onClick(*this); } //fire the onClick event AFTER the onRelease 135 | //reset states (for timing and for event triggering) 136 | pressedStartTime = -1; 137 | } 138 | //note that the state changed 139 | bitWrite(state,CHANGED,true); 140 | } 141 | else 142 | { 143 | //note that the state did not change 144 | bitWrite(state,CHANGED,false); 145 | //should we trigger an onHold event? 146 | if (pressedStartTime!=-1 && !triggeredHoldEvent) 147 | { 148 | if (millis()-pressedStartTime > holdEventThreshold) 149 | { 150 | if (cb_onHold) 151 | { 152 | cb_onHold(*this); 153 | triggeredHoldEvent = true; 154 | } 155 | } 156 | } 157 | } 158 | } 159 | 160 | /* 161 | || @description 162 | || | Return the bitRead(state,CURRENT) of the switch 163 | || # 164 | || 165 | || @return true if button is pressed 166 | */ 167 | bool Button::isPressed(bool proc) 168 | { 169 | if(proc) process(); 170 | return bitRead(state,CURRENT); 171 | } 172 | 173 | /* 174 | || @description 175 | || | Return true if the button has been pressed 176 | || # 177 | */ 178 | bool Button::wasPressed(bool proc) 179 | { 180 | if(proc) process(); 181 | return bitRead(state,CURRENT); 182 | } 183 | 184 | /* 185 | || @description 186 | || | Return true if state has been changed 187 | || # 188 | */ 189 | bool Button::stateChanged(bool proc) 190 | { 191 | if(proc) process(); 192 | return bitRead(state,CHANGED); 193 | } 194 | 195 | /* 196 | || @description 197 | || | Return true if the button is pressed, and was not pressed before 198 | || # 199 | */ 200 | bool Button::uniquePress() 201 | { 202 | process(); 203 | return (isPressed(false) && stateChanged(false)); 204 | } 205 | 206 | /* 207 | || @description 208 | || | onHold polling model 209 | || | Check to see if the button has been pressed for time ms 210 | || | This will clear the counter for next iteration and thus return true once 211 | || # 212 | */ 213 | bool Button::held(unsigned int time /*=0*/) 214 | { 215 | process(); 216 | unsigned int threshold = time ? time : holdEventThreshold; //use holdEventThreshold if time == 0 217 | //should we trigger a onHold event? 218 | if (pressedStartTime!=-1 && !triggeredHoldEvent) 219 | { 220 | if (millis()-pressedStartTime > threshold) 221 | { 222 | triggeredHoldEvent = true; 223 | return true; 224 | } 225 | } 226 | return false; 227 | } 228 | 229 | /* 230 | || @description 231 | || | Polling model for holding, this is true every check after hold time 232 | || | Check to see if the button has been pressed for time ms 233 | || # 234 | */ 235 | bool Button::heldFor(unsigned int time) 236 | { 237 | if (isPressed()) 238 | { 239 | if (millis()-pressedStartTime > time) { return true; } 240 | } 241 | return false; 242 | } 243 | 244 | /* 245 | || @description 246 | || | Set the hold event time threshold 247 | || # 248 | */ 249 | void Button::setHoldThreshold(unsigned int holdTime) 250 | { 251 | holdEventThreshold = holdTime; 252 | } 253 | 254 | /* 255 | || @description 256 | || | Register a handler for presses on this button 257 | || # 258 | || 259 | || @parameter handler The function to call when this button is pressed 260 | */ 261 | void Button::pressHandler(buttonEventHandler handler) 262 | { 263 | cb_onPress = handler; 264 | } 265 | 266 | /* 267 | || @description 268 | || | Register a handler for releases on this button 269 | || # 270 | || 271 | || @parameter handler The function to call when this button is released 272 | */ 273 | void Button::releaseHandler(buttonEventHandler handler) 274 | { 275 | cb_onRelease = handler; 276 | } 277 | 278 | /* 279 | || @description 280 | || | Register a handler for clicks on this button 281 | || # 282 | || 283 | || @parameter handler The function to call when this button is clicked 284 | */ 285 | void Button::clickHandler(buttonEventHandler handler) 286 | { 287 | cb_onClick = handler; 288 | } 289 | 290 | /* 291 | || @description 292 | || | Register a handler for when this button is held 293 | || # 294 | || 295 | || @parameter handler The function to call when this button is held 296 | */ 297 | void Button::holdHandler(buttonEventHandler handler, unsigned int holdTime /*=0*/) 298 | { 299 | if (holdTime>0) { setHoldThreshold(holdTime); } 300 | cb_onHold = handler; 301 | } 302 | 303 | /* 304 | || @description 305 | || | Get the time this button has been held 306 | || # 307 | || 308 | || @return The time this button has been held 309 | */ 310 | unsigned int Button::holdTime() const { if (pressedStartTime!=-1) { return millis()-pressedStartTime; } else return 0; } 311 | 312 | /* 313 | || @description 314 | || | Compare a button object against this 315 | || # 316 | || 317 | || @parameter rhs the Button to compare against this Button 318 | || 319 | || @return true if they are the same 320 | */ 321 | bool Button::operator==(Button &rhs) 322 | { 323 | return (this==&rhs); 324 | } 325 | -------------------------------------------------------------------------------- /Button.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | || 3 | || @file Button.cpp 4 | || @author Alexander Brevig 5 | || @url http://alexanderbrevig.com 6 | || 7 | || @description 8 | || | This is a Hardware Abstraction Library for Buttons 9 | || | It providea an easy way of handling buttons 10 | || # 11 | || 12 | || @license LICENSE_REPLACE 13 | || 14 | */ 15 | 16 | #ifndef Button_h 17 | #define Button_h 18 | 19 | #include 20 | 21 | #define BUTTON_PULLUP HIGH 22 | #define BUTTON_PULLUP_INTERNAL 2 23 | #define BUTTON_PULLDOWN LOW 24 | 25 | class Button; 26 | typedef void (*buttonEventHandler)(Button&); 27 | 28 | class Button { 29 | public: 30 | 31 | Button(uint8_t buttonPin, uint8_t buttonMode=BUTTON_PULLUP_INTERNAL, bool _debounceMode=true, int _debounceDuration=20); 32 | 33 | uint8_t pin; 34 | void pullup(uint8_t buttonMode); 35 | void pulldown(); 36 | void process(); 37 | 38 | bool isPressed(bool proc=true); 39 | bool wasPressed(bool proc=true); 40 | bool stateChanged(bool proc=true); 41 | bool uniquePress(); 42 | 43 | void setHoldThreshold(unsigned int holdTime); 44 | bool held(unsigned int time=0); 45 | bool heldFor(unsigned int time); 46 | 47 | void pressHandler(buttonEventHandler handler); 48 | void releaseHandler(buttonEventHandler handler); 49 | void clickHandler(buttonEventHandler handler); 50 | void holdHandler(buttonEventHandler handler, unsigned int holdTime=0); 51 | 52 | unsigned int holdTime() const; 53 | inline unsigned int presses() const { return numberOfPresses; } 54 | 55 | bool operator==(Button &rhs); 56 | 57 | private: 58 | uint8_t mode; 59 | uint8_t state; 60 | bool debounceMode; 61 | unsigned long pressedStartTime; 62 | unsigned int holdEventThreshold; 63 | unsigned long debounceStartTime; 64 | int debounceDuration; 65 | buttonEventHandler cb_onPress; 66 | buttonEventHandler cb_onRelease; 67 | buttonEventHandler cb_onClick; 68 | buttonEventHandler cb_onHold; 69 | unsigned int numberOfPresses; 70 | bool triggeredHoldEvent; 71 | }; 72 | 73 | #endif -------------------------------------------------------------------------------- /Examples/Button/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/t3db0t/Button/3158831359f9b769d4ffaf41a40b832a1e449b6a/Examples/Button/.DS_Store -------------------------------------------------------------------------------- /Examples/Button/Button.ino: -------------------------------------------------------------------------------- 1 | /* 2 | || 3 | || @file Button.ino 4 | || @version 1.1 5 | || @author Alexander Brevig 6 | || @contact alexanderbrevig@gmail.com 7 | || 8 | || @description 9 | || | Display the intuitive way of using a button when using this Hardware Abstraction class 10 | || | Minor fixes by Ted Hayes / ted.hayes@liminastudio.com 11 | || # 12 | || 13 | || @license 14 | || | Copyright (c) 2009 Alexander Brevig. All rights reserved. 15 | || | This code is subject to AlphaLicence.txt 16 | || | alphabeta.alexanderbrevig.com/AlphaLicense.txt 17 | || # 18 | || 19 | */ 20 | 21 | #include 22 | 23 | //create a Button object at pin 12 24 | /* 25 | || Wiring: 26 | || GND -----/ ------ pin 12 27 | */ 28 | Button button = Button(12, BUTTON_PULLUP_INTERNAL); 29 | 30 | void setup(){ 31 | pinMode(13,OUTPUT); //debug to led 13 32 | } 33 | 34 | void loop(){ 35 | if(button.isPressed()){ 36 | digitalWrite(13,HIGH); 37 | }else{ 38 | digitalWrite(13,LOW); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Examples/Callbacks/Callbacks.ino: -------------------------------------------------------------------------------- 1 | /* 2 | || 3 | || @file ChangeState.ino 4 | || @version 1.0 5 | || @author Ted Hayes 6 | || @contact ted.hayes@liminastudio.com 7 | || 8 | || @description 9 | || | Demonstrates the use of asynchronous callback functions instead of synchronous state checks 10 | || # 11 | || 12 | || @license 13 | || | Copyright (c) 2012 Ted Hayes. All rights reserved. 14 | || # 15 | || 16 | */ 17 | 18 | #include 19 | 20 | //create two Button objects for two physical switches 21 | /* 22 | || Wiring: 23 | || GND -----/ ------ pin 12 24 | || GND -----/ ------ pin 11 25 | */ 26 | 27 | // Uses debounce mode. You may need to experiment with the debounce duration 28 | // for your particular switch. 29 | 30 | Button button = Button(12, BUTTON_PULLUP_INTERNAL, true, 50); 31 | Button button2 = Button(11, BUTTON_PULLUP_INTERNAL, true, 50); 32 | 33 | // Callbacks 34 | // "Button& b" is a reference to the button that triggered the callback 35 | // This way we can access its information so we know which button it was 36 | void onPress(Button& b){ 37 | Serial.print("onPress: "); 38 | Serial.println(b.pin); 39 | digitalWrite(13,HIGH); 40 | } 41 | 42 | void onRelease(Button& b){ 43 | Serial.print("onRelease: "); 44 | Serial.println(b.pin); 45 | digitalWrite(13,LOW); 46 | } 47 | 48 | void onHold(Button& b){ 49 | Serial.print("Held for at least 1 second: "); 50 | Serial.println(b.pin); 51 | } 52 | 53 | void setup(){ 54 | Serial.begin(9600); 55 | Serial.println("Started"); 56 | pinMode(13,OUTPUT); //debug to led 13 57 | 58 | // Assign callback functions 59 | button.pressHandler(onPress); 60 | button.releaseHandler(onRelease); 61 | button.holdHandler(onHold, 1000); // must be held for at least 1000 ms to trigger 62 | 63 | button2.pressHandler(onPress); 64 | button2.releaseHandler(onRelease); 65 | button2.holdHandler(onHold, 1000); // must be held for at least 1000 ms to trigger 66 | } 67 | 68 | void loop(){ 69 | // update the buttons' internals 70 | button.process(); 71 | button2.process(); 72 | } -------------------------------------------------------------------------------- /Examples/Debounce/Debounce.ino: -------------------------------------------------------------------------------- 1 | /* 2 | || 3 | || @file ChangeState.ino 4 | || @version 1.0 5 | || @author Ted Hayes 6 | || @contact ted.hayes@liminastudio.com 7 | || 8 | || @description 9 | || | Detects a state change in the button 10 | || # 11 | || 12 | || @license 13 | || | Copyright (c) 2012 Ted Hayes. All rights reserved. 14 | || # 15 | || 16 | */ 17 | 18 | #include 19 | 20 | //create a Button object at pin 12 21 | /* 22 | || Wiring: 23 | || GND -----/ ------ pin 12 24 | */ 25 | 26 | // Uses debounce mode. You may need to experiment with the debounce duration 27 | // for your particular switch. 28 | 29 | Button button = Button(12, BUTTON_PULLUP_INTERNAL, true, 50); 30 | 31 | void setup(){ 32 | Serial.begin(9600); 33 | pinMode(13,OUTPUT); //debug to led 13 34 | } 35 | 36 | void loop(){ 37 | if(button.uniquePress()){ 38 | Serial.println("Button Pressed"); 39 | digitalWrite(13,HIGH); 40 | }else{ 41 | digitalWrite(13,LOW); 42 | } 43 | } -------------------------------------------------------------------------------- /Examples/StateChanged/StateChanged.ino: -------------------------------------------------------------------------------- 1 | /* 2 | || 3 | || @file ChangeState.ino 4 | || @version 1.0 5 | || @author Ted Hayes 6 | || @contact ted.hayes@liminastudio.com 7 | || 8 | || @description 9 | || | Detects a state change in the button 10 | || # 11 | || 12 | || @license 13 | || | Copyright (c) 2012 Ted Hayes. All rights reserved. 14 | || # 15 | || 16 | */ 17 | 18 | #include 19 | 20 | //create a Button object at pin 12 21 | /* 22 | || Wiring: 23 | || GND -----/ ------ pin 12 24 | */ 25 | Button button = Button(12, BUTTON_PULLUP_INTERNAL); 26 | 27 | void setup(){ 28 | Serial.begin(9600); 29 | pinMode(13,OUTPUT); //debug to led 13 30 | } 31 | 32 | void loop(){ 33 | if(button.stateChanged()){ 34 | Serial.println("stateChanged"); 35 | digitalWrite(13,HIGH); 36 | }else{ 37 | digitalWrite(13,LOW); 38 | } 39 | } -------------------------------------------------------------------------------- /Examples/UniquePress/UniquePress.ino: -------------------------------------------------------------------------------- 1 | /* 2 | || 3 | || @file ChangeState.ino 4 | || @version 1.0 5 | || @author Ted Hayes 6 | || @contact ted.hayes@liminastudio.com 7 | || 8 | || @description 9 | || | Detects a state change in the button 10 | || # 11 | || 12 | || @license 13 | || | Copyright (c) 2012 Ted Hayes. All rights reserved. 14 | || # 15 | || 16 | */ 17 | 18 | #include 19 | 20 | //create a Button object at pin 12 21 | /* 22 | || Wiring: 23 | || GND -----/ ------ pin 12 24 | */ 25 | Button button = Button(12, BUTTON_PULLUP_INTERNAL); 26 | 27 | void setup(){ 28 | Serial.begin(9600); 29 | pinMode(13,OUTPUT); //debug to led 13 30 | } 31 | 32 | void loop(){ 33 | if(button.uniquePress()){ 34 | Serial.println("Button Pressed"); 35 | digitalWrite(13,HIGH); 36 | }else{ 37 | digitalWrite(13,LOW); 38 | } 39 | } -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Buttons 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | Button KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | isPressed KEYWORD2 16 | wasPressed KEYWORD2 17 | stateChanged KEYWORD2 18 | uniquePress KEYWORD2 19 | pullup KEYWORD2 20 | pulldown KEYWORD2 21 | 22 | ####################################### 23 | # Constants (LITERAL1) 24 | ####################################### 25 | 26 | PULLUP LITERAL1 27 | PULLDOWN LITERAL1 28 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # New & Improved Arduino Button Library 2 | 3 | _by Ted Hayes, from code originally by Alexander Brevig & Tom Igoe_ 4 | 5 | The Arduino Button library makes it easy to do some very common but rather tedious tasks. Usually when you interact with a button (such as a momentary switch), you mainly want to detect the state change, not just the current state. You have to do something like: 6 | 7 | int lastState = 0; 8 | 9 | void loop(){ 10 | int currentState = digitalRead(11); 11 | if(currentState != lastState){ 12 | // do something 13 | } 14 | lastState = currentState; 15 | } 16 | 17 | It's not hard, just tedious. This new and improved Button library makes this much simpler but adds so much more. Now you can do it this way: 18 | 19 | Button button = Button(12); 20 | 21 | void onPress(Button& b){ 22 | Serial.print("onPress: "); 23 | Serial.println(b.pin); 24 | // will print out "onPress: 12" 25 | } 26 | 27 | void setup(){ 28 | Serial.begin(9600); 29 | // Assign callback function 30 | button.pressHandler(onPress); 31 | } 32 | 33 | void loop(){ 34 | // update the buttons' internals 35 | button.process(); 36 | } 37 | 38 | ## Features 39 | 40 | * Instance-based design 41 | 42 | `Button myButton(11);` 43 | 44 | * Automatic pull-up setting 45 | 46 | `Button myButton(11, BUTTON_PULLUP_INTERNAL);` 47 | 48 | * Simplified state-change detection: 49 | 50 | `if(button.isPressed()) ...` 51 | 52 | * Callback model 53 | 54 | `button.pressHandler(onPress)` 55 | 56 | * Built-in debouncing 57 | 58 | `// Sets 50ms debounce duration` 59 | 60 | `Button button = Button(12, BUTTON_PULLUP_INTERNAL, true, 50);` 61 | 62 | ## Installing 63 | 64 | To install, [download](https://github.com/virgildisgr4ce/Button/zipball/master) the library, extract it to ~/Documents/Arduino/libraries and rename the folder "Button." (Github generates a different name for the zip link.) Restart Arduino if it was already open. 65 | 66 | I hope you find this useful! Please report any bugs using the [Github issue tracker](https://github.com/virgildisgr4ce/Button/issues). --------------------------------------------------------------------------------