Skip to content

Commit

Permalink
Merge pull request #135 from mathertel/V2.5.0
Browse files Browse the repository at this point in the history
This release is a minor update including som smaller fixes.

Functions marked with deprecated will be removed in version 3.x
Formatting of source code conformint the standard Arduino IDE 2.0 formatting using .clang-format
Version for platform.io in sync with version for Arduino
Introducing the OneButtonTiny class for small environments with limited program space and memory.
  • Loading branch information
mathertel authored Dec 2, 2023
2 parents 0ed3b51 + a93a729 commit 27da5fd
Show file tree
Hide file tree
Showing 9 changed files with 499 additions and 34 deletions.
5 changes: 1 addition & 4 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
BreakStringLiterals: false
# v12 has various problems with this set to 0 (no limit)
# possible workaround is to set this to 4294967295 aka some large number
# see https://reviews.llvm.org/D96896
ColumnLimit: 0
# "" matches none
CommentPragmas: ""
Expand Down Expand Up @@ -117,7 +114,7 @@ PenaltyReturnTypeOnItsOwnLine: 1
# Used as a fallback if alignment style can't be detected from code (DerivePointerAlignment: true)
PointerAlignment: Right
RawStringFormats: []
ReflowComments: true
ReflowComments: false
SortIncludes: false
SortUsingDeclarations: false
SpaceAfterCStyleCast: false
Expand Down
23 changes: 23 additions & 0 deletions .markdownlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"default": true,
"no-hard-tabs": true,
"no-trailing-spaces": true,
"blank_lines": true,
"no-multiple-blanks": {
"maximum": 2
},
"ul-indent": {
"indent": 2
},
"ul-style": {
"style": "asterisk"
},
"line-length": false,
"no-inline-html": false,
"code-block-style": {
"style": "fenced"
},
"no-duplicate-header": {
"allow_different_nesting": true
}
}
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

All notable changes to this project will be documented in this file starting 2021.

## [2.5.0] - 2023-12-02

This release is a minor update including som smaller fixes.

* Functions marked with deprecated will be removed in version 3.x
* Formatting of source code conformint the standard Arduino IDE 2.0 formatting using .clang-format
* Version for platform.io in sync with version for Arduino
* Introducing the `OneButtonTiny` class for small environments with limited program space and memory.


## [2.1.0] - 2023-05-10

This release is a minor update as there is new internal functionality and
Expand Down
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ You can find more details on this library at

The change log of this library can be found in [CHANGELOG](CHANGELOG.md).


## Getting Started

Clone this repository into `Arduino/Libraries` or use the built-in Arduino IDE Library manager to install
Expand All @@ -25,6 +26,30 @@ a copy of this library. You can find more detail about installing libraries

Each physical button requires its own `OneButton` instance. You can initialize them like this:


### OneButton Tiny version

The OneButton Library was extended over time with functionality that was requested for specific
use cases. This makes the library growing over time too and therefore was limiting use cases using very small processors like attiny84.

Staring with version 2.5 the OneButton Library starts supporting these processors with limited
memory and low cpu frequencies by introducing the `OneButtonTiny` class that offers a subset of
the features of the complete `OneButton` class by exposing the following events as callbacks:

* Click event
* DoubleClick event
* LongPressStart event
* Callbacks without parameters

This saves up to 1k of binary program space that is a huge amount on these processors.

With Version 2.5 the `OneButtonTiny` class is now in a beta state.

* Any Issues or pull requests fixing problems are welcome.
* Any new feature request for the `OneButtonTiny` class will be rejected to keep size small.
* New, reasonable functionality will be added to the OneButton class only.


### Initialize a Button to GND

```CPP
Expand All @@ -43,6 +68,7 @@ OneButton btn = OneButton(
);
```


### Initialize a Button to VCC

```CPP
Expand All @@ -62,6 +88,7 @@ OneButton btn = OneButton(
);
```


### Attach State Events

Once you have your button initialized, you can handle events by attaching them to the button
Expand Down Expand Up @@ -103,6 +130,7 @@ void loop() {
}
```


### Usage with lambdas that capture context

You __can't pass__ a lambda-__with-context__ to an argument which expects a __function pointer__. To work that around,
Expand All @@ -115,6 +143,7 @@ okBtn.attachClick([](void *ctx){Serial.println(*((BtnHandler*)ctx) -> state);},
See also discussion in [Issue #112](https://github.com/mathertel/OneButton/issues/112).
## State Events
Here's a full list of events handled by this library:
Expand All @@ -128,6 +157,7 @@ Here's a full list of events handled by this library:
| `attachDuringLongPress` | Fires periodically as long as the button is held down. |
| `attachLongPressStop` | Fires when the button is released after a long hold. |
### Event Timing
Valid events occur when `tick()` is called after a specified number of milliseconds. You can use
Expand All @@ -151,6 +181,7 @@ The former functions `setDebounceTicks`, `setClickTicks` and `setPressTicks` are
The term `Ticks` in these functions where confusing. Replace them with the ...Ms function calls.
There is no functional change on them.
### Additional Functions
`OneButton` also provides a couple additional functions to use for querying button status:
Expand All @@ -163,11 +194,13 @@ There is no functional change on them.
| `int state()` | Get the OneButton state |
| `int debouncedValue()` | Get the OneButton debounced value |
### `tick()` and `reset()`
You can specify a logic level when calling `tick(bool)`, which will skip reading the pin and use
that level instead. If you wish to reset the internal state of your buttons, call `reset()`.
## Troubleshooting
If your buttons aren't acting they way they should, check these items:
Expand Down
65 changes: 37 additions & 28 deletions examples/BlinkMachine/BlinkMachine.ino
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
-------- ------ |
| OFF |<--click-+->| ON | |
-------- | ------ |
| | |
| d-click |
| | |
^ | | |
| | d-click |
longpress | | |
| V |
| ------ |
+- | SLOW | |
Expand All @@ -47,24 +47,24 @@
// 06.10.2012 created by Matthias Hertel
// 26.03.2017 state diagram added, minor changes

#include "OneButton.h"
// #include "OneButton.h"
#include "OneButtonTiny.h" // This example also works with reduced OneButtonTiny class saving.

// The actions I ca do...
typedef enum {
ACTION_OFF, // set LED "OFF".
ACTION_ON, // set LED "ON"
ACTION_SLOW, // blink LED "SLOW"
ACTION_FAST // blink LED "FAST"
}
MyActions;
ACTION_OFF, // set LED "OFF".
ACTION_ON, // set LED "ON"
ACTION_SLOW, // blink LED "SLOW"
ACTION_FAST // blink LED "FAST"
} MyActions;

#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO_EVERY) ||defined(ARDUINO_UNOR4_WIFI)
// Example for Arduino UNO with input button on pin 2 and builtin LED on pin 13
#define PIN_INPUT A1
#define PIN_LED 13

#elif defined(ARDUINO_attiny)
// Example for Arduino UNO with input button on pin 2 and builtin LED on pin 13
// Example for Arduino ATTiny85
#define PIN_INPUT PB0
#define PIN_LED PB1

Expand All @@ -83,36 +83,40 @@ MyActions;

#endif

// Setup a new OneButton on pin PIN_INPUT.
OneButton button(PIN_INPUT, true);
// Setup a new OneButton on pin PIN_INPUT.
// OneButton button(PIN_INPUT, true);
OneButtonTiny button(PIN_INPUT, true); // This example also works with reduced OneButtonTiny class saving.

MyActions nextAction = ACTION_OFF; // no action when starting
MyActions nextAction = ACTION_OFF; // no action when starting


// setup code here, to run once.
void setup() {
// enable the standard led on pin 13.
pinMode(PIN_LED, OUTPUT); // sets the digital pin as output
pinMode(PIN_LED, OUTPUT); // sets the digital pin as output

// link the myClickFunction function to be called on a click event.
// link the myClickFunction function to be called on a click event.
button.attachClick(myClickFunction);

// link the doubleclick function to be called on a doubleclick event.
// link the doubleclick function to be called on a doubleclick event.
button.attachDoubleClick(myDoubleClickFunction);

// link the doubleclick function to be called on a doubleclick event.
button.attachLongPressStart(myDoubleClickFunction);

// set 80 msec. debouncing time. Default is 50 msec.
button.setDebounceMs(80);
} // setup
} // setup


// main code here, to run repeatedly:
// main code here, to run repeatedly:
void loop() {
unsigned long now = millis();

// keep watching the push button:
button.tick();

// You can implement other code in here or just wait a while
// You can implement other code in here or just wait a while

if (nextAction == ACTION_OFF) {
// do nothing.
Expand All @@ -128,17 +132,17 @@ void loop() {
digitalWrite(PIN_LED, LOW);
} else {
digitalWrite(PIN_LED, HIGH);
} // if
} // if

} else if (nextAction == ACTION_FAST) {
// do a fast blinking
if (now % 200 < 100) {
digitalWrite(PIN_LED, LOW);
} else {
digitalWrite(PIN_LED, HIGH);
} // if
} // if
} // loop
} // if
} // if
} // loop


// this function will be called when the button was pressed 1 time and them some time has passed.
Expand All @@ -147,7 +151,7 @@ void myClickFunction() {
nextAction = ACTION_ON;
else
nextAction = ACTION_OFF;
} // myClickFunction
} // myClickFunction


// this function will be called when the button was pressed 2 times in a short timeframe.
Expand All @@ -160,8 +164,13 @@ void myDoubleClickFunction() {

} else if (nextAction == ACTION_FAST) {
nextAction = ACTION_ON;
} // if
} // myDoubleClickFunction
} // if
} // myDoubleClickFunction

// End

// this function will be called when a long press was detected.
void myLongPressFunction() {
nextAction = ACTION_OFF;
} // myLongPressFunction

// End
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "OneButton",
"version": "2.1.0",
"version": "2.5.0",
"keywords": "arduino, button, pushbutton",
"description": "This Arduino library is improving the usage of a singe button for input. It shows how to use an digital input pin with a single pushbutton attached for detecting some of the typical button press events like single clicks, double clicks and long-time pressing. This enables you to reuse the same button for multiple functions and lowers the hardware invests.",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=OneButton
version=2.1.0
version=2.5.0
author=Matthias Hertel
maintainer=Matthias Hertel, https://www.mathertel.de
sentence=Arduino library for improving the usage of a singe input button.
Expand Down
Loading

0 comments on commit 27da5fd

Please sign in to comment.