Skip to content

Commit 27eb3ad

Browse files
committed
V3.3.1 - Avoid mistakenly double press detection after boot.
1 parent ca97908 commit 27eb3ad

8 files changed

Lines changed: 33 additions & 28 deletions

File tree

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ Available as [Arduino library "EasyButtonAtInt01"](https://www.arduinolibraries.
1717
Debouncing is merely done by ignoring a button change within the debouncing time (default 50 ms).
1818
So **button state is instantly available** without debouncing delay!
1919
- Implements **toggle button** functionality.
20-
- Support for **double press detection** is included. See [EasyButtonExample](examples/EasyButtonExample/EasyButtonExample.ino#L112) and [Callback example](examples/Callback/Callback.ino#L78).
21-
- Support for **long press detection**, is included. See [Callback example](examples/Callback/Callback.ino#L98).
20+
- Support for **double press detection** is included. See [EasyButtonExample](examples/EasyButtonExample/EasyButtonExample.ino#L111) and [Callback example](examples/Callback/Callback.ino#L77).
21+
- Support for **long press detection**, is included. See [Callback example](examples/Callback/Callback.ino#L97).
2222
- Support for **active high buttons**.
2323
- Small memory footprint.
24-
- Support to **measure maximum bouncing period of a button**. See [DebounceTest example](examples/DebounceTest/DebounceTest.ino#L64).
24+
- Support to **measure maximum bouncing period of a button**. See [DebounceTest example](examples/DebounceTest/DebounceTest.ino#L62).
2525

2626
## Table of available pins for the 2 buttons
2727
| CPU | Button 0 | Button 1 using INT1 | Button 1 using PCINT, if INT1_PIN is defined !=3 |
@@ -154,7 +154,7 @@ Modify them by enabling / disabling them, or change the values if applicable.
154154
| `USE_BUTTON_1` | disabled | Enables code for button at INT1 (pin3 on 328P, PA3 on ATtiny167, PCINT0 / PCx for ATtinyX5). |
155155
| `BUTTON_IS_ACTIVE_HIGH` | disabled | Enable this if you buttons are active high. |
156156
| `USE_ATTACH_INTERRUPT` | disabled | This forces use of the arduino function attachInterrupt(). It is required if you get the error "multiple definition of \`__vector_1'" (or \`__vector_2'), because another library uses the attachInterrupt() function. |
157-
| `NO_BUTTON_RELEASE_CALLBACK` | disabled | Disables the code for release callback. This saves 2 bytes RAM and 64 bytes FLASH. |
157+
| `NO_BUTTON_RELEASE_CALLBACK` | disabled | Disables the code for release callback. This saves 2 bytes RAM and 64 bytes program space. |
158158
| `BUTTON_DEBOUNCING_MILLIS` | 50 | With this you can adapt to the characteristic of your button. |
159159
| `ANALYZE_MAX_BOUNCING_PERIOD` | disabled | Analyze the buttons actual debounce value. |
160160
| `BUTTON_LED_FEEDBACK` | disabled | This activates LED_BUILTIN as long as button is pressed. |
@@ -197,6 +197,9 @@ bool checkForForButtonNotPressedTime(uint16_t aTimeoutMillis);
197197
```
198198

199199
# Revision History
200+
### Version 3.3.1
201+
- Avoid mistakenly double press detection after boot.
202+
200203
### Version 3.3.0
201204
- Renamed EasyButtonAtInt01.cpp.h to EasyButtonAtInt01.hpp.
202205

examples/Callback/Callback.ino

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,6 @@ void blinkLEDBlocking(uint8_t aLedPin, uint8_t aBlinkCount, uint16_t aDelay) {
7676
void handleButtonPress(bool aButtonToggleState) {
7777
/*
7878
* Double press (< 200 ms) detection by calling checkForForDoublePress() once at button press time.
79-
* Be aware, that the first press after booting may be detected as double press!
80-
* This is because the "last time of press" is initialized with 0 milliseconds, which is interpreted as the first press happened at the beginning of boot.
8179
*/
8280
if (Button0AtPin2.checkForDoublePress(300)) {
8381
Serial.print(F("Double press "));

examples/EasyButtonExample/ATtinySerialOut.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ void writeUnsignedByte(uint8_t aByte) {
243243
}
244244

245245
/*
246-
* 2 Byte Hex output
246+
* 2 byte Hex output
247247
*/
248248
void writeUnsignedByteHex(uint8_t aByte) {
249249
char tStringBuffer[3];
@@ -261,7 +261,7 @@ void writeUnsignedByteHex(uint8_t aByte) {
261261
}
262262

263263
/*
264-
* 2 Byte Hex output with 2 Byte prefix "0x"
264+
* 2 byte Hex output with 2 byte prefix "0x"
265265
*/
266266
void writeUnsignedByteHexWithPrefix(uint8_t aByte) {
267267
writeBinary('0');
@@ -354,7 +354,7 @@ void TinySerialOut::flush() {
354354
}
355355

356356
/*
357-
* 2 Byte Hex output with 2 Byte prefix "0x"
357+
* 2 byte Hex output with 2 byte prefix "0x"
358358
*/
359359
void TinySerialOut::printHex(uint8_t aByte) {
360360
writeUnsignedByteHexWithPrefix(aByte);
@@ -530,7 +530,7 @@ inline void delay4CyclesExact(uint16_t a4Microseconds) {
530530
* 115200 baud - 8,680 cycles per bit, 86,8 per byte at 1 MHz
531531
*
532532
* Assembler code for 115200 baud extracted from Digispark core files:
533-
* Code size is 196 Byte (including first call)
533+
* Code size is 196 byte (including first call)
534534
*
535535
* TinySerialOut.h - Tiny write-only software serial.
536536
* Copyright 2010 Rowdy Dog Software. This code is part of Arduino-Tiny.
@@ -680,7 +680,7 @@ void write1Start8Data1StopNoParity(uint8_t aValue) {
680680
}
681681
#else
682682
/*
683-
* Small code using loop. Code size is 76 Byte (including first call)
683+
* Small code using loop. Code size is 76 byte (including first call)
684684
*
685685
* 1 MHz CPU Clock
686686
* 26,04 cycles per bit, 260,4 per byte for 38400 baud at 1 MHz Clock

examples/EasyButtonExample/EasyButtonExample.ino

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,7 @@ void loop() {
109109

110110
void handleButtonPress(bool aButtonToggleState) {
111111
/*
112-
* This function works reliable only if called early in press callback function
113-
* Be aware, that the first press after booting may be detected as double press!
114-
* This is because the "last time of press" is initialized with 0 milliseconds, which is interpreted as the first press happened at the beginning of boot.
112+
* checkForDoublePress() works reliable only if called early in press callback function
115113
*/
116114
if (Button0AtPin2.checkForDoublePress()) {
117115
Serial.println(F("Button 0 double press (< 400 ms) detected"));

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"type": "git",
77
"url": "https://github.com/ArminJo/EasyButtonAtInt01"
88
},
9-
"version": "3.3.0",
9+
"version": "3.3.1",
1010
"exclude": "pictures",
1111
"authors": {
1212
"name": "Armin Joachimsmeyer",

library.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
name=EasyButtonAtInt01
2-
version=3.3.0
2+
version=3.3.1
33
author=Armin Joachimsmeyer
44
maintainer=Armin Joachimsmeyer <armin.arduino@gmail.com>
55
sentence=Small and easy to use Arduino library for using push buttons at INT0/pin2 and / or any PinChangeInterrupt pin.<br/>Functions for long and double press detection are included.<br/><br/>Just connect buttons between ground and any pin of your Arduino - that's it<br/><br/><b>No call</b> of begin() or polling function like update() required. No blocking debouncing delay.<br/>
6-
paragraph=<br/>Define an EasyButtonIn in you main program and use <i>ButtonStateIsActive</i> or <i>ButtonToggleState</i> to determine your action.<br/>Or use a <b>callback function</b> which will be called once on every button press or release.<br/><br/>Usage:<pre>#define USE_BUTTON_0<br/>#include "EasyButtonAtInt01.hpp"<br/>EasyButton Button0AtPin2;<br/><br/>void setup() {}<br/>void loop() {<br/>...<br/> digitalWrite(LED_BUILTIN, Button0AtPin2.ButtonToggleState);<br/>...<br/>}</pre><br/><br/><b>New: </b>Renamed EasyButtonAtInt01.cpp.h to EasyButtonAtInt01.hpp. => <b>You must change: #include "EasyButtonAtInt01.cpp.h" to: #include "EasyButtonAtInt01.hpp"</b><br/>
6+
paragraph=<br/>Define an EasyButtonIn in you main program and use <i>ButtonStateIsActive</i> or <i>ButtonToggleState</i> to determine your action.<br/>Or use a <b>callback function</b> which will be called once on every button press or release.<br/><br/>Usage:<pre>#define USE_BUTTON_0<br/>#include "EasyButtonAtInt01.hpp"<br/>EasyButton Button0AtPin2;<br/><br/>void setup() {}<br/>void loop() {<br/>...<br/> digitalWrite(LED_BUILTIN, Button0AtPin2.ButtonToggleState);<br/>...<br/>}</pre><br/><br/><b>New: </b>Avoid mistakenly double press detection after boot.</b><br/>
77
category=Signal Input/Output
88
url=https://github.com/ArminJo/EasyButtonAtInt01
99
architectures=avr

src/EasyButtonAtInt01.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* #include "EasyButtonAtInt01.h"
1313
* EasyButton Button0AtPin2(true);
1414
*
15-
* Copyright (C) 2018 Armin Joachimsmeyer
15+
* Copyright (C) 2018-2022 Armin Joachimsmeyer
1616
* armin.joachimsmeyer@gmail.com
1717
*
1818
* This file is part of EasyButtonAtInt01 https://github.com/ArminJo/EasyButtonAtInt01.
@@ -34,7 +34,7 @@
3434
#ifndef EASY_BUTTON_AT_INT01_H_
3535
#define EASY_BUTTON_AT_INT01_H_
3636

37-
#define VERSION_EASY_BUTTON "3.2.0"
37+
#define VERSION_EASY_BUTTON "3.2.1"
3838
#define VERSION_EASY_BUTTON_MAJOR 3
3939
#define VERSION_EASY_BUTTON_MINOR 2
4040
// The change log is at the bottom of the file
@@ -62,7 +62,7 @@
6262
/*
6363
* Define USE_ATTACH_INTERRUPT to force use of the arduino function attachInterrupt().
6464
* It is required if you get the error " multiple definition of `__vector_1'" (or `__vector_2'), because another library uses the attachInterrupt() function.
65-
* For one button it needs additional 160 bytes FLASH, for 2 buttons it needs additional 88 bytes.
65+
* For one button it needs additional 160 bytes program space, for 2 buttons it needs additional 88 bytes.
6666
*/
6767
//#define USE_ATTACH_INTERRUPT
6868
//
@@ -84,7 +84,7 @@
8484
#endif
8585

8686
/*
87-
* Activate this to save 2 bytes RAM and 64 bytes FLASH
87+
* Activate this to save 2 bytes RAM and 64 bytes program space
8888
*/
8989
//#define NO_BUTTON_RELEASE_CALLBACK
9090
//
@@ -128,7 +128,7 @@
128128
#endif
129129

130130
/*
131-
* These defines are here to enable saving of 150 bytes FLASH if only one button is needed
131+
* These defines are here to enable saving of 150 bytes program space if only one button is needed
132132
*/
133133
//#define USE_BUTTON_0
134134
//#define USE_BUTTON_1

src/EasyButtonAtInt01.hpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* #include "EasyButtonAtInt01.hpp"
1616
* EasyButton Button0AtPin2(true);
1717
*
18-
* Copyright (C) 2018 Armin Joachimsmeyer
18+
* Copyright (C) 2018-2022 Armin Joachimsmeyer
1919
* armin.joachimsmeyer@gmail.com
2020
*
2121
* This file is part of EasyButtonAtInt01 https://github.com/ArminJo/EasyButtonAtInt01.
@@ -42,7 +42,7 @@
4242
* - USE_BUTTON_1 Enables code for button at INT1 (pin3 on 328P, PA3 on ATtiny167, PCINT0 / PCx for ATtinyX5).
4343
* - BUTTON_IS_ACTIVE_HIGH Enable this if you buttons are active high.
4444
* - USE_ATTACH_INTERRUPT This forces use of the arduino function attachInterrupt(). It is required if you get the error "multiple definition of __vector_1".
45-
* - NO_BUTTON_RELEASE_CALLBACK Disables the code for release callback. This saves 2 bytes RAM and 64 bytes FLASH.
45+
* - NO_BUTTON_RELEASE_CALLBACK Disables the code for release callback. This saves 2 bytes RAM and 64 bytes program space.
4646
* - BUTTON_DEBOUNCING_MILLIS With this you can adapt to the characteristic of your button.
4747
* - ANALYZE_MAX_BOUNCING_PERIOD Analyze the buttons actual debounce value.
4848
* - BUTTON_LED_FEEDBACK This activates LED_BUILTIN as long as button is pressed.
@@ -458,13 +458,19 @@ bool EasyButton::checkForLongPressBlocking(uint16_t aLongPressThresholdMillis) {
458458
* Double press detection by computing difference between current (active) timestamp ButtonLastChangeMillis
459459
* and last release timestamp ButtonReleaseMillis.
460460
* !!!Works only reliable if called early in ButtonPress callback function!!!
461-
* Be aware, that the first press after booting may be detected as double press!
462-
* This is because ButtonReleaseMillis is initialized with 0 milliseconds, which is interpreted as the first press happened at the beginning of boot.
463461
* @return true if double press detected.
464462
*/
465463
bool EasyButton::checkForDoublePress(uint16_t aDoublePressDelayMillis) {
466-
unsigned long tReleaseToPressTimeMillis = ButtonLastChangeMillis - ButtonReleaseMillis;
467-
return (tReleaseToPressTimeMillis <= aDoublePressDelayMillis);
464+
/*
465+
* Check if ButtonReleaseMillis is not in initialized state
466+
* otherwise a single press before aDoublePressDelayMillis after boot is mistakenly detected as double press
467+
*/
468+
if (ButtonReleaseMillis != 0) {
469+
// because ButtonReleaseMillis is initialized with 0 milliseconds, which is interpreted as the first press happened at the beginning of boot.
470+
unsigned long tReleaseToPressTimeMillis = ButtonLastChangeMillis - ButtonReleaseMillis;
471+
return (tReleaseToPressTimeMillis <= aDoublePressDelayMillis);
472+
}
473+
return false;
468474
}
469475

470476
/*

0 commit comments

Comments
 (0)