Johannes Stratmann / OneButton

Dependents:   ECH_V004

Fork of OneButton by Zibin Zheng

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers OneButton.cpp Source File

OneButton.cpp

00001 // Modifyed to support mbed environment, rewrite the state machine.
00002 // by Zibin Zheng <znbin@qq.com>
00003 
00004 // -----
00005 // OneButton.cpp - Library for detecting button clicks, doubleclicks and long press pattern on a single button.
00006 // This class is implemented for use with the Arduino environment.
00007 // Copyright (c) by Matthias Hertel, http://www.mathertel.de
00008 // This work is licensed under a BSD style license. See http://www.mathertel.de/License.aspx
00009 // More information on: http://www.mathertel.de/Arduino
00010 // -----
00011 
00012 
00013 #include "OneButton.h"
00014 
00015 
00016 // ----- Initialization and Default Values -----
00017 
00018 OneButton::OneButton(PinName pin, bool active_level)
00019 {
00020     btn_pin = new DigitalIn((PinName)pin);      // sets the MenuPin as input
00021 
00022     timer = new Timer;
00023     timer->start();
00024 
00025     _clickTicks = 400;        // number of millisec that have to pass by before a click is detected.
00026     _pressTicks = 800;       // number of millisec that have to pass by before a long button press is detected.
00027     _debounceTicks = 10;
00028 
00029     _state = 0; // starting with state 0: waiting for button to be pressed
00030     _isLongPressed = false;  // Keep track of long press state
00031 
00032     button_level = (bool)(btn_pin->read());
00033     active = active_level;
00034 
00035     if (active_level) {
00036         // button connects VCC to the pin when pressed.
00037         btn_pin->mode(PullDown);
00038 
00039     } else {
00040         // turn on pullUp resistor
00041         btn_pin->mode(PullUp);
00042     }
00043 
00044 #if (MBED_LIBRARY_VERSION < 122)
00045     clickFn = NULL;
00046     pressFn = NULL;
00047     doubleClickFn = NULL;
00048     longPressStartFn = NULL;
00049     longPressStopFn = NULL;
00050     duringLongPressFn = NULL;
00051 #endif
00052 } // OneButton
00053 
00054 
00055 // explicitly set the number of millisec that have to pass by before a click is detected.
00056 void OneButton::setClickTicks(int ticks)
00057 {
00058     _clickTicks = ticks;
00059 } // setClickTicks
00060 
00061 
00062 // explicitly set the number of millisec that have to pass by before a long button press is detected.
00063 void OneButton::setPressTicks(int ticks)
00064 {
00065     _pressTicks = ticks;
00066 } // setPressTicks
00067 
00068 
00069 #if (MBED_LIBRARY_VERSION < 122)
00070 // save function for click event
00071 void OneButton::attachClick(callbackFunction newFunction)
00072 {
00073     clickFn = newFunction;
00074 } // attachClick
00075 
00076 
00077 // save function for doubleClick event
00078 void OneButton::attachDoubleClick(callbackFunction newFunction)
00079 {
00080     doubleClickFn = newFunction;
00081 } // attachDoubleClick
00082 
00083 
00084 // save function for press event
00085 // DEPRECATED, is replaced by attachLongPressStart, attachLongPressStop, attachDuringLongPress,
00086 void OneButton::attachPress(callbackFunction newFunction)
00087 {
00088     pressFn = newFunction;
00089 } // attachPress
00090 
00091 // save function for longPressStart event
00092 void OneButton::attachLongPressStart(callbackFunction newFunction)
00093 {
00094     longPressStartFn = newFunction;
00095 } // attachLongPressStart
00096 
00097 // save function for longPressStop event
00098 void OneButton::attachLongPressStop(callbackFunction newFunction)
00099 {
00100     longPressStopFn = newFunction;
00101 } // attachLongPressStop
00102 
00103 // save function for during longPress event
00104 void OneButton::attachDuringLongPress(callbackFunction newFunction)
00105 {
00106     duringLongPressFn = newFunction;
00107 } // attachDuringLongPress
00108 #endif
00109 
00110 // function to get the current long pressed state
00111 bool OneButton::isLongPressed()
00112 {
00113     return _isLongPressed;
00114 }
00115 
00116 /**
00117   * @brief  Button driver core function, driver state machine.
00118   * @param  handle: the button handle strcut.
00119   * @retval None
00120   */
00121 void OneButton::tick(void)
00122 {
00123     int read_gpio_level = btn_pin->read(); // current button signal.
00124 
00125     /*------------button debounce handle---------------*/
00126     if(ticks != timer->read_ms()) { //1ms scan again.
00127         if(read_gpio_level != button_level) {
00128             //continue read 'debounce_cnt' times same new level change
00129             if(++_debounce_cnt >= _debounceTicks) {
00130                 button_level = read_gpio_level;
00131                 _debounce_cnt = 0;
00132             }
00133 
00134         } else { //leved not change ,counter reset.
00135             _debounce_cnt = 0;
00136         }
00137     }
00138 
00139     //current (relative) time in msecs.
00140     ticks = timer->read_ms();
00141 
00142     /*-----------------State machine-------------------*/
00143     switch (_state) {
00144         case 0:
00145             if(button_level == active) {    //start press
00146                 timer->reset();
00147                 _state = 1;
00148             }
00149             break;
00150 
00151         case 1:
00152             if(button_level != active) { //released
00153                 _state = 2;
00154 
00155             } else if(ticks > _pressTicks) {
00156                 if(pressFn) pressFn();  //press event
00157                 if(longPressStartFn) longPressStartFn();
00158                 _isLongPressed = 1;
00159                 _state = 5;
00160             }
00161             break;
00162 
00163         case 2:
00164             if(ticks > _clickTicks) {   //released
00165                 if (clickFn) clickFn();
00166                 _state = 0; //reset
00167 
00168             } else if(button_level == active) { //press again
00169                 _state = 3;
00170             }
00171             break;
00172 
00173         case 3: //repeat press pressing
00174             if(button_level != active) {    //double releasd
00175                 //double click event
00176                 if(doubleClickFn) doubleClickFn();
00177                 _state = 0;
00178             }
00179             break;
00180 
00181         case 5:
00182             if(button_level == active) {
00183                 //continue hold trigger
00184                 if(duringLongPressFn) duringLongPressFn();
00185 
00186             } else { //releasd
00187                 if(longPressStopFn) longPressStopFn();
00188                 _isLongPressed = 0;
00189                 _state = 0; //reset
00190             }
00191             break;
00192     }
00193 }
00194 
00195 // end.
00196