Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of OneButton by
OneButton.cpp@3:48a593e2d4cf, 2016-09-22 (annotated)
- Committer:
- JojoS
- Date:
- Thu Sep 22 21:46:37 2016 +0000
- Revision:
- 3:48a593e2d4cf
- Parent:
- 2:26960fb1d783
reverted to original state machine behaviour by mh. This works better for detecting click / double click events.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| jaup | 1:fdf67f893a5c | 1 | // Modifyed to support mbed environment, rewrite the state machine. |
| jaup | 1:fdf67f893a5c | 2 | // by Zibin Zheng <znbin@qq.com> |
| jaup | 1:fdf67f893a5c | 3 | |
| jaup | 0:62d614796022 | 4 | // ----- |
| jaup | 0:62d614796022 | 5 | // OneButton.cpp - Library for detecting button clicks, doubleclicks and long press pattern on a single button. |
| jaup | 0:62d614796022 | 6 | // This class is implemented for use with the Arduino environment. |
| jaup | 0:62d614796022 | 7 | // Copyright (c) by Matthias Hertel, http://www.mathertel.de |
| jaup | 0:62d614796022 | 8 | // This work is licensed under a BSD style license. See http://www.mathertel.de/License.aspx |
| jaup | 0:62d614796022 | 9 | // More information on: http://www.mathertel.de/Arduino |
| jaup | 0:62d614796022 | 10 | // ----- |
| jaup | 1:fdf67f893a5c | 11 | |
| jaup | 0:62d614796022 | 12 | |
| jaup | 0:62d614796022 | 13 | #include "OneButton.h" |
| jaup | 0:62d614796022 | 14 | |
| jaup | 1:fdf67f893a5c | 15 | |
| jaup | 0:62d614796022 | 16 | // ----- Initialization and Default Values ----- |
| jaup | 0:62d614796022 | 17 | |
| jaup | 1:fdf67f893a5c | 18 | OneButton::OneButton(PinName pin, bool active_level) |
| jaup | 0:62d614796022 | 19 | { |
| JojoS | 2:26960fb1d783 | 20 | btn_pin = new DigitalIn((PinName)pin); // sets the MenuPin as input |
| jaup | 1:fdf67f893a5c | 21 | |
| JojoS | 2:26960fb1d783 | 22 | timer = new Timer; |
| JojoS | 2:26960fb1d783 | 23 | timer->start(); |
| jaup | 0:62d614796022 | 24 | |
| JojoS | 2:26960fb1d783 | 25 | _clickTicks = 400; // number of millisec that have to pass by before a click is detected. |
| JojoS | 2:26960fb1d783 | 26 | _pressTicks = 800; // number of millisec that have to pass by before a long button press is detected. |
| JojoS | 2:26960fb1d783 | 27 | _debounceTicks = 10; |
| jaup | 0:62d614796022 | 28 | |
| JojoS | 2:26960fb1d783 | 29 | _state = 0; // starting with state 0: waiting for button to be pressed |
| JojoS | 2:26960fb1d783 | 30 | _isLongPressed = false; // Keep track of long press state |
| jaup | 0:62d614796022 | 31 | |
| JojoS | 2:26960fb1d783 | 32 | button_level = (bool)(btn_pin->read()); |
| JojoS | 2:26960fb1d783 | 33 | active = active_level; |
| jaup | 1:fdf67f893a5c | 34 | |
| JojoS | 2:26960fb1d783 | 35 | if (active_level) { |
| JojoS | 2:26960fb1d783 | 36 | // button connects VCC to the pin when pressed. |
| JojoS | 2:26960fb1d783 | 37 | btn_pin->mode(PullDown); |
| JojoS | 2:26960fb1d783 | 38 | |
| JojoS | 2:26960fb1d783 | 39 | } else { |
| JojoS | 2:26960fb1d783 | 40 | // turn on pullUp resistor |
| JojoS | 2:26960fb1d783 | 41 | btn_pin->mode(PullUp); |
| JojoS | 2:26960fb1d783 | 42 | } |
| jaup | 0:62d614796022 | 43 | |
| JojoS | 2:26960fb1d783 | 44 | #if (MBED_LIBRARY_VERSION < 122) |
| JojoS | 2:26960fb1d783 | 45 | clickFn = NULL; |
| JojoS | 2:26960fb1d783 | 46 | pressFn = NULL; |
| JojoS | 2:26960fb1d783 | 47 | doubleClickFn = NULL; |
| JojoS | 2:26960fb1d783 | 48 | longPressStartFn = NULL; |
| JojoS | 2:26960fb1d783 | 49 | longPressStopFn = NULL; |
| JojoS | 2:26960fb1d783 | 50 | duringLongPressFn = NULL; |
| JojoS | 2:26960fb1d783 | 51 | #endif |
| jaup | 0:62d614796022 | 52 | } // OneButton |
| jaup | 0:62d614796022 | 53 | |
| jaup | 0:62d614796022 | 54 | |
| jaup | 0:62d614796022 | 55 | // explicitly set the number of millisec that have to pass by before a click is detected. |
| jaup | 0:62d614796022 | 56 | void OneButton::setClickTicks(int ticks) |
| jaup | 0:62d614796022 | 57 | { |
| JojoS | 2:26960fb1d783 | 58 | _clickTicks = ticks; |
| jaup | 0:62d614796022 | 59 | } // setClickTicks |
| jaup | 0:62d614796022 | 60 | |
| jaup | 0:62d614796022 | 61 | |
| jaup | 0:62d614796022 | 62 | // explicitly set the number of millisec that have to pass by before a long button press is detected. |
| jaup | 0:62d614796022 | 63 | void OneButton::setPressTicks(int ticks) |
| jaup | 0:62d614796022 | 64 | { |
| JojoS | 2:26960fb1d783 | 65 | _pressTicks = ticks; |
| jaup | 0:62d614796022 | 66 | } // setPressTicks |
| jaup | 0:62d614796022 | 67 | |
| jaup | 0:62d614796022 | 68 | |
| JojoS | 2:26960fb1d783 | 69 | #if (MBED_LIBRARY_VERSION < 122) |
| jaup | 0:62d614796022 | 70 | // save function for click event |
| jaup | 0:62d614796022 | 71 | void OneButton::attachClick(callbackFunction newFunction) |
| jaup | 0:62d614796022 | 72 | { |
| JojoS | 2:26960fb1d783 | 73 | clickFn = newFunction; |
| jaup | 0:62d614796022 | 74 | } // attachClick |
| jaup | 0:62d614796022 | 75 | |
| jaup | 0:62d614796022 | 76 | |
| jaup | 0:62d614796022 | 77 | // save function for doubleClick event |
| jaup | 0:62d614796022 | 78 | void OneButton::attachDoubleClick(callbackFunction newFunction) |
| jaup | 0:62d614796022 | 79 | { |
| JojoS | 2:26960fb1d783 | 80 | doubleClickFn = newFunction; |
| jaup | 0:62d614796022 | 81 | } // attachDoubleClick |
| jaup | 0:62d614796022 | 82 | |
| jaup | 0:62d614796022 | 83 | |
| jaup | 0:62d614796022 | 84 | // save function for press event |
| jaup | 0:62d614796022 | 85 | // DEPRECATED, is replaced by attachLongPressStart, attachLongPressStop, attachDuringLongPress, |
| jaup | 0:62d614796022 | 86 | void OneButton::attachPress(callbackFunction newFunction) |
| jaup | 0:62d614796022 | 87 | { |
| JojoS | 2:26960fb1d783 | 88 | pressFn = newFunction; |
| jaup | 0:62d614796022 | 89 | } // attachPress |
| jaup | 0:62d614796022 | 90 | |
| jaup | 0:62d614796022 | 91 | // save function for longPressStart event |
| jaup | 0:62d614796022 | 92 | void OneButton::attachLongPressStart(callbackFunction newFunction) |
| jaup | 0:62d614796022 | 93 | { |
| JojoS | 2:26960fb1d783 | 94 | longPressStartFn = newFunction; |
| jaup | 0:62d614796022 | 95 | } // attachLongPressStart |
| jaup | 0:62d614796022 | 96 | |
| jaup | 0:62d614796022 | 97 | // save function for longPressStop event |
| jaup | 0:62d614796022 | 98 | void OneButton::attachLongPressStop(callbackFunction newFunction) |
| jaup | 0:62d614796022 | 99 | { |
| JojoS | 2:26960fb1d783 | 100 | longPressStopFn = newFunction; |
| jaup | 0:62d614796022 | 101 | } // attachLongPressStop |
| jaup | 0:62d614796022 | 102 | |
| jaup | 0:62d614796022 | 103 | // save function for during longPress event |
| jaup | 0:62d614796022 | 104 | void OneButton::attachDuringLongPress(callbackFunction newFunction) |
| jaup | 0:62d614796022 | 105 | { |
| JojoS | 2:26960fb1d783 | 106 | duringLongPressFn = newFunction; |
| jaup | 0:62d614796022 | 107 | } // attachDuringLongPress |
| JojoS | 2:26960fb1d783 | 108 | #endif |
| jaup | 0:62d614796022 | 109 | |
| jaup | 0:62d614796022 | 110 | // function to get the current long pressed state |
| jaup | 0:62d614796022 | 111 | bool OneButton::isLongPressed() |
| jaup | 0:62d614796022 | 112 | { |
| JojoS | 2:26960fb1d783 | 113 | return _isLongPressed; |
| jaup | 0:62d614796022 | 114 | } |
| jaup | 0:62d614796022 | 115 | |
| jaup | 1:fdf67f893a5c | 116 | /** |
| jaup | 1:fdf67f893a5c | 117 | * @brief Button driver core function, driver state machine. |
| jaup | 1:fdf67f893a5c | 118 | * @param handle: the button handle strcut. |
| jaup | 1:fdf67f893a5c | 119 | * @retval None |
| jaup | 1:fdf67f893a5c | 120 | */ |
| jaup | 0:62d614796022 | 121 | void OneButton::tick(void) |
| jaup | 0:62d614796022 | 122 | { |
| JojoS | 2:26960fb1d783 | 123 | int read_gpio_level = btn_pin->read(); // current button signal. |
| jaup | 0:62d614796022 | 124 | |
| JojoS | 2:26960fb1d783 | 125 | /*------------button debounce handle---------------*/ |
| JojoS | 2:26960fb1d783 | 126 | if(ticks != timer->read_ms()) { //1ms scan again. |
| JojoS | 2:26960fb1d783 | 127 | if(read_gpio_level != button_level) { |
| JojoS | 2:26960fb1d783 | 128 | //continue read 'debounce_cnt' times same new level change |
| JojoS | 2:26960fb1d783 | 129 | if(++_debounce_cnt >= _debounceTicks) { |
| JojoS | 2:26960fb1d783 | 130 | button_level = read_gpio_level; |
| JojoS | 2:26960fb1d783 | 131 | _debounce_cnt = 0; |
| JojoS | 2:26960fb1d783 | 132 | } |
| jaup | 0:62d614796022 | 133 | |
| JojoS | 2:26960fb1d783 | 134 | } else { //leved not change ,counter reset. |
| JojoS | 2:26960fb1d783 | 135 | _debounce_cnt = 0; |
| JojoS | 2:26960fb1d783 | 136 | } |
| JojoS | 2:26960fb1d783 | 137 | } |
| jaup | 0:62d614796022 | 138 | |
| JojoS | 2:26960fb1d783 | 139 | //current (relative) time in msecs. |
| JojoS | 2:26960fb1d783 | 140 | ticks = timer->read_ms(); |
| jaup | 0:62d614796022 | 141 | |
| JojoS | 2:26960fb1d783 | 142 | /*-----------------State machine-------------------*/ |
| JojoS | 2:26960fb1d783 | 143 | switch (_state) { |
| JojoS | 2:26960fb1d783 | 144 | case 0: |
| JojoS | 2:26960fb1d783 | 145 | if(button_level == active) { //start press |
| JojoS | 2:26960fb1d783 | 146 | timer->reset(); |
| JojoS | 2:26960fb1d783 | 147 | _state = 1; |
| JojoS | 2:26960fb1d783 | 148 | } |
| JojoS | 2:26960fb1d783 | 149 | break; |
| jaup | 0:62d614796022 | 150 | |
| JojoS | 2:26960fb1d783 | 151 | case 1: |
| JojoS | 2:26960fb1d783 | 152 | if(button_level != active) { //released |
| JojoS | 2:26960fb1d783 | 153 | _state = 2; |
| jaup | 0:62d614796022 | 154 | |
| JojoS | 2:26960fb1d783 | 155 | } else if(ticks > _pressTicks) { |
| JojoS | 3:48a593e2d4cf | 156 | if(pressFn) pressFn(); //press event |
| JojoS | 2:26960fb1d783 | 157 | if(longPressStartFn) longPressStartFn(); |
| JojoS | 2:26960fb1d783 | 158 | _isLongPressed = 1; |
| JojoS | 2:26960fb1d783 | 159 | _state = 5; |
| JojoS | 2:26960fb1d783 | 160 | } |
| JojoS | 2:26960fb1d783 | 161 | break; |
| jaup | 0:62d614796022 | 162 | |
| JojoS | 2:26960fb1d783 | 163 | case 2: |
| JojoS | 2:26960fb1d783 | 164 | if(ticks > _clickTicks) { //released |
| JojoS | 3:48a593e2d4cf | 165 | if (clickFn) clickFn(); |
| JojoS | 2:26960fb1d783 | 166 | _state = 0; //reset |
| jaup | 0:62d614796022 | 167 | |
| JojoS | 2:26960fb1d783 | 168 | } else if(button_level == active) { //press again |
| JojoS | 2:26960fb1d783 | 169 | _state = 3; |
| JojoS | 2:26960fb1d783 | 170 | } |
| JojoS | 2:26960fb1d783 | 171 | break; |
| jaup | 0:62d614796022 | 172 | |
| JojoS | 2:26960fb1d783 | 173 | case 3: //repeat press pressing |
| JojoS | 2:26960fb1d783 | 174 | if(button_level != active) { //double releasd |
| JojoS | 2:26960fb1d783 | 175 | //double click event |
| JojoS | 2:26960fb1d783 | 176 | if(doubleClickFn) doubleClickFn(); |
| JojoS | 2:26960fb1d783 | 177 | _state = 0; |
| JojoS | 2:26960fb1d783 | 178 | } |
| JojoS | 2:26960fb1d783 | 179 | break; |
| jaup | 0:62d614796022 | 180 | |
| JojoS | 2:26960fb1d783 | 181 | case 5: |
| JojoS | 2:26960fb1d783 | 182 | if(button_level == active) { |
| JojoS | 2:26960fb1d783 | 183 | //continue hold trigger |
| JojoS | 2:26960fb1d783 | 184 | if(duringLongPressFn) duringLongPressFn(); |
| jaup | 1:fdf67f893a5c | 185 | |
| JojoS | 2:26960fb1d783 | 186 | } else { //releasd |
| JojoS | 2:26960fb1d783 | 187 | if(longPressStopFn) longPressStopFn(); |
| JojoS | 2:26960fb1d783 | 188 | _isLongPressed = 0; |
| JojoS | 2:26960fb1d783 | 189 | _state = 0; //reset |
| JojoS | 2:26960fb1d783 | 190 | } |
| JojoS | 2:26960fb1d783 | 191 | break; |
| JojoS | 2:26960fb1d783 | 192 | } |
| jaup | 1:fdf67f893a5c | 193 | } |
| jaup | 0:62d614796022 | 194 | |
| jaup | 0:62d614796022 | 195 | // end. |
| jaup | 0:62d614796022 | 196 |
