This Arduino library is improving the usage of a singe button for input. It allows using a digital input pin with a single pushbutton attached and detecting some of the typical button press events like single clicks, double clicks, multple clicks and long-time pressing. This enables you to reuse the same button for multiple functions and lowers the hardware investments.
This is also a sample for implementing simple finite-state machines by using the simple pattern above.
You can find more details on this library at http://www.mathertel.de/Arduino/OneButtonLibrary.aspx
Modified by [email protected]
Major Modification:
- added new functions:
multiClick()for multiple 3+ clicks (for 3 clicks and more)getNumberClicks()to return number of multiple clicks;attachPressStart()to mainatin compatibility with the new release v1.5 of the parent library: fires immediately as the button is pressed down.
21.01.2021
- added
isIdle()function to maintain compatibility with original library developments - renamed
tripleClick()tomultiClick()to maintain compatibility - made some more optimization to decrease size
12.02.2020
- modified state machine (still same number of states), maintained full compatibility with the initial library;
- introduced a new functions:
multiClickFunc()for multiple 3+ clicks;getNumberClicks()to return number of clicks; - optimized - changed some types of variables (f.e.:
bool _buttonPressed,uint8_t _state) to compact the code; - optimized - by using
switch()instead of multipleif()-s; - introdiced
#define PARAM_FUNC- if commented inoneButton.h, the call functions with parameters will not be used to save space; - modified
SimpleOneButtonexample to test more functions incl. newmultiClickFunc()andgetNumberClicks()functions.
23.06.2020
- sync up with the original library, release v1.5, by adding the new function
attachPressStart(). - extensed
SimpleOneButtonexample that includes new function and allows to test almost all library functions.
If you like new functions and use the modified library, please, consider making a small "cup of coffee" donation using PayPal
Clone this repository into Arduino/Libraries or use the built-in Arduino IDE Library manager to install
a copy of this library. You can find more detail about installing libraries
here, on Arduino's website.
#include <Arduino.h>
#include <OneButton.h>Each physical button requires its own OneButton instance. You can initialize them like this:
#define BUTTON_PIN 4
/**
* Initialize a new OneButton instance for a button
* connected to digital pin 4 and GND, which is active low
* and uses the internal pull-up resistor.
*/
OneButton btn = OneButton(
BUTTON_PIN, // Input pin for the button
LOW, // Button is active LOW
true // Enable internal pull-up resistor
);The same by using active low as a default settings:
OneButton btn = OneButton( BUTTON_PIN ); // Input pin for the button#define BUTTON_PIN 4
/**
* Initialize a new OneButton instance for a button
* connected to digital pin 4, which is active high.
* As this does not use any internal resistor
* an external resistor (4.7k) may be required to create a LOW signal when the button is not pressed.
*/
OneButton btn = OneButton(
BUTTON_PIN, // Input pin for the button
HIGH, // Button is active high
false // Disable internal pull-up resistor
);Once you have your button initialized, you can handle events by attaching them to the button instance. Events can either be static functions or lambdas (without captured variables).
// Handler function for a single click:
static void handleClick() {
Serial.println("Clicked!");
}
// Single Click event attachment
btn.attachClick(handleClick);
// Double Click event attachment with lambda
btn.attachDoubleClick([]() {
Serial.println("Double Click!");
};
// Triple Click event attachment
btn.attachMultiClick([]() {
Serial.println("Multi Click!");
};In order for OneButton to work correctly, you must call tick() on each button instance
within your main loop(). If you're not getting any button events, this is probably why.
You may also call tick() from PinChangeInterupt routine to make buttons more reponsive. Please, refer to InterruptOneButton example.
void loop() {
btn.tick();
// Do other things...
}Here's a full list of events handled by this library:
| Attach Function | Description |
|---|---|
attachClick |
Fires as soon as a single click is detected. |
attachDoubleClick |
Fires as soon as a double click is detected. |
attachMultiClick |
NEW Fires as soon as multiple 3+ click are detected. |
attachPressStart |
NEW Fires as soon as the button is pressed down. |
attachLongPressStart |
Fires as soon as the button is held down for 1 second. |
attachDuringLongPress |
Fires periodically as long as the button is held down. |
attachLongPressStop |
Fires when the button is released after a long hold. |
Valid events occur when tick() is called after a specified number of milliseconds. You can use
the following functions to change the timing.
Note: Attaching a double click will increase the delay for detecting a single click. If a double click event is not attached, the library will assume a valid single click after one click duration, otherwise it must wait for the double click timeout to pass.
| Function | Default (ms) | Description |
|---|---|---|
setDebounceTicks(int) |
50 |
Period of time in which to ignore additional level changes. |
setClickTicks(int) |
400 |
Timeout used to distinguish single clicks from double clicks. |
setPressTicks(int) |
800 |
Duration to hold a button to trigger a long press. |
OneButton also provides a couple additional functions to use for querying button status:
| Function | Description |
|---|---|
bool isLongPressed() |
Detect whether or not the button is currently inside a long press. |
bool isIdle() |
NEW Returns true if no button press is under processing |
int getPressedTicks() |
Get the current number of milliseconds that the button has been held down for. |
uint8_t getNumberClicks() |
NEW Get number of detected clicks. Return single or multiple number of clicks. |
You can specify a logic level when calling tick(bool), which will skip reading the pin and use
that level instead. If you wish to reset the internal state of your buttons, call reset().
If your buttons aren't acting they way they should, check these items:
- Check your wiring and pin numbers.
- Did you call
tick()on each button instance in your loop? - Did you alter your clock timers in any way without adjusting ticks?
If you like new functions and use the modified library, please, consider making a small "cup of coffee" donation using PayPal