├── .gitattributes ├── LICENSE ├── README.md ├── examples └── AnalogMultiButton │ └── AnalogMultiButton.ino ├── keywords.txt ├── library.properties └── src ├── AnalogMultiButton.cpp └── AnalogMultiButton.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | MIT License 3 | 4 | Copyright (c) 2016 Damien Clarke 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AnalogMultiButton 2 | 3 | ![AnalogMultiButton](https://user-images.githubusercontent.com/345320/50956995-3b001800-1511-11e9-8d3d-b7e4d88a18cf.jpg) 4 | 5 | AnalogMultiButton is an Arduino library to capture button presses on multiple buttons through a single analog pin. It provides a set of functions to detect when buttons are being held, pressed, released, pressed for a duration, released before or after a specific duration has elapsed, and also allows a button being held to repeatedly report a "press" on a timed interval for use with cursors or scrolling. The library also debounces each button press, it can also cope with different or irregular times between calling update(), and can be used with analog inputs that have an analogRead range other than 0-1023. 6 | 7 | #### One button at a time please... 8 | 9 | While up to ~20 buttons may be connected at a time, please note that the circuit and this library are only capable of capturing one *button press* at a time. If you hold down two buttons at once, only one of them will register. It's a limitation of the circuit being used. If you need to capture multiple simultaneous button presses through a single analog input pin you will need to find another circuit and library. 10 | 11 | ## How to install 12 | In the Arduino IDE, go to Sketch > Include libraries > Manage libraries, and search for AnalogMultiButton. 13 | Or you can also just use the files directly from the src folder. 14 | 15 | ## How to use 16 | This library allows you to detect presses and releases of different buttons using a single analog input pin. To set this up with your Arduino, connect resistors in the following pattern: 17 | 18 | ``` 19 | [5V pin] (or 3.3V pin if your Arduino runs at 3.3V) 20 | | 21 | V 22 | [2.2K resistor] 23 | | 24 | V 25 | [analog input pin] --> button 1 --> GND 26 | | 27 | V 28 | [1K resistor] 29 | | 30 | +--> button 2 --> GND 31 | | 32 | V 33 | [1K resistor] 34 | | 35 | +--> button 3 --> GND 36 | | 37 | V 38 | [1K resistor] 39 | | 40 | +--> button 4 --> GND 41 | | 42 | V 43 | ... etc. 44 | ``` 45 | 46 | The resistors you choose are up to you. The resistor between the 5V pin and the analog input is usually about the same size as the first half of the other resisitors combined. So if we had 4 resistors chained between buttons, where each is 1K, then the 5V-analog resistor would probably be about 1K + 1K = 2K 47 | 48 | Once you have the library installed, try running Serial.println(analogRead(BUTTONS_PIN)); in loop() and press each button. The value being printed should change when each button is pressed, and those values shouldn't be too close to each other. The more evenly spaced the values are betweeon 0 and 1023 the better (the less chance that one button press will be mistaken for another). 49 | 50 | ## Example code 51 | Start a new project and copy and paste the following to try out the library. 52 | 53 | ```C++ 54 | // include the AnalogMultiButton library 55 | #include 56 | 57 | // define the pin you want to use 58 | const int BUTTONS_PIN = A0; 59 | 60 | // set how many buttons you have connected 61 | const int BUTTONS_TOTAL = 3; 62 | 63 | // find out what the value of analogRead is when you press each of your buttons and put them in this array 64 | // you can find this out by putting Serial.println(analogRead(BUTTONS_PIN)); in your loop() and opening the serial monitor to see the values 65 | // make sure they are in order of smallest to largest 66 | const int BUTTONS_VALUES[BUTTONS_TOTAL] = {0, 320, 678}; 67 | 68 | // you can also define constants for each of your buttons, which makes your code easier to read 69 | // define these in the same order as the numbers in your BUTTONS_VALUES array, so whichever button has the smallest analogRead() number should come first 70 | const int BUTTON_RED = 0; 71 | const int BUTTON_GREEN = 1; 72 | const int BUTTON_BLUE = 2; 73 | 74 | // make an AnalogMultiButton object, pass in the pin, total and values array 75 | AnalogMultiButton buttons(BUTTONS_PIN, BUTTONS_TOTAL, BUTTONS_VALUES); 76 | 77 | // pass a fourth parameter to set the debounce time in milliseconds 78 | // this defaults to 20 and can be increased if you're working with particularly bouncy buttons 79 | 80 | void setup() { 81 | // begin serial so we can see which buttons are being pressed through the serial monitor 82 | Serial.begin(9600); 83 | } 84 | 85 | void loop() { 86 | // update the AnalogMultiButton object every loop 87 | buttons.update(); 88 | 89 | // check if BUTTON_RED is pressed 90 | if(buttons.isPressed(BUTTON_RED)) 91 | { 92 | // Serial.println("Button red is pressed"); 93 | } else { 94 | // Serial.println("Button red is not pressed"); 95 | } 96 | 97 | // check if BUTTON_GREEN has just been pressed this update 98 | if(buttons.onPress(BUTTON_GREEN)) 99 | { 100 | Serial.println("Green has been pressed"); 101 | } 102 | 103 | // check if BUTTON_GREEN has just been released this update 104 | if(buttons.onRelease(BUTTON_GREEN)) 105 | { 106 | Serial.println("Green has been released"); 107 | } 108 | 109 | // do this if BUTTON_BLUE has been released 110 | if(buttons.onRelease(BUTTON_BLUE)) 111 | { 112 | Serial.println("Blue has been released"); 113 | } 114 | 115 | // do this once if BUTTON_BLUE has been held for 1 second 116 | if(buttons.onPressAfter(BUTTON_BLUE, 1000)) 117 | { 118 | Serial.println("Blue has been down for 1 second"); 119 | } 120 | 121 | // do this contantly if BUTTON_GREEN has been held down for less than a second 122 | if(buttons.isPressedBefore(BUTTON_GREEN, 1000)) 123 | { 124 | Serial.print("Green is held for "); 125 | Serial.print(buttons.getPressDuration()); 126 | Serial.println(" ms"); 127 | } 128 | 129 | // do this contantly if BUTTON_RED has been held down for more than a second 130 | if(buttons.isPressedAfter(BUTTON_RED, 1000)) 131 | { 132 | Serial.print("Red is held for "); 133 | Serial.print(buttons.getPressDuration()); 134 | Serial.println(" ms"); 135 | } 136 | 137 | // do this if BUTTON_BLUE was released, and it was held for 1 second or less 138 | if(buttons.onReleaseBefore(BUTTON_BLUE, 1000)) 139 | { 140 | Serial.println("Blue has been released after less than 1 second of pressing"); 141 | Serial.print("Blue was held for "); 142 | Serial.print(buttons.getLastReleasePressDuration()); 143 | Serial.println(" ms"); 144 | } 145 | 146 | // do this if BUTTON_BLUE was released, and it was held for 2 seconds or more 147 | if(buttons.onReleaseAfter(BUTTON_BLUE, 2000)) 148 | { 149 | Serial.println("Blue has been released after at least 2 seconds of pressing"); 150 | Serial.print("Blue was held for "); 151 | Serial.print(buttons.getLastReleasePressDuration()); 152 | Serial.println(" ms"); 153 | } 154 | 155 | // 156 | // More examples: 157 | // 158 | // do this once when BUTTON_BLUE is pressed, and again after 1 second 159 | // if(buttons.onPressAndAfter(BUTTON_BLUE, 1000)) {} 160 | // 161 | // do this once if BUTTON_BLUE is held for 1 second, and again every 0.5 seconds after that 162 | // if(buttons.onPressAfter(BUTTON_BLUE, 1000, 500)) {} 163 | // 164 | // do this once when BUTTON_BLUE is pressed, and again after 1 second, and again every 0.5 seconds after that 165 | // useful for cursors or scrolling through menu items 166 | // if(buttons.onPressAndAfter(BUTTON_BLUE, 1000, 500)) {} 167 | // 168 | 169 | delay(10); 170 | } 171 | ``` 172 | 173 | ## Further functionality 174 | See AnalogMultiButton.h for details on any remaining functionality it provides. 175 | 176 | ## License 177 | 178 | Licensed under the MIT License (MIT) 179 | 180 | Copyright (c) 2016, Damien Clarke, [http:/damienclarke.me](http:/damienclarke.me) 181 | 182 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 183 | 184 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 185 | 186 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 187 | -------------------------------------------------------------------------------- /examples/AnalogMultiButton/AnalogMultiButton.ino: -------------------------------------------------------------------------------- 1 | // include the AnalogMultiButton library 2 | #include 3 | 4 | // define the pin you want to use 5 | const int BUTTONS_PIN = A0; 6 | 7 | // set how many buttons you have connected 8 | const int BUTTONS_TOTAL = 3; 9 | 10 | // find out what the value of analogRead is when you press each of your buttons and put them in this array 11 | // you can find this out by putting Serial.println(analogRead(BUTTONS_PIN)); in your loop() and opening the serial monitor to see the values 12 | // make sure they are in order of smallest to largest 13 | const int BUTTONS_VALUES[BUTTONS_TOTAL] = {0, 320, 678}; 14 | 15 | // you can also define constants for each of your buttons, which makes your code easier to read 16 | // define these in the same order as the numbers in your BUTTONS_VALUES array, so whichever button has the smallest analogRead() number should come first 17 | const int BUTTON_RED = 0; 18 | const int BUTTON_GREEN = 1; 19 | const int BUTTON_BLUE = 2; 20 | 21 | // make an AnalogMultiButton object, pass in the pin, total and values array 22 | AnalogMultiButton buttons(BUTTONS_PIN, BUTTONS_TOTAL, BUTTONS_VALUES); 23 | 24 | // pass a fourth parameter to set the debounce time in milliseconds 25 | // this defaults to 20 and can be increased if you're working with particularly bouncy buttons 26 | 27 | void setup() { 28 | // begin serial so we can see which buttons are being pressed through the serial monitor 29 | Serial.begin(9600); 30 | } 31 | 32 | void loop() { 33 | // update the AnalogMultiButton object every loop 34 | buttons.update(); 35 | 36 | // check if BUTTON_RED is pressed 37 | if(buttons.isPressed(BUTTON_RED)) 38 | { 39 | // Serial.println("Button red is pressed"); 40 | } else { 41 | // Serial.println("Button red is not pressed"); 42 | } 43 | 44 | // check if BUTTON_GREEN has just been pressed this update 45 | if(buttons.onPress(BUTTON_GREEN)) 46 | { 47 | Serial.println("Green has been pressed"); 48 | } 49 | 50 | // check if BUTTON_GREEN has just been released this update 51 | if(buttons.onRelease(BUTTON_GREEN)) 52 | { 53 | Serial.println("Green has been released"); 54 | } 55 | 56 | // do this if BUTTON_BLUE has been released 57 | if(buttons.onRelease(BUTTON_BLUE)) 58 | { 59 | Serial.println("Blue has been released"); 60 | } 61 | 62 | // do this once if BUTTON_BLUE has been held for 1 second 63 | if(buttons.onPressAfter(BUTTON_BLUE, 1000)) 64 | { 65 | Serial.println("Blue has been down for 1 second"); 66 | } 67 | 68 | // do this contantly if BUTTON_GREEN has been held down for less than a second 69 | if(buttons.isPressedBefore(BUTTON_GREEN, 1000)) 70 | { 71 | Serial.print("Green is held for "); 72 | Serial.print(buttons.getPressDuration()); 73 | Serial.println(" ms"); 74 | } 75 | 76 | // do this contantly if BUTTON_RED has been held down for more than a second 77 | if(buttons.isPressedAfter(BUTTON_RED, 1000)) 78 | { 79 | Serial.print("Red is held for "); 80 | Serial.print(buttons.getPressDuration()); 81 | Serial.println(" ms"); 82 | } 83 | 84 | // do this if BUTTON_BLUE was released, and it was held for 1 second or less 85 | if(buttons.onReleaseBefore(BUTTON_BLUE, 1000)) 86 | { 87 | Serial.println("Blue has been released after less than 1 second of pressing"); 88 | Serial.print("Blue was held for "); 89 | Serial.print(buttons.getLastReleasePressDuration()); 90 | Serial.println(" ms"); 91 | } 92 | 93 | // do this if BUTTON_BLUE was released, and it was held for 2 seconds or more 94 | if(buttons.onReleaseAfter(BUTTON_BLUE, 2000)) 95 | { 96 | Serial.println("Blue has been released after at least 2 seconds of pressing"); 97 | Serial.print("Blue was held for "); 98 | Serial.print(buttons.getLastReleasePressDuration()); 99 | Serial.println(" ms"); 100 | } 101 | 102 | // 103 | // More examples: 104 | // 105 | // do this once when BUTTON_BLUE is pressed, and again after 1 second 106 | // if(buttons.onPressAndAfter(BUTTON_BLUE, 1000)) {} 107 | // 108 | // do this once if BUTTON_BLUE is held for 1 second, and again every 0.5 seconds after that 109 | // if(buttons.onPressAfter(BUTTON_BLUE, 1000, 500)) {} 110 | // 111 | // do this once when BUTTON_BLUE is pressed, and again after 1 second, and again every 0.5 seconds after that 112 | // useful for cursors or scrolling through menu items 113 | // if(buttons.onPressAndAfter(BUTTON_BLUE, 1000, 500)) {} 114 | // 115 | 116 | delay(10); 117 | } -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | AnalogMultiButton KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | isPressed KEYWORD2 15 | isPressedBefore KEYWORD2 16 | isPressedAfter KEYWORD2 17 | onPress KEYWORD2 18 | onPressAfter KEYWORD2 19 | onPressAndAfter KEYWORD2 20 | onPressAfter KEYWORD2 21 | onPressAndAfter KEYWORD2 22 | onRelease KEYWORD2 23 | onReleaseBefore KEYWORD2 24 | onReleaseAfter KEYWORD2 25 | getPressDuration KEYWORD2 26 | getLastReleasePressDuration KEYWORD2 27 | update KEYWORD2 -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=AnalogMultiButton 2 | version=1.0 3 | author=Damien Clarke 4 | maintainer=Damien Clarke 5 | sentence=An Arduino library to capture button presses on multiple buttons through a single analog pin. 6 | paragraph=Includes debouncing and many options for triggering timed / delayed / repeated press events. 7 | category=Signal Input/Output 8 | url=http://damienclarke.me/code/analog-multi-button 9 | architectures=* -------------------------------------------------------------------------------- /src/AnalogMultiButton.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * AnalogMultiButton.cpp 3 | * A library to capture multiple button presses through a single analog pin 4 | * 5 | * Copyright (c) 2016 Damien Clarke 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | #include 27 | #include "AnalogMultiButton.h" 28 | 29 | AnalogMultiButton::AnalogMultiButton(int pin, int total, const int values[], unsigned int debounceDuration, unsigned int analogResolution) 30 | { 31 | pinMode(pin, INPUT ); // ensure button pin is an input 32 | digitalWrite(pin, LOW ); // ensure pullup is off on button pin 33 | 34 | this->pin = pin; 35 | this->total = total; 36 | this->debounceDuration = debounceDuration; 37 | this->analogResolution = analogResolution; 38 | 39 | for(int i = 0; i < total; i++) { 40 | // determine value boundaries, so we can easily determine which button has the closest value to the current analogRead() 41 | // for example if values were {100, 200, 300}, then we want any value from 0-149 to trigger button 1, 150-245 to trigger button 2 etc... 42 | int nextValue; 43 | if(i+1 < total) 44 | { 45 | nextValue = values[i+1]; 46 | } 47 | else 48 | { 49 | nextValue = analogResolution; 50 | } 51 | valueBoundaries[i] = (values[i] + nextValue)*0.5; 52 | } 53 | } 54 | 55 | void AnalogMultiButton::update() 56 | { 57 | buttonOnPress = -1; 58 | buttonOnRelease = -1; 59 | lastUpdateTime = thisUpdateTime; 60 | thisUpdateTime = millis(); 61 | 62 | int a = analogRead(pin); 63 | int button = getButtonForAnalogValue(a); 64 | if(debounceButton(button) && button != buttonPressed) 65 | { 66 | releasedButtonPressTime = buttonPressTime; 67 | 68 | if(button != -1) 69 | buttonPressTime = thisUpdateTime; 70 | 71 | buttonOnPress = button; 72 | buttonOnRelease = buttonPressed; 73 | 74 | buttonPressed = button; 75 | } 76 | } 77 | 78 | boolean AnalogMultiButton::isPressedBefore(int button, int duration) 79 | { 80 | return buttonPressed == button && (thisUpdateTime < duration + buttonPressTime); 81 | } 82 | 83 | boolean AnalogMultiButton::isPressedAfter(int button, int duration) 84 | { 85 | return buttonPressed == button && (thisUpdateTime >= duration + buttonPressTime); 86 | } 87 | 88 | boolean AnalogMultiButton::onPressAfter(int button, int duration) 89 | { 90 | unsigned long delayedPressTime = duration + buttonPressTime; 91 | return buttonPressed == button && (thisUpdateTime >= delayedPressTime) && (lastUpdateTime < delayedPressTime); 92 | } 93 | 94 | boolean AnalogMultiButton::onPressAndAfter(int button, int duration) 95 | { 96 | return onPress(button) || onPressAfter(button, duration); 97 | } 98 | 99 | boolean AnalogMultiButton::onPressAfter(int button, int duration, int repeatTime) 100 | { 101 | int a = (int(thisUpdateTime - buttonPressTime) - duration + int(repeatTime * 0.5)) / repeatTime; 102 | if(a < 0) 103 | a = 0; 104 | 105 | unsigned long delayedPressTime = duration + buttonPressTime + repeatTime*a; 106 | return buttonPressed == button && (thisUpdateTime >= delayedPressTime) && (lastUpdateTime < delayedPressTime); 107 | } 108 | 109 | boolean AnalogMultiButton::onPressAndAfter(int button, int duration, int repeatTime) 110 | { 111 | return onPress(button) || onPressAfter(button, duration, repeatTime); 112 | } 113 | 114 | boolean AnalogMultiButton::onReleaseBefore(int button, int duration) 115 | { 116 | return buttonOnRelease == button && (thisUpdateTime < duration + releasedButtonPressTime); 117 | } 118 | 119 | boolean AnalogMultiButton::onReleaseAfter(int button, int duration) 120 | { 121 | return buttonOnRelease == button && (thisUpdateTime >= duration + releasedButtonPressTime); 122 | } 123 | 124 | int AnalogMultiButton::getPressDuration() 125 | { 126 | if(buttonPressed == -1) 127 | return 0; 128 | 129 | return thisUpdateTime - buttonPressTime; 130 | } 131 | 132 | int AnalogMultiButton::getButtonForAnalogValue(int value) 133 | { 134 | for(int i = 0; i < total; i++) { 135 | if(value < valueBoundaries[i]) 136 | return i; 137 | } 138 | return -1; 139 | } 140 | 141 | boolean AnalogMultiButton::debounceButton(int button) 142 | { 143 | if(button != lastDebounceButton) 144 | lastDebounceButtonTime = thisUpdateTime; 145 | 146 | lastDebounceButton = button; 147 | return (thisUpdateTime - lastDebounceButtonTime > debounceDuration); 148 | } 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /src/AnalogMultiButton.h: -------------------------------------------------------------------------------- 1 | /* 2 | * AnalogMultiButton.h 3 | * A library to capture multiple button presses through a single analog pin 4 | * 5 | * Copyright (c) 2016 Damien Clarke 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | #ifndef ANALOG_MULTI_BUTTON_H 27 | #define ANALOG_MULTI_BUTTON_H 28 | 29 | #include 30 | 31 | class AnalogMultiButton 32 | { 33 | public: 34 | static const int MAX_BUTTONS = 20; 35 | 36 | // pin - the pin to read 37 | // total - the total number of buttons 38 | // values[] - an array of int analogRead() values that are detected when each button is pressed. This must be in order of lowest button analogRead() value to highest 39 | // debounceDuration - milliseconds that a button must be continually down to count as a press 40 | // analogResolution - nearly always 1024, but sometimes people use different analog input resolutions 41 | 42 | AnalogMultiButton(int pin, int total, const int values[], unsigned int debounceDuration = 20, unsigned int analogResolution = 1024); 43 | 44 | boolean isPressed(int button) { return buttonPressed == button; } // evaluates to true continually while