A simple Arduino library to assign multiple functions to a single push button, depending on how long it is pressed. Can provide feedback to the user indicating when to release the button to trigger a specific function.
#include <InfiniteFunctionButton.h>
/*!
@brief The class constructor.
@param[in] gpio The gpio to use.
@param[in] debounceTime The debounce time, in milliseconds.
@param[in] activeHigh Specify if the button is wired to output a HIGH state when pressed.
@details Pick a pin that supports interrupts on your microcontroller (2 or 3 for Arduino Uno).
I found 25ms debounce time to work well with my test 6x6mm push button switch.
When activeHigh is false or not specified, the pin will be set up as INPUT_PULLUP
and the button should be connected to short it to ground when pressed.
Likewise, when activeHigh is true, the pin will be set up as INPUT
and a HIGH state will represent the button being pressed.
Remember to provide your own pulldown resistor in this setting.
*/
InfiniteFunctionButton button(2, 25);
void testISR() { // add IRAM_ATTR if using ESP!
button.onInterrupt();
}
void setup() {
Serial.begin(115200);
button.addIntermediateFunction(1000, []() {
Serial.println("The button has been released in less than 1 second.");
Serial.println("Function A activated.");
}, NULL);
button.addIntermediateFunction(2000, []() {
Serial.println("The button has been released in less than 2 seconds.");
Serial.println("Function B activated.");
}, []() {
Serial.println("Please release the button to activate function B.");
// This callback can be used to light up an LED, sound a buzzer, change text on a display, etc.
});
button.setEndingFunction([]() {
Serial.println("You've held the button for over 2 seconds... That's some tough finger!");
});
button.begin(testISR);
}
void loop() {
button.handleInterruptAndFunctions();
}All functions of the InfiniteFunctionButton class are fully documented in the source code.
When using an AVR microcontroller, you can change the IFB_MAX_FUNCTIONS macro inside InfiniteFunctionButtonConfig.h. The default value is 8:
#define IFB_MAX_FUNCTIONS 8On other architectures, this has no effect and the library will attempt to use the vector class from C++'s Standard Template Library. That way the number of defined functions can be truly infinite... Until you run out of RAM!
To tune the debounce time for your setup, you can define IFB_DEBOUNCE_TUNE inside InfiniteFunctionButtonConfig.h:
#define IFB_DEBOUNCE_TUNEThis will cause the handler function to print "1" to the Serial when it thinks that the button has been pressed, and "0" when released. You can use this to increase the time until you no longer see more than one of those on the Serial output when pressing or releasing the button.