Library for detecting button clicks, doubleclicks and long press pattern on a single button. Updated to use Callback class when mbed lib >= 122 is used. Then also member functions can be used as callbacks.
Fork of OneButton by
Diff: OneButton.cpp
- Revision:
- 2:26960fb1d783
- Parent:
- 1:fdf67f893a5c
- Child:
- 3:48a593e2d4cf
--- a/OneButton.cpp Thu Sep 01 09:21:00 2016 +0000 +++ b/OneButton.cpp Thu Sep 22 20:36:52 2016 +0000 @@ -17,64 +17,67 @@ OneButton::OneButton(PinName pin, bool active_level) { - btn_pin = new DigitalIn((PinName)pin); // sets the MenuPin as input + btn_pin = new DigitalIn((PinName)pin); // sets the MenuPin as input - timer = new Timer; - timer->start(); + timer = new Timer; + timer->start(); - _clickTicks = 400; // number of millisec that have to pass by before a click is detected. - _pressTicks = 800; // number of millisec that have to pass by before a long button press is detected. - _debounceTicks = 10; + _clickTicks = 400; // number of millisec that have to pass by before a click is detected. + _pressTicks = 800; // number of millisec that have to pass by before a long button press is detected. + _debounceTicks = 10; - _state = 0; // starting with state 0: waiting for button to be pressed - _isLongPressed = false; // Keep track of long press state + _state = 0; // starting with state 0: waiting for button to be pressed + _isLongPressed = false; // Keep track of long press state - button_level = (bool)(btn_pin->read()); - active = active_level; + button_level = (bool)(btn_pin->read()); + active = active_level; - if (active_level) { - // button connects VCC to the pin when pressed. - btn_pin->mode(PullDown); + if (active_level) { + // button connects VCC to the pin when pressed. + btn_pin->mode(PullDown); + + } else { + // turn on pullUp resistor + btn_pin->mode(PullUp); + } - } else { - // turn on pullUp resistor - btn_pin->mode(PullUp); - } - - _clickFunc = NULL; - _pressFunc = NULL; - _doubleClickFunc = NULL; - _longPressStartFunc = NULL; - _longPressStopFunc = NULL; - _duringLongPressFunc = NULL; +#if (MBED_LIBRARY_VERSION < 122) + clickFn = NULL; + pressFn = NULL; + doubleClickFn = NULL; + longPressStartFn = NULL; + longPressStopFn = NULL; + duringLongPressFn = NULL; +#endif } // OneButton // explicitly set the number of millisec that have to pass by before a click is detected. void OneButton::setClickTicks(int ticks) { - _clickTicks = ticks; + _clickTicks = ticks; } // setClickTicks // explicitly set the number of millisec that have to pass by before a long button press is detected. void OneButton::setPressTicks(int ticks) { - _pressTicks = ticks; + _pressTicks = ticks; } // setPressTicks +#if (MBED_LIBRARY_VERSION < 122) // save function for click event void OneButton::attachClick(callbackFunction newFunction) { - _clickFunc = newFunction; + clickFn = newFunction; } // attachClick // save function for doubleClick event void OneButton::attachDoubleClick(callbackFunction newFunction) { - _doubleClickFunc = newFunction; + doubleClickFn = newFunction; } // attachDoubleClick @@ -82,31 +85,32 @@ // DEPRECATED, is replaced by attachLongPressStart, attachLongPressStop, attachDuringLongPress, void OneButton::attachPress(callbackFunction newFunction) { - _pressFunc = newFunction; + pressFn = newFunction; } // attachPress // save function for longPressStart event void OneButton::attachLongPressStart(callbackFunction newFunction) { - _longPressStartFunc = newFunction; + longPressStartFn = newFunction; } // attachLongPressStart // save function for longPressStop event void OneButton::attachLongPressStop(callbackFunction newFunction) { - _longPressStopFunc = newFunction; + longPressStopFn = newFunction; } // attachLongPressStop // save function for during longPress event void OneButton::attachDuringLongPress(callbackFunction newFunction) { - _duringLongPressFunc = newFunction; + duringLongPressFn = newFunction; } // attachDuringLongPress +#endif // function to get the current long pressed state bool OneButton::isLongPressed() { - return _isLongPressed; + return _isLongPressed; } /** @@ -116,78 +120,78 @@ */ void OneButton::tick(void) { - int read_gpio_level = btn_pin->read(); // current button signal. + int read_gpio_level = btn_pin->read(); // current button signal. - /*------------button debounce handle---------------*/ - if(ticks != timer->read_ms()) { //1ms scan again. - if(read_gpio_level != button_level) { - //continue read 'debounce_cnt' times same new level change - if(++_debounce_cnt >= _debounceTicks) { - button_level = read_gpio_level; - _debounce_cnt = 0; - } + /*------------button debounce handle---------------*/ + if(ticks != timer->read_ms()) { //1ms scan again. + if(read_gpio_level != button_level) { + //continue read 'debounce_cnt' times same new level change + if(++_debounce_cnt >= _debounceTicks) { + button_level = read_gpio_level; + _debounce_cnt = 0; + } - } else { //leved not change ,counter reset. - _debounce_cnt = 0; - } - } + } else { //leved not change ,counter reset. + _debounce_cnt = 0; + } + } - //current (relative) time in msecs. - ticks = (uint16_t)(timer->read_ms()); + //current (relative) time in msecs. + ticks = timer->read_ms(); - /*-----------------State machine-------------------*/ - switch (_state) { - case 0: - if(button_level == active) { //start press - if(_clickFunc) _clickFunc(); - timer->reset(); - _state = 1; - } - break; + /*-----------------State machine-------------------*/ + switch (_state) { + case 0: + if(button_level == active) { //start press + if(clickFn) clickFn(); + timer->reset(); + _state = 1; + } + break; - case 1: - if(button_level != active) { //released - _state = 2; + case 1: + if(button_level != active) { //released + _state = 2; - } else if(ticks > _pressTicks) { - if(_longPressStartFunc) _longPressStartFunc(); - _isLongPressed = 1; - _state = 5; - } - break; + } else if(ticks > _pressTicks) { + if(longPressStartFn) longPressStartFn(); + _isLongPressed = 1; + _state = 5; + } + break; - case 2: - if(ticks > _clickTicks) { //released - //press event - if(_pressFunc) _pressFunc(); //press event - _state = 0; //reset + case 2: + if(ticks > _clickTicks) { //released + //press event + if(pressFn) pressFn(); //press event + _state = 0; //reset - } else if(button_level == active) { //press again - if(_clickFunc) _clickFunc(); - _state = 3; - } - break; + } else if(button_level == active) { //press again + if(clickFn) clickFn(); + _state = 3; + } + break; - case 3: //repeat press pressing - if(button_level != active) { //double releasd - //double click event - if(_doubleClickFunc) _doubleClickFunc(); - _state = 0; - } - break; + case 3: //repeat press pressing + if(button_level != active) { //double releasd + //double click event + if(doubleClickFn) doubleClickFn(); + _state = 0; + } + break; - case 5: - if(button_level == active) { - //continue hold trigger - if(_duringLongPressFunc) _duringLongPressFunc(); + case 5: + if(button_level == active) { + //continue hold trigger + if(duringLongPressFn) duringLongPressFn(); - } else { //releasd - if(_longPressStopFunc) _longPressStopFunc(); - _isLongPressed = 0; - _state = 0; //reset - } - break; - } + } else { //releasd + if(longPressStopFn) longPressStopFn(); + _isLongPressed = 0; + _state = 0; //reset + } + break; + } } // end.