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
OneButton.cpp
- Committer:
- jaup
- Date:
- 2016-08-31
- Revision:
- 0:62d614796022
- Child:
- 1:fdf67f893a5c
File content as of revision 0:62d614796022:
// ----- // OneButton.cpp - Library for detecting button clicks, doubleclicks and long press pattern on a single button. // This class is implemented for use with the Arduino environment. // Copyright (c) by Matthias Hertel, http://www.mathertel.de // This work is licensed under a BSD style license. See http://www.mathertel.de/License.aspx // More information on: http://www.mathertel.de/Arduino // ----- // Changelog: see OneButton.h // ----- #include "OneButton.h" // ----- Initialization and Default Values ----- OneButton::OneButton(PinName pin, int activeLow) { btn_pin = new DigitalIn((PinName)pin); // sets the MenuPin as input _pin = pin; _clickTicks = 300; // 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. _state = 0; // starting with state 0: waiting for button to be pressed _isLongPressed = false; // Keep track of long press state if (activeLow) { // button connects ground to the pin when pressed. _buttonReleased = HIGH; // notPressed _buttonPressed = LOW; // digitalWrite(pin, HIGH); // turn on pullUp resistor btn_pin->mode(PullUp); } else { // button connects VCC to the pin when pressed. _buttonReleased = LOW; _buttonPressed = HIGH; } // if _doubleClickFunc = NULL; _pressFunc = NULL; _longPressStartFunc = NULL; _longPressStopFunc = NULL; _duringLongPressFunc = NULL; startMillis (); } // OneButton // explicitly set the number of millisec that have to pass by before a click is detected. void OneButton::setClickTicks(int 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; } // setPressTicks // save function for click event void OneButton::attachClick(callbackFunction newFunction) { _clickFunc = newFunction; } // attachClick // save function for doubleClick event void OneButton::attachDoubleClick(callbackFunction newFunction) { _doubleClickFunc = newFunction; } // attachDoubleClick // save function for press event // DEPRECATED, is replaced by attachLongPressStart, attachLongPressStop, attachDuringLongPress, void OneButton::attachPress(callbackFunction newFunction) { _pressFunc = newFunction; } // attachPress // save function for longPressStart event void OneButton::attachLongPressStart(callbackFunction newFunction) { _longPressStartFunc = newFunction; } // attachLongPressStart // save function for longPressStop event void OneButton::attachLongPressStop(callbackFunction newFunction) { _longPressStopFunc = newFunction; } // attachLongPressStop // save function for during longPress event void OneButton::attachDuringLongPress(callbackFunction newFunction) { _duringLongPressFunc = newFunction; } // attachDuringLongPress // function to get the current long pressed state bool OneButton::isLongPressed() { return _isLongPressed; } void OneButton::tick(void) { // Detect the input information // int buttonLevel = digitalRead(_pin); // current button signal. int buttonLevel = btn_pin->read(); // current button signal. unsigned long now = millis(); // current (relative) time in msecs. // Implementation of the state machine if (_state == 0) { // waiting for menu pin being pressed. if (buttonLevel == _buttonPressed) { _state = 1; // step to state 1 _startTime = now; // remember starting time } // if } else if (_state == 1) { // waiting for menu pin being released. if ((buttonLevel == _buttonReleased) && ((unsigned long)(now - _startTime) < _debounceTicks)) { // button was released to quickly so I assume some debouncing. // go back to state 0 without calling a function. _state = 0; } else if (buttonLevel == _buttonReleased) { _state = 2; // step to state 2 } else if ((buttonLevel == _buttonPressed) && ((unsigned long)(now - _startTime) > _pressTicks)) { _isLongPressed = true; // Keep track of long press state if (_pressFunc) _pressFunc(); if (_longPressStartFunc) _longPressStartFunc(); if (_duringLongPressFunc) _duringLongPressFunc(); _state = 6; // step to state 6 } else { // wait. Stay in this state. } // if } else if (_state == 2) { // waiting for menu pin being pressed the second time or timeout. if ((unsigned long)(now - _startTime) > _clickTicks) { // this was only a single short click if (_clickFunc) _clickFunc(); _state = 0; // restart. } else if (buttonLevel == _buttonPressed) { _state = 3; // step to state 3 } // if } else if (_state == 3) { // waiting for menu pin being released finally. if (buttonLevel == _buttonReleased) { // this was a 2 click sequence. if (_doubleClickFunc) _doubleClickFunc(); _state = 0; // restart. } // if } else if (_state == 6) { // waiting for menu pin being release after long press. if (buttonLevel == _buttonReleased) { _isLongPressed = false; // Keep track of long press state if(_longPressStopFunc) _longPressStopFunc(); _state = 0; // restart. } else { // button is being long pressed _isLongPressed = true; // Keep track of long press state if (_duringLongPressFunc) _duringLongPressFunc(); } // if } // if } // OneButton.tick() // end.