Skip to content

Commit

Permalink
V3.3.1 - Avoid mistakenly double press detection after boot.
Browse files Browse the repository at this point in the history
  • Loading branch information
ArminJo committed Feb 18, 2022
1 parent ca97908 commit 27eb3ad
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 28 deletions.
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ Available as [Arduino library "EasyButtonAtInt01"](https://www.arduinolibraries.
Debouncing is merely done by ignoring a button change within the debouncing time (default 50 ms).
So **button state is instantly available** without debouncing delay!
- Implements **toggle button** functionality.
- Support for **double press detection** is included. See [EasyButtonExample](examples/EasyButtonExample/EasyButtonExample.ino#L112) and [Callback example](examples/Callback/Callback.ino#L78).
- Support for **long press detection**, is included. See [Callback example](examples/Callback/Callback.ino#L98).
- Support for **double press detection** is included. See [EasyButtonExample](examples/EasyButtonExample/EasyButtonExample.ino#L111) and [Callback example](examples/Callback/Callback.ino#L77).
- Support for **long press detection**, is included. See [Callback example](examples/Callback/Callback.ino#L97).
- Support for **active high buttons**.
- Small memory footprint.
- Support to **measure maximum bouncing period of a button**. See [DebounceTest example](examples/DebounceTest/DebounceTest.ino#L64).
- Support to **measure maximum bouncing period of a button**. See [DebounceTest example](examples/DebounceTest/DebounceTest.ino#L62).

## Table of available pins for the 2 buttons
| CPU | Button 0 | Button 1 using INT1 | Button 1 using PCINT, if INT1_PIN is defined !=3 |
Expand Down Expand Up @@ -154,7 +154,7 @@ Modify them by enabling / disabling them, or change the values if applicable.
| `USE_BUTTON_1` | disabled | Enables code for button at INT1 (pin3 on 328P, PA3 on ATtiny167, PCINT0 / PCx for ATtinyX5). |
| `BUTTON_IS_ACTIVE_HIGH` | disabled | Enable this if you buttons are active high. |
| `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. |
| `NO_BUTTON_RELEASE_CALLBACK` | disabled | Disables the code for release callback. This saves 2 bytes RAM and 64 bytes FLASH. |
| `NO_BUTTON_RELEASE_CALLBACK` | disabled | Disables the code for release callback. This saves 2 bytes RAM and 64 bytes program space. |
| `BUTTON_DEBOUNCING_MILLIS` | 50 | With this you can adapt to the characteristic of your button. |
| `ANALYZE_MAX_BOUNCING_PERIOD` | disabled | Analyze the buttons actual debounce value. |
| `BUTTON_LED_FEEDBACK` | disabled | This activates LED_BUILTIN as long as button is pressed. |
Expand Down Expand Up @@ -197,6 +197,9 @@ bool checkForForButtonNotPressedTime(uint16_t aTimeoutMillis);
```

# Revision History
### Version 3.3.1
- Avoid mistakenly double press detection after boot.

### Version 3.3.0
- Renamed EasyButtonAtInt01.cpp.h to EasyButtonAtInt01.hpp.

Expand Down
2 changes: 0 additions & 2 deletions examples/Callback/Callback.ino
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ void blinkLEDBlocking(uint8_t aLedPin, uint8_t aBlinkCount, uint16_t aDelay) {
void handleButtonPress(bool aButtonToggleState) {
/*
* Double press (< 200 ms) detection by calling checkForForDoublePress() once at button press time.
* Be aware, that the first press after booting may be detected as double press!
* 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.
*/
if (Button0AtPin2.checkForDoublePress(300)) {
Serial.print(F("Double press "));
Expand Down
10 changes: 5 additions & 5 deletions examples/EasyButtonExample/ATtinySerialOut.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ void writeUnsignedByte(uint8_t aByte) {
}

/*
* 2 Byte Hex output
* 2 byte Hex output
*/
void writeUnsignedByteHex(uint8_t aByte) {
char tStringBuffer[3];
Expand All @@ -261,7 +261,7 @@ void writeUnsignedByteHex(uint8_t aByte) {
}

/*
* 2 Byte Hex output with 2 Byte prefix "0x"
* 2 byte Hex output with 2 byte prefix "0x"
*/
void writeUnsignedByteHexWithPrefix(uint8_t aByte) {
writeBinary('0');
Expand Down Expand Up @@ -354,7 +354,7 @@ void TinySerialOut::flush() {
}

/*
* 2 Byte Hex output with 2 Byte prefix "0x"
* 2 byte Hex output with 2 byte prefix "0x"
*/
void TinySerialOut::printHex(uint8_t aByte) {
writeUnsignedByteHexWithPrefix(aByte);
Expand Down Expand Up @@ -530,7 +530,7 @@ inline void delay4CyclesExact(uint16_t a4Microseconds) {
* 115200 baud - 8,680 cycles per bit, 86,8 per byte at 1 MHz
*
* Assembler code for 115200 baud extracted from Digispark core files:
* Code size is 196 Byte (including first call)
* Code size is 196 byte (including first call)
*
* TinySerialOut.h - Tiny write-only software serial.
* Copyright 2010 Rowdy Dog Software. This code is part of Arduino-Tiny.
Expand Down Expand Up @@ -680,7 +680,7 @@ void write1Start8Data1StopNoParity(uint8_t aValue) {
}
#else
/*
* Small code using loop. Code size is 76 Byte (including first call)
* Small code using loop. Code size is 76 byte (including first call)
*
* 1 MHz CPU Clock
* 26,04 cycles per bit, 260,4 per byte for 38400 baud at 1 MHz Clock
Expand Down
4 changes: 1 addition & 3 deletions examples/EasyButtonExample/EasyButtonExample.ino
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,7 @@ void loop() {

void handleButtonPress(bool aButtonToggleState) {
/*
* This function works reliable only if called early in press callback function
* Be aware, that the first press after booting may be detected as double press!
* 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.
* checkForDoublePress() works reliable only if called early in press callback function
*/
if (Button0AtPin2.checkForDoublePress()) {
Serial.println(F("Button 0 double press (< 400 ms) detected"));
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"type": "git",
"url": "https://github.com/ArminJo/EasyButtonAtInt01"
},
"version": "3.3.0",
"version": "3.3.1",
"exclude": "pictures",
"authors": {
"name": "Armin Joachimsmeyer",
Expand Down
4 changes: 2 additions & 2 deletions library.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name=EasyButtonAtInt01
version=3.3.0
version=3.3.1
author=Armin Joachimsmeyer
maintainer=Armin Joachimsmeyer <armin.arduino@gmail.com>
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/>
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/>
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/>
category=Signal Input/Output
url=https://github.com/ArminJo/EasyButtonAtInt01
architectures=avr
Expand Down
10 changes: 5 additions & 5 deletions src/EasyButtonAtInt01.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* #include "EasyButtonAtInt01.h"
* EasyButton Button0AtPin2(true);
*
* Copyright (C) 2018 Armin Joachimsmeyer
* Copyright (C) 2018-2022 Armin Joachimsmeyer
* armin.joachimsmeyer@gmail.com
*
* This file is part of EasyButtonAtInt01 https://github.com/ArminJo/EasyButtonAtInt01.
Expand All @@ -34,7 +34,7 @@
#ifndef EASY_BUTTON_AT_INT01_H_
#define EASY_BUTTON_AT_INT01_H_

#define VERSION_EASY_BUTTON "3.2.0"
#define VERSION_EASY_BUTTON "3.2.1"
#define VERSION_EASY_BUTTON_MAJOR 3
#define VERSION_EASY_BUTTON_MINOR 2
// The change log is at the bottom of the file
Expand Down Expand Up @@ -62,7 +62,7 @@
/*
* Define USE_ATTACH_INTERRUPT to force 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.
* For one button it needs additional 160 bytes FLASH, for 2 buttons it needs additional 88 bytes.
* For one button it needs additional 160 bytes program space, for 2 buttons it needs additional 88 bytes.
*/
//#define USE_ATTACH_INTERRUPT
//
Expand All @@ -84,7 +84,7 @@
#endif

/*
* Activate this to save 2 bytes RAM and 64 bytes FLASH
* Activate this to save 2 bytes RAM and 64 bytes program space
*/
//#define NO_BUTTON_RELEASE_CALLBACK
//
Expand Down Expand Up @@ -128,7 +128,7 @@
#endif

/*
* These defines are here to enable saving of 150 bytes FLASH if only one button is needed
* These defines are here to enable saving of 150 bytes program space if only one button is needed
*/
//#define USE_BUTTON_0
//#define USE_BUTTON_1
Expand Down
18 changes: 12 additions & 6 deletions src/EasyButtonAtInt01.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* #include "EasyButtonAtInt01.hpp"
* EasyButton Button0AtPin2(true);
*
* Copyright (C) 2018 Armin Joachimsmeyer
* Copyright (C) 2018-2022 Armin Joachimsmeyer
* armin.joachimsmeyer@gmail.com
*
* This file is part of EasyButtonAtInt01 https://github.com/ArminJo/EasyButtonAtInt01.
Expand All @@ -42,7 +42,7 @@
* - USE_BUTTON_1 Enables code for button at INT1 (pin3 on 328P, PA3 on ATtiny167, PCINT0 / PCx for ATtinyX5).
* - BUTTON_IS_ACTIVE_HIGH Enable this if you buttons are active high.
* - USE_ATTACH_INTERRUPT This forces use of the arduino function attachInterrupt(). It is required if you get the error "multiple definition of __vector_1".
* - NO_BUTTON_RELEASE_CALLBACK Disables the code for release callback. This saves 2 bytes RAM and 64 bytes FLASH.
* - NO_BUTTON_RELEASE_CALLBACK Disables the code for release callback. This saves 2 bytes RAM and 64 bytes program space.
* - BUTTON_DEBOUNCING_MILLIS With this you can adapt to the characteristic of your button.
* - ANALYZE_MAX_BOUNCING_PERIOD Analyze the buttons actual debounce value.
* - BUTTON_LED_FEEDBACK This activates LED_BUILTIN as long as button is pressed.
Expand Down Expand Up @@ -458,13 +458,19 @@ bool EasyButton::checkForLongPressBlocking(uint16_t aLongPressThresholdMillis) {
* Double press detection by computing difference between current (active) timestamp ButtonLastChangeMillis
* and last release timestamp ButtonReleaseMillis.
* !!!Works only reliable if called early in ButtonPress callback function!!!
* Be aware, that the first press after booting may be detected as double press!
* This is because ButtonReleaseMillis is initialized with 0 milliseconds, which is interpreted as the first press happened at the beginning of boot.
* @return true if double press detected.
*/
bool EasyButton::checkForDoublePress(uint16_t aDoublePressDelayMillis) {
unsigned long tReleaseToPressTimeMillis = ButtonLastChangeMillis - ButtonReleaseMillis;
return (tReleaseToPressTimeMillis <= aDoublePressDelayMillis);
/*
* Check if ButtonReleaseMillis is not in initialized state
* otherwise a single press before aDoublePressDelayMillis after boot is mistakenly detected as double press
*/
if (ButtonReleaseMillis != 0) {
// because ButtonReleaseMillis is initialized with 0 milliseconds, which is interpreted as the first press happened at the beginning of boot.
unsigned long tReleaseToPressTimeMillis = ButtonLastChangeMillis - ButtonReleaseMillis;
return (tReleaseToPressTimeMillis <= aDoublePressDelayMillis);
}
return false;
}

/*
Expand Down

0 comments on commit 27eb3ad

Please sign in to comment.