Improved button debouncing
This commit is contained in:
parent
44b729f0e6
commit
29954007e8
8
Makefile
8
Makefile
|
@ -275,7 +275,7 @@ DEFS = -DHAVE_CONFIG_H
|
|||
DEPDIR = .deps
|
||||
DEPS_CFLAGS = -DDBUS_API_SUBJECT_TO_CHANGE -I/usr/include/dbus-c++-1 -I/usr/include/dbus-1.0 -I/usr/lib/arm-linux-gnueabihf/dbus-1.0/include
|
||||
DEPS_LIBS = -ldbus-c++-1 -ldbus-1
|
||||
DHMAKE = notfound
|
||||
DHMAKE = /usr/bin/dh_make
|
||||
ECHO_C =
|
||||
ECHO_N = -n
|
||||
ECHO_T =
|
||||
|
@ -295,10 +295,10 @@ OBJEXT = o
|
|||
PACKAGE = mediacore-hid
|
||||
PACKAGE_BUGREPORT = bugs@miqra.nl
|
||||
PACKAGE_NAME = MediaCore HID Server
|
||||
PACKAGE_STRING = MediaCore HID Server 4.0.0
|
||||
PACKAGE_STRING = MediaCore HID Server 4.0.1
|
||||
PACKAGE_TARNAME = mediacore-hid
|
||||
PACKAGE_URL = http://www.miqra.nl/
|
||||
PACKAGE_VERSION = 4.0.0
|
||||
PACKAGE_VERSION = 4.0.1
|
||||
PATH_SEPARATOR = :
|
||||
PKG_CONFIG = /usr/bin/pkg-config
|
||||
PKG_CONFIG_LIBDIR =
|
||||
|
@ -306,7 +306,7 @@ PKG_CONFIG_PATH =
|
|||
SET_MAKE =
|
||||
SHELL = /bin/bash
|
||||
STRIP =
|
||||
VERSION = 4.0.0
|
||||
VERSION = 4.0.1
|
||||
abs_builddir = /home/pi/mediacore-hid
|
||||
abs_srcdir = /home/pi/mediacore-hid
|
||||
abs_top_builddir = /home/pi/mediacore-hid
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#define PACKAGE_NAME "MediaCore HID Server"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "MediaCore HID Server 4.0.0"
|
||||
#define PACKAGE_STRING "MediaCore HID Server 4.0.1"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "mediacore-hid"
|
||||
|
@ -20,4 +20,4 @@
|
|||
#define PACKAGE_URL "http://www.miqra.nl/"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "4.0.0"
|
||||
#define PACKAGE_VERSION "4.0.1"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
AC_INIT([MediaCore HID Server], [4.0.0], [bugs@miqra.nl], [mediacore-hid], [http://www.miqra.nl/])
|
||||
AC_INIT([MediaCore HID Server], [4.0.1], [bugs@miqra.nl], [mediacore-hid], [http://www.miqra.nl/])
|
||||
AC_PREREQ([2.59])
|
||||
AM_INIT_AUTOMAKE([1.11 no-define foreign subdir-objects])
|
||||
AC_CONFIG_HEADERS([config.hpp])
|
||||
|
|
|
@ -26,7 +26,14 @@ void ButtonTimer::RegisterPress(const uint8_t keycode)
|
|||
// Prevent trouble when calling this from within one of our event listeners
|
||||
if(eventLock) { MutexUnlock(); return; }
|
||||
|
||||
pressRegistry[keycode] = now_ms();
|
||||
// register current registered time for first triggering press
|
||||
if(!pressRegistry.count(keycode))
|
||||
{
|
||||
pressRegistry[keycode] = now_ms();
|
||||
}
|
||||
|
||||
// register press state to true for debouncing
|
||||
pressState[keycode] = true;
|
||||
MutexUnlock();
|
||||
}
|
||||
|
||||
|
@ -36,18 +43,44 @@ void ButtonTimer::RegisterRelease(const uint8_t keycode)
|
|||
MutexLock();
|
||||
// Prevent trouble when calling this from within one of our event listeners
|
||||
if(eventLock) { MutexUnlock(); return; }
|
||||
|
||||
|
||||
// register current press state to false
|
||||
pressState[keycode] = false;
|
||||
|
||||
if(pressRegistry.count(keycode))
|
||||
{
|
||||
// if it was a long press, the key code would already have been erased, so we
|
||||
// can safely fire the onShortPress event
|
||||
uint64_t now = now_ms();
|
||||
uint64_t then = pressRegistry[keycode];
|
||||
// remove from registry after release, if it was a long press, the event should have already been fired
|
||||
pressRegistry.erase(keycode);
|
||||
|
||||
if(now - then > shortpressMinTime)
|
||||
if(pressHold.count(keycode))
|
||||
{
|
||||
// debounce locks for release
|
||||
// pressHold[keycode] == true means wait for release
|
||||
// pressHold[keycode] == false means we're in the release debounce time
|
||||
if(pressHold[keycode] == true){
|
||||
// first release after longpress
|
||||
// Register time and switch to next mode
|
||||
pressHold[keycode] = false;
|
||||
pressRegistry[keycode] = now;
|
||||
}
|
||||
else
|
||||
{
|
||||
// still in debounce
|
||||
// release the debounce lock if this release occurs after the shortpresstime
|
||||
if(now - then > shortpressMinTime){
|
||||
pressHold.erase(keycode);
|
||||
pressRegistry.erase(keycode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(now - then > shortpressMinTime)
|
||||
{
|
||||
// only trigger this if the release is later than the shortpresstime
|
||||
// remove from registry after release, if it was a long press, the event should have already been fired
|
||||
pressRegistry.erase(keycode);
|
||||
|
||||
eventLock = true; // lock out trouble
|
||||
onShortPress(keycode);
|
||||
eventLock = false; // risk of trouble gone
|
||||
|
@ -74,32 +107,57 @@ void ButtonTimer::CancelPress(const uint8_t keycode)
|
|||
void ButtonTimer::ThreadLoop()
|
||||
{
|
||||
uint64_t now = now_ms();
|
||||
std::list<uint8_t> btnList;
|
||||
std::list<uint8_t> shortPressList;
|
||||
std::list<uint8_t> longPressList;
|
||||
boost::optional<bool> valid;
|
||||
MutexLock();
|
||||
// list through all the items
|
||||
|
||||
for( std::map<uint8_t,uint64_t>::iterator ii=pressRegistry.begin(); ii!=pressRegistry.end(); ++ii)
|
||||
for( auto const& itm : pressRegistry)
|
||||
{
|
||||
if(now - (ii->second) >= longpressTime) // if it is in overtime
|
||||
if(now - (itm.second) >= shortpressMinTime && pressState[itm.first] == false) // if the shortpresstime wa exceeded and the value is false
|
||||
{
|
||||
if(!pressHold.count(itm.first))
|
||||
{
|
||||
shortPressList.push_back(itm.first);
|
||||
}
|
||||
else if(pressHold[itm.first] == false)
|
||||
{
|
||||
// release debounce lock from longpress
|
||||
pressRegistry.erase(itm.first);
|
||||
pressHold.erase(itm.first);
|
||||
}
|
||||
}
|
||||
if(now - (itm.second) >= longpressTime && !pressHold.count(itm.first)) // if it is in overtime and not waiting for release debounce
|
||||
{
|
||||
// Schedule to process the thing
|
||||
btnList.push_back(ii->first);
|
||||
longPressList.push_back(itm.first);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (auto const& gpio : shortPressList)
|
||||
{
|
||||
pressRegistry.erase(gpio);
|
||||
// If any validators are connected, they can retun false to indicate that this connection is not
|
||||
// allowed
|
||||
eventLock = true; // lock out trouble
|
||||
onShortPress(gpio);
|
||||
eventLock = false; // risk of trouble gone
|
||||
}
|
||||
|
||||
// Process listed items
|
||||
for (std::list<uint8_t>::iterator it=btnList.begin(); it != btnList.end(); ++it)
|
||||
for (auto const& gpio : longPressList)
|
||||
{
|
||||
pressRegistry.erase(*it);
|
||||
pressHold[gpio] = true; // debounce wait state
|
||||
// If any validators are connected, they can retun false to indicate that this connection is not
|
||||
// allowed
|
||||
eventLock = true; // lock out trouble
|
||||
|
||||
valid = onValidatePress(*it);
|
||||
valid = onValidatePress(gpio);
|
||||
if(valid.get_value_or(true))
|
||||
{
|
||||
onLongPress(*it);
|
||||
onLongPress(gpio);
|
||||
}
|
||||
eventLock = false; // risk of trouble gone
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ class ButtonTimer : protected Thread
|
|||
uint32_t longpressTime;
|
||||
uint32_t shortpressMinTime;
|
||||
std::map<const uint8_t, uint64_t> pressRegistry;
|
||||
std::map<const uint8_t, bool> pressState;
|
||||
std::map<const uint8_t, bool> pressHold;
|
||||
|
||||
bool eventLock;
|
||||
static int64_t now_ms(void);
|
||||
|
|
|
@ -82,10 +82,10 @@ HidServer::HidServer(DBus::Connection &connection)
|
|||
{
|
||||
|
||||
// Initialize button timer
|
||||
btnTimer = new ButtonTimer(10,5000); // Short press should take at leas 10 ms, and a Long press takes 5 seconds
|
||||
btnTimer = new ButtonTimer(70,5000); // 70 ms debounce time, and a Long press takes 5 seconds
|
||||
onShortPressConnection = this->btnTimer->onShortPress.connect( boost::bind( &HidServer::onShortPress, this, _1) );
|
||||
onLongPressConnection = this->btnTimer->onLongPress.connect( boost::bind( &HidServer::onLongPress, this, _1) );
|
||||
onValidatePressConnection = this->btnTimer->onValidatePress.connect( boost::bind( &HidServer::onValidatePress, this, _1) );
|
||||
//onValidatePressConnection = this->btnTimer->onValidatePress.connect( boost::bind( &HidServer::onValidatePress, this, _1) );
|
||||
|
||||
// **** Initialize the GPIO Interrupt pin
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
PACKAGE="mediacore-hid"
|
||||
VERSION="4.0.0"
|
||||
VERSION="4.0.1"
|
||||
|
|
Loading…
Reference in New Issue
Block a user