DebounceSwitchRK
Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Static Protected Attributes
DebounceSwitch Class Reference

Singleton class for all debounced switches on a device. More...

#include <DebounceSwitchRK.h>

Inheritance diagram for DebounceSwitch:
DebounceConfiguration

Public Member Functions

void setup ()
 You must call DebounceSwitch::getInstance()->setup() from the global setup! More...
 
DebounceSwitchStateaddSwitch (pin_t pin, DebounceSwitchStyle style, std::function< void(DebounceSwitchState *switchState, void *context)> callback, void *context=0, std::function< bool(DebounceSwitchState *switchState, void *pollContext)> pollCallback=0, void *pollContext=0)
 Adds a new switch to debounce. Normally done during setup. More...
 
template<typename T >
DebounceSwitchStateaddSwitch (pin_t pin, DebounceSwitchStyle style, void(T::*callback)(DebounceSwitchState *), T *instance)
 Adds a new switch to debounce with callback in a class member function. More...
 
template<typename T1 , typename T2 >
DebounceSwitchStateaddSwitch (pin_t pin, DebounceSwitchStyle style, void(T1::*callback)(DebounceSwitchState *), T1 *instance, bool(T2::*pollingCallback)(DebounceSwitchState *), T2 *pollingInstance)
 Adds a new switch to debounce with callback in a class member function. More...
 
DebounceSwitchwithCheckMs (unsigned long ms)
 Adjust how often to poll the switches in milliseconds (default: 5) More...
 
unsigned long getCheckMs () const
 Get how often to poll the switches in milliseconds (default: 5)
 
DebounceSwitchwithStackSize (size_t _stackSize)
 Set the stack size for the worker thread (default: 1024 bytes) More...
 
- Public Member Functions inherited from DebounceConfiguration
DebounceConfigurationwithDebounceMs (unsigned long ms)
 Set the debounce press and release time in milliseconds (default: 20) More...
 
DebounceConfigurationwithDebouncePressMs (unsigned long ms)
 Set the debounce press time in milliseconds (default: 20) More...
 
unsigned long getDebouncePressMs () const
 Gets the debounce time in milliseconds (default: 20)
 
DebounceConfigurationwithDebounceReleaseMs (unsigned long ms)
 Set the debounce release time in milliseconds (default: 20) More...
 
unsigned long getDebounceReleaseMs () const
 Gets the debounce time in milliseconds (default: 20)
 
DebounceConfigurationwithInterTapMs (unsigned long ms)
 Set the inter-tap time in milliseconds (default: 500) More...
 
unsigned long getInterTapMs () const
 Gets the inter-tap time in milliseconds (default: 500)
 
DebounceConfigurationwithLongPressMs (unsigned long ms)
 Set the long press duration in milliseconds (default: 3000, 3 seconds) More...
 
DebounceConfigurationwithNoLongPress ()
 Disables support for long and very long press. Only short press is returned.
 
unsigned long getLongPressMs () const
 Get the long press duration in milliseconds (default: 3000, 3 seconds)
 
DebounceConfigurationwithVeryLongPressMs (unsigned long ms)
 Set the very long press duration in milliseconds (default: 10000, 10 seconds) More...
 
DebounceConfigurationwithNoVeryLongPress ()
 Disables support for very long press. More...
 
unsigned long getVeryLongPressMs () const
 Gets the very long press duration in milliseconds (default: 10000, 10 seconds)
 
DebounceConfigurationoperator= (const DebounceConfiguration &src)
 Copy settings from another DebounceConfiguration. More...
 

Static Public Member Functions

static DebounceSwitchgetInstance ()
 This class is a singleton - use getInstance() to get the pointer to the object. More...
 

Static Public Attributes

static const pin_t VIRTUAL_PIN = 8192
 Constant to pass to addSwitch() if you are using something other than built-in GPIO. More...
 
static const pin_t NOTIFY_PIN = 8193
 Constant to pass to addSwitch() if you are using something other than built-in GPIO. More...
 

Protected Member Functions

 DebounceSwitch ()
 Private constructor - use getInstance() instead to get the singleton.
 
virtual ~DebounceSwitch ()
 The singleton object is never destructed one constructed.
 
 DebounceSwitch (const DebounceSwitch &)=delete
 This class is not copyable.
 
DebounceSwitchoperator= (const DebounceSwitch &)=delete
 This class is not copyable.
 
void threadFunction ()
 Internal thread function. Never returns.
 

Static Protected Member Functions

static os_thread_return_t threadFunctionStatic (void *param)
 Internal thread function. Never returns.
 
static bool gpioPoll (DebounceSwitchState *switchState, void *context)
 Function used to poll a hardware GPIO using pinReadFast. More...
 

Protected Attributes

unsigned long checkMs = 5
 How often to check switch state (default: 5) More...
 
Thread * thread = 0
 Thread object for the worker thread. More...
 
std::vector< DebounceSwitchState * > switchStates
 All of the DebounceSwitchState classes, one for each switch. More...
 
size_t stackSize = 1024
 Stack size. Must be set before calling the setup method.
 
unsigned long lastCheck = 0
 millis() value at last check of buttons. Compared with checkMs. More...
 
- Protected Attributes inherited from DebounceConfiguration
unsigned long debouncePressMs = 20
 Debounce period for press in milliseconds (default: 20) More...
 
unsigned long debounceReleaseMs = 20
 Debounce period for release in milliseconds (default: 20) More...
 
unsigned long interTapMs = 500
 How long to wait for double-tap, triple-tap, etc. in milliseconds (default: 500) More...
 
unsigned long longPressMs = 3000
 How long to wait for a long press in milliseconds (default: 3000, or 3 seconds) More...
 
unsigned long veryLongPressMs = 10000
 How long to wait for a very long press in milliseconds (default: 10000, or 10 seconds) More...
 

Static Protected Attributes

static DebounceSwitchinstance = 0
 Singleton object instance. getInstance() allocates it if it has not been allocated, otherwise returns instance.
 

Detailed Description

Singleton class for all debounced switches on a device.

Use DebounceSwitch::getInstance() to get the object instance pointer.

Call DebounceSwitch::getInstance()->setup() during global setup() to initialize the library. This is required!

Call DebounceSwitch::getInstance()->addSwitch() to add switches to debounce. You should add switches during setup().

It uses threads so you do not need to call anything from loop().

Member Function Documentation

◆ addSwitch() [1/3]

DebounceSwitchState * DebounceSwitch::addSwitch ( pin_t  pin,
DebounceSwitchStyle  style,
std::function< void(DebounceSwitchState *switchState, void *context)>  callback,
void *  context = 0,
std::function< bool(DebounceSwitchState *switchState, void *pollContext)>  pollCallback = 0,
void *  pollContext = 0 
)

Adds a new switch to debounce. Normally done during setup.

Parameters
pinThe pin to add a switch to (D2, D3, ...) or a special constant: DebounceSwitch::VIRTUAL_PIN or DebounceSwitch::NOTIFY_PIN.
styleThe type of switch, PRESS for momentary switches or TOGGLE for toggle switches, along with whether they're connected to 3V3 or GND, and whether MCU pull-up or down should be used.
callbackThe function to call when a switch event occurs.
contextOptional data passed to the callback if desired. Pass 0 if not using.
pollCallbackThe function to call to poll the GPIO. Not needed for standard GPIO that can be read using pinReadFast. Optional for NOTIFY_PIN callbacks. Required for VIRTUAL_PIN (not a standard GPIO and using polling, not notify).
pollContextOptional data to pass to pollCallback. Pass 0 if not using.

Note that there are three overloads for the addSwitch method. It's also possible to use it with class member functions instead of the functions and context here. Also, since the functions are defined using a std::function you can also pass a C++11 lambda function to this method. This is shown in the 03-notify example.

The prototype for callback is:

void callback(DebounceSwitchState *switchState, void *context)

The prototype for pollCallback is:

bool pollCallback(DebounceSwitchState *switchState, void *context)

◆ addSwitch() [2/3]

template<typename T1 , typename T2 >
DebounceSwitchState* DebounceSwitch::addSwitch ( pin_t  pin,
DebounceSwitchStyle  style,
void(T1::*)(DebounceSwitchState *)  callback,
T1 *  instance,
bool(T2::*)(DebounceSwitchState *)  pollingCallback,
T2 *  pollingInstance 
)
inline

Adds a new switch to debounce with callback in a class member function.

Parameters
pinThe pin to add a switch to (D2, D3, ...) or a special constant: DebounceSwitch::VIRTUAL_PIN or DebounceSwitch::NOTIFY_PIN.
styleThe type of switch, PRESS for momentary switches or TOGGLE for toggle switches, along with whether they're connected to 3V3 or GND, and whether MCU pull-up or down should be used.
callbackThe class member to call when a switch event occurs.
instanceThe "this" pointer to use for the instance to call the class member function with.
pollingCallbackThe class member to call to poll for the current value.
pollingInstanceThe "this" pointer to use for the instance to call the class member function with. Note that instance and pollingInstance do not need to be for the same class.

You typically call it like this:

DebounceSwitch::getInstance()->addSwitch(pin, DebounceSwitchStyle::PRESS_LOW_PULLUP,
&MyButtonClass::callback, this, &MyButtonClass::pollingCallback, this);

Note the very specific syntax for callback: &MyButtonClass::callback. The callback member function has this prototype:

void YourClass::callback(DebounceSwitchState *switchState);

And, similarly for pollingCallback, which must return a bool:

bool YourClass::pollingCallback(DebounceSwitchState *switchState);

Note that when using a class member function, context is not used; if you want to pass data to the callback, use a class member variable instead of context. Also, while both callbacks are in the same class in example 09-class-member-polling, they don't have to be.

◆ addSwitch() [3/3]

template<typename T >
DebounceSwitchState* DebounceSwitch::addSwitch ( pin_t  pin,
DebounceSwitchStyle  style,
void(T::*)(DebounceSwitchState *)  callback,
T *  instance 
)
inline

Adds a new switch to debounce with callback in a class member function.

Parameters
pinThe pin to add a switch to (D2, D3, ...) or a special constant: DebounceSwitch::VIRTUAL_PIN or DebounceSwitch::NOTIFY_PIN.
styleThe type of switch, PRESS for momentary switches or TOGGLE for toggle switches, along with whether they're connected to 3V3 or GND, and whether MCU pull-up or down should be used.
callbackThe class member to call when a switch event occurs.
instanceThe "this" pointer to use for the instance to call the class member function with.

You typically call it like this:

DebounceSwitch::getInstance()->addSwitch(pin, DebounceSwitchStyle::PRESS_LOW_PULLUP,
&MyButtonClass::callback, this);

Note the very specific syntax for callback: &MyButtonClass::callback. The callback member function has this prototype:

void YourClass::callback(DebounceSwitchState *switchState);

Note that when using a class member function, context is not used; if you want to pass data to the callback, use a class member variable instead of context.

◆ getInstance()

DebounceSwitch * DebounceSwitch::getInstance ( )
static

This class is a singleton - use getInstance() to get the pointer to the object.

You never construct one of these object directly (using a global, stack, or new). You also cannot destruct it once created.

◆ gpioPoll()

bool DebounceSwitch::gpioPoll ( DebounceSwitchState switchState,
void *  context 
)
staticprotected

Function used to poll a hardware GPIO using pinReadFast.

Parameters
switchStateThe pin to poll
contextThe option context that was passed into addSwitch. This may be NULL.

If you addSwitch with a physical GPIO pin (D2, A3, etc.) and do not set a pollingCallback then this function is used to read the GPIO.

◆ setup()

void DebounceSwitch::setup ( )

You must call DebounceSwitch::getInstance()->setup() from the global setup!

This initializes the library. You can call it more than once safely, this is handy if you want to initialize it from a class instance setup.

◆ withCheckMs()

DebounceSwitch& DebounceSwitch::withCheckMs ( unsigned long  ms)
inline

Adjust how often to poll the switches in milliseconds (default: 5)

Parameters
msValue to change to in milliseconds

You probably should not change this, because making it smaller doesn't really improve performance, and making it longer can cause presses to be missed. It cannot be larger than debounceMs.

◆ withStackSize()

DebounceSwitch& DebounceSwitch::withStackSize ( size_t  _stackSize)
inline

Set the stack size for the worker thread (default: 1024 bytes)

You might want to make this bigger if you get stack overflow in your callback, or you may want to reduce the amount of code you execute in your callback.

You must call this before the first call to the setup() method! Changing it later will have no effect.

Field Documentation

◆ checkMs

unsigned long DebounceSwitch::checkMs = 5
protected

How often to check switch state (default: 5)

Switches are checked on a constant cadence as part of the debouncing process. There's a good article about pitfalls of some commonly used debouncing algoriths (here)[https://www.embedded.com/my-favorite-software-debouncers/].

In any case, every checkMs milliseconds the debouncing algorithm runs. This is done even for notify pins, which are still checked on the same cadence.

The default value is 5 milliseconds and this should be appropriate in most cases. It can't be larger than 20 milliseconds, and shouldn't be less than 1, and 5 is about right.

This must be the same for all switches, but the other parameters like the length of debounce are configurable on a per-switch basis.

◆ lastCheck

unsigned long DebounceSwitch::lastCheck = 0
protected

millis() value at last check of buttons. Compared with checkMs.

This works properly across millis() rollover at 49 days.

◆ NOTIFY_PIN

const pin_t DebounceSwitch::NOTIFY_PIN = 8193
static

Constant to pass to addSwitch() if you are using something other than built-in GPIO.

For example, if you are using an MCP23008 I2C GPIO expander and the switch is connected to that and you are using an interrupt line from the MCP23008 to the MCU to notify of GPIO state changes on the expander so you don't need to poll over I2C constantly.

See also VIRTUAL_PIN.

◆ switchStates

std::vector<DebounceSwitchState *> DebounceSwitch::switchStates
protected

All of the DebounceSwitchState classes, one for each switch.

These are instantiated by addSwitch() and added to this vector.

◆ thread

Thread* DebounceSwitch::thread = 0
protected

Thread object for the worker thread.

This is also used to determine if the setup method has already been called

◆ VIRTUAL_PIN

const pin_t DebounceSwitch::VIRTUAL_PIN = 8192
static

Constant to pass to addSwitch() if you are using something other than built-in GPIO.

For example, if you are using an MCP23008 I2C GPIO expander and the switch is connected to that and you are polling for changes.

See also NOTIFY_PIN.


The documentation for this class was generated from the following files:
DebounceSwitch::addSwitch
DebounceSwitchState * addSwitch(pin_t pin, DebounceSwitchStyle style, std::function< void(DebounceSwitchState *switchState, void *context)> callback, void *context=0, std::function< bool(DebounceSwitchState *switchState, void *pollContext)> pollCallback=0, void *pollContext=0)
Adds a new switch to debounce. Normally done during setup.
Definition: DebounceSwitchRK.cpp:63
DebounceSwitch::getInstance
static DebounceSwitch * getInstance()
This class is a singleton - use getInstance() to get the pointer to the object.
Definition: DebounceSwitchRK.cpp:11
DebounceSwitchState
Configuration and state for a single switch.
Definition: DebounceSwitchRK.h:362