Skip to content

Commit f438909

Browse files
authored
Merge branch 'master' into V2.5.0
2 parents 3691fec + eb36148 commit f438909

File tree

6 files changed

+166
-10
lines changed

6 files changed

+166
-10
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ There is no functional change on them.
189189
| Function | Description |
190190
| ----------------------- | ------------------------------------------------------------------------------ |
191191
| `bool isLongPressed()` | Detect whether or not the button is currently inside a long press. |
192-
| `int getPressedTicks()` | Get the current number of milliseconds that the button has been held down for. |
192+
| `int getPressedMs()` | Get the current number of milliseconds that the button has been held down for. |
193193
| `int pin()` | Get the OneButton pin |
194194
| `int state()` | Get the OneButton state |
195195
| `int debouncedValue()` | Get the OneButton debounced value |

examples/BlinkMachine/BlinkMachine.ino

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ typedef enum {
5858
ACTION_FAST // blink LED "FAST"
5959
} MyActions;
6060

61-
#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO_EVERY)
61+
#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO_EVERY) ||defined(ARDUINO_UNOR4_WIFI)
6262
// Example for Arduino UNO with input button on pin 2 and builtin LED on pin 13
6363
#define PIN_INPUT A1
6464
#define PIN_LED 13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
This is a sample sketch to show how to use the OneButtonLibrary
3+
to detect long press events on a button.
4+
The library internals are explained at
5+
http://www.mathertel.de/Arduino/OneButtonLibrary.aspx
6+
7+
Setup a test circuit:
8+
* Connect a pushbutton to PIN_INPUT (ButtonPin) and ground.
9+
10+
The sketch shows how to setup the library and bind the functions (LongPressStart, LongPressStop, DuringLongPress) to the events.
11+
In the loop function the button.tick function must be called as often as you like.
12+
The output of the program is:
13+
14+
OneButton Example.
15+
Please press and hold the button for a few seconds.
16+
810 - LongPressStart()
17+
820 - DuringLongPress()
18+
1820 - DuringLongPress()
19+
2820 - DuringLongPress()
20+
3820 - DuringLongPress()
21+
4820 - DuringLongPress()
22+
5820 - DuringLongPress()
23+
6550 - LongPressStop()
24+
*/
25+
26+
// 05.05.2023 created by Ihor Nehrutsa
27+
28+
#include "OneButton.h"
29+
30+
#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO_EVERY)
31+
// Example for Arduino UNO with input button on pin 2
32+
#define PIN_INPUT 2
33+
34+
#elif defined(ESP8266)
35+
// Example for NodeMCU with input button using FLASH button on D3
36+
#define PIN_INPUT D3
37+
38+
#elif defined(ESP32)
39+
// Example pin assignments for a ESP32 board
40+
// Some boards have a BOOT switch using GPIO 0.
41+
#define PIN_INPUT 0
42+
43+
#endif
44+
45+
// Setup a new OneButton on pin PIN_INPUT
46+
// The 2. parameter activeLOW is true, because external wiring sets the button to LOW when pressed.
47+
OneButton button(PIN_INPUT, true);
48+
49+
// In case the momentary button puts the input to HIGH when pressed:
50+
// The 2. parameter activeLOW is false when the external wiring sets the button to HIGH when pressed.
51+
// The 3. parameter can be used to disable the PullUp .
52+
// OneButton button(PIN_INPUT, false, false);
53+
54+
// setup code here, to run once:
55+
void setup()
56+
{
57+
Serial.begin(115200);
58+
Serial.println("\nOneButton Example.");
59+
Serial.println("Please press and hold the button for a few seconds.");
60+
61+
// link functions to be called on events.
62+
button.attachLongPressStart(LongPressStart, &button);
63+
button.attachDuringLongPress(DuringLongPress, &button);
64+
button.attachLongPressStop(LongPressStop, &button);
65+
66+
button.setLongPressIntervalMs(1000);
67+
} // setup
68+
69+
70+
// main code here, to run repeatedly:
71+
void loop()
72+
{
73+
// keep watching the push button:
74+
button.tick();
75+
76+
// You can implement other code in here or just wait a while
77+
delay(10);
78+
} // loop
79+
80+
81+
// this function will be called when the button started long pressed.
82+
void LongPressStart(void *oneButton)
83+
{
84+
Serial.print(((OneButton *)oneButton)->getPressedMs());
85+
Serial.println("\t - LongPressStart()");
86+
}
87+
88+
// this function will be called when the button is released.
89+
void LongPressStop(void *oneButton)
90+
{
91+
Serial.print(((OneButton *)oneButton)->getPressedMs());
92+
Serial.println("\t - LongPressStop()\n");
93+
}
94+
95+
// this function will be called when the button is held down.
96+
void DuringLongPress(void *oneButton)
97+
{
98+
Serial.print(((OneButton *)oneButton)->getPressedMs());
99+
Serial.println("\t - DuringLongPress()");
100+
}
101+
102+
// End

library.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@
1616
"homepage": "http://www.mathertel.de/Arduino/OneButtonLibrary.aspx",
1717
"frameworks": "arduino",
1818
"platforms": "*"
19-
}
19+
}

src/OneButton.cpp

+27-5
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ void OneButton::setPressMs(const unsigned int ms)
7878
_press_ms = ms;
7979
} // setPressMs
8080

81+
// explicitly set the number of millisec that have to pass by before button idle is detected.
82+
void OneButton::setIdleMs(const unsigned int ms)
83+
{
84+
_idle_ms = ms;
85+
} // setIdleMs
8186

8287
// save function for click event
8388
void OneButton::attachClick(callbackFunction newFunction)
@@ -173,11 +178,19 @@ void OneButton::attachDuringLongPress(parameterizedCallbackFunction newFunction,
173178
} // attachDuringLongPress
174179

175180

181+
// save function for idle button event
182+
void OneButton::attachIdle(callbackFunction newFunction)
183+
{
184+
_idleFunc = newFunction;
185+
} // attachIdle
186+
187+
176188
void OneButton::reset(void)
177189
{
178190
_state = OneButton::OCS_INIT;
179191
_nClicks = 0;
180-
_startTime = 0;
192+
_startTime = millis();
193+
_idleState = false;
181194
}
182195

183196

@@ -242,6 +255,13 @@ void OneButton::_fsm(bool activeLevel)
242255
// Implementation of the state machine
243256
switch (_state) {
244257
case OneButton::OCS_INIT:
258+
// on idle for idle_ms call idle function
259+
if (!_idleState and (waitTime > _idle_ms))
260+
if (_idleFunc) {
261+
_idleState = true;
262+
_idleFunc();
263+
}
264+
245265
// waiting for level to become active.
246266
if (activeLevel) {
247267
_newState(OneButton::OCS_DOWN);
@@ -257,7 +277,7 @@ void OneButton::_fsm(bool activeLevel)
257277
_newState(OneButton::OCS_UP);
258278
_startTime = now; // remember starting time
259279

260-
} else if ((activeLevel) && (waitTime > _press_ms)) {
280+
} else if (waitTime > _press_ms) {
261281
if (_longPressStartFunc) _longPressStartFunc();
262282
if (_paramLongPressStartFunc) _paramLongPressStartFunc(_longPressStartFuncParam);
263283
_newState(OneButton::OCS_PRESS);
@@ -308,12 +328,14 @@ void OneButton::_fsm(bool activeLevel)
308328

309329
if (!activeLevel) {
310330
_newState(OneButton::OCS_PRESSEND);
311-
_startTime = now;
312331

313332
} else {
314333
// still the button is pressed
315-
if (_duringLongPressFunc) _duringLongPressFunc();
316-
if (_paramDuringLongPressFunc) _paramDuringLongPressFunc(_duringLongPressFuncParam);
334+
if ((now - _lastDuringLongPressTime) >= _long_press_interval_ms) {
335+
if (_duringLongPressFunc) _duringLongPressFunc();
336+
if (_paramDuringLongPressFunc) _paramDuringLongPressFunc(_duringLongPressFuncParam);
337+
_lastDuringLongPressTime = now;
338+
}
317339
} // if
318340
break;
319341

src/OneButton.h

+34-2
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,17 @@ class OneButton
7272
void setPressTicks(const unsigned int ms) { setPressMs(ms); }; // deprecated
7373
void setPressMs(const unsigned int ms);
7474

75+
/**
76+
* set interval in msecs between calls of the DuringLongPress event.
77+
* 0 ms is the fastest events calls.
78+
*/
79+
void setLongPressIntervalMs(const unsigned int ms) { _long_press_interval_ms = ms; };
80+
81+
/**
82+
* set # millisec after idle is assumed.
83+
*/
84+
void setIdleMs(const unsigned int ms);
85+
7586
// ----- Attach events functions -----
7687

7788
/**
@@ -111,11 +122,18 @@ class OneButton
111122

112123
/**
113124
* Attach an event to fire periodically while the button is held down.
125+
* The period of calls is set by setLongPressIntervalMs(ms).
114126
* @param newFunction
115127
*/
116128
void attachDuringLongPress(callbackFunction newFunction);
117129
void attachDuringLongPress(parameterizedCallbackFunction newFunction, void *parameter);
118130

131+
/**
132+
* Attach an event when the button is in idle position.
133+
* @param newFunction
134+
*/
135+
void attachIdle(callbackFunction newFunction);
136+
119137
// ----- State machine functions -----
120138

121139
/**
@@ -130,7 +148,7 @@ class OneButton
130148
* level is given by the parameter.
131149
* Run the finite state machine (FSM) using the given level.
132150
*/
133-
void tick(bool level);
151+
void tick(bool activeLevel);
134152

135153

136154
/**
@@ -162,6 +180,7 @@ class OneButton
162180
unsigned int _debounce_ms = 50; // number of msecs for debounce times.
163181
unsigned int _click_ms = 400; // number of msecs before a click is detected.
164182
unsigned int _press_ms = 800; // number of msecs before a long button press is detected
183+
unsigned int _idle_ms = 1000; // number of msecs before idle is detected
165184

166185
int _buttonPressed = 0; // this is the level of the input pin when the button is pressed.
167186
// LOW if the button connects the input pin to GND when pressed.
@@ -192,6 +211,8 @@ class OneButton
192211
parameterizedCallbackFunction _paramDuringLongPressFunc = NULL;
193212
void *_duringLongPressFuncParam = NULL;
194213

214+
callbackFunction _idleFunc = NULL;
215+
195216
// These variables that hold information across the upcoming tick calls.
196217
// They are initialized once on program start and are updated every time the
197218
// tick function is called.
@@ -218,20 +239,31 @@ class OneButton
218239

219240
stateMachine_t _state = OCS_INIT;
220241

242+
bool _idleState = false;
243+
221244
int debouncedPinLevel = -1;
222245
int _lastDebouncePinLevel = -1; // used for pin debouncing
223246
unsigned long _lastDebounceTime = 0; // millis()
224247
unsigned long now = 0; // millis()
225248

226-
unsigned long _startTime = 0; // start of current input change to checking debouncing
249+
unsigned long _startTime = 0; // start time of current activeLevel change
227250
int _nClicks = 0; // count the number of clicks with this variable
228251
int _maxClicks = 1; // max number (1, 2, multi=3) of clicks of interest by registration of event functions.
229252

253+
unsigned int _long_press_interval_ms = 0; // interval in msecs between calls of the DuringLongPress event
254+
unsigned long _lastDuringLongPressTime = 0; // used to produce the DuringLongPress interval
255+
230256
public:
231257
int pin() const { return _pin; };
232258
stateMachine_t state() const { return _state; };
233259
int debounce(const int value);
234260
int debouncedValue() const { return debouncedPinLevel; };
261+
262+
/**
263+
* @brief Use this function in the DuringLongPress and LongPressStop events to get the time since the button was pressed.
264+
* @return milliseconds from the start of the button press.
265+
*/
266+
unsigned long getPressedMs() { return(millis() - _startTime); };
235267
};
236268

237269
#endif

0 commit comments

Comments
 (0)