初始化提交

This commit is contained in:
王立帮
2024-07-20 22:09:06 +08:00
commit c247dd07a6
6876 changed files with 2743096 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
# MAC .dot folder
.DS_Store
# vs code files
.vscode
*.code-workspace
# arduino_ci unit test binaries and artifacts
*.bin
*.bin.dSYM

View File

@@ -0,0 +1,74 @@
# Changelog
## Unreleased
-
## [1.6.2] - 2021-06-22
- initialized ```pin``` property to 255 instead of -1, as pointed out by [rin67630](https://github.com/rin67630) in issue [#26](https://github.com/LennartHennigs/Button2/issues/26)
## [1.6.1] - 2021-03-22
- updated [README.md](https://github.com/LennartHennigs/Button2/blob/master/README.md)
- added ```const``` to getter functions
## [1.6.0] - 2021-02-10
- added getter/setter functions for debounce, longclick and doubleclick timeouts
- removed debounce timeout parameter from ```contructor``` and ```begin()```
## [1.5.4] - 2021-02-08
- Added ```getAttachPin()``` function, as suggested by [madivad](https://github.com/madivad) in issue [#23](https://github.com/LennartHennigs/Button2/issues/23)
## [1.5.3] - 2021-01-26
- Fixed a bug in the constructor, as suggested by [alex-s-v](https://github.com/alex-s-v) in pull request [#22](https://github.com/LennartHennigs/Button2/pull/22)
## [1.5.2] - 2021-01-26
- Fixed a bug in the ```isPressed()``` function, as suggested by [zenturacp](https://github.com/zenturacp) in [#21](https://github.com/LennartHennigs/Button2/issues/21)
## [1.5.1] - 2021-01-04
- Fixed a bug in the ```loop()``` function
## [1.5.0] - 2021-01-03
- Added default constructor and ```begin()``` function
- Added pull request by [skelstar](https://github.com/skelstar) to add the ```setLongClickDetectedHandler()``` function which is triggered as soon as the longclick timeout has passed
## [1.4.1] - 2020-12-19
- Moved activeLow outside of isCapacitive condition (as suggested by [Wai Lin](https://github.com/w4ilun) in [#18](https://github.com/LennartHennigs/Button2/pull/18)
## [1.4.0] - 2020-11-06
- Updated LongpressHandler example - changed variable name to from ```buttonA``` to ```button```
- toggled ```pressed``` and ```released``` (as suggesed by [TommyC81](https://github.com/TommyC81) in [#16](https://github.com/LennartHennigs/Button2/issues/16))
- added debug function ```isPressedRaw()``` (as suggesed by [TommyC81](https://github.com/TommyC81) in [#16](https://github.com/LennartHennigs/Button2/issues/16))
- fixed bug with ```click_count``` (as suggesed by [TommyC81](https://github.com/TommyC81) in [#16](https://github.com/LennartHennigs/Button2/issues/16))
- changed return types of ```getNumberOfClicks()``` and ```getClickType()``` to ```byte```
## [1.3.0] - 2020-11-06
- Added capacitive touch sensor capabilties (for ESP32) (as suggested by [qubolino](https://github.com/qubolino) in [#11](https://github.com/LennartHennigs/Button2/issues/11))
- Removed deprecated entry in the library.properties file (as suggested by [SangLe](https://github.com/SNL5943)) in [#15](https://github.com/LennartHennigs/Button2/issues/15)
- Added ```const``` modifier to functions (as suggested by [Anton-V-K](https://github.com/Anton-V-K) in [#13](https://github.com/LennartHennigs/Button2/issues/13))
## [1.2.0] - 2020-04-16
- Added possibility to define your own timeouts for clicks (as suggested by [cmeldas](https://github.com/cmeldas) in [#10](https://github.com/LennartHennigs/Button2/issues/10))
- Removed ```yield()``` in main ```loop()``` since it caused some problems
- Created and added CHANGELOG.md
## [1.1.0] - 2020-03-27
- Changed the private functions to protected (as suggested by [Nagymadar](https://github.com/Nagymadar) in [#9](https://github.com/LennartHennigs/Button2/issues/9))
- Added support for active high buttons (as suggested by [Nagymadar](https://github.com/Nagymadar) in [#8](https://github.com/LennartHennigs/Button2/issues/8))
- Added ```reset()``` function to unset all functions (as suggested by [Nagymadar](https://github.com/Nagymadar) in [#7](https://github.com/LennartHennigs/Button2/issues/7))
- Added a ```yield()``` command to the main ```loop()```
- Changed the times for double and triple click
- Fixed error in ```SingleButton.ino``` (as suggested by [alexthe-red](https://github.com/alexthe-red) in [#3](https://github.com/LennartHennigs/Button2/issues/3))
- Added the library to the Arduino IDE
## [1.0.0] - 2017-11-09
- initial release
## Note
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017-2021 Lennart Hennigs
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,137 @@
Button2
======
Arduino/ESP library to simplify working with buttons.
* Author: Lennart Hennigs (https://www.lennarthennigs.de)
* Copyright (C) 2017-2021 Lennart Hennigs.
* Released under the MIT license.
Description
-----------
This library allows you to use callback functions to track single, double, triple and long clicks. It takes care of debouncing. Using this lib will reduce and simplify your source code significantly.
It has been tested with Arduino, ESP8266 and ESP32 devices.
How To Use
----------
This library allows you to define a button and uses callback functions to detect different types of button interactions.
__Definition__
- Define the button either using the ```constructor``` or the ```begin()``` function.
- Per default the button pins are defined as ```INPUT_PULLUP```. You can override this upon creation.
- On an ESP32 you can use it with the built-in capacitive button pins.
__Callback Handler__
- You can define callback functions to track various types of clicks:
- ```setTapHandler()``` will be be called when any click occurs.
- ```setLongClickHandler()``` will be called after the button has released.
- ```setLongClickDetectedHandler()``` will be called as soon as the long click timeout has passed.
- ```setDoubleClickHandler()``` and ```setTripleClickHandler()``` detect complex interactions.
- ```setChangedHandler()```, ```setPressedHandler()``` and ```setReleasedHandler()``` allow to detect basic interactions.
- The callback function needs a ```Button2``` reference parameter. There the reference to the triggered button is stored. This can used to call status fuctions, e.g. ```wasPressedFor()```.
- Please take a look at the included examples to get an overview over the different callback handlers.
__Timeouts__
- You can define your own timeouts by using these setter functions:
- ```void setDebounceTime(unsigned int ms);```
- ```void setLongClickTime(unsigned int ms);```
- ```void setDoubleClickTime(unsigned int ms);```
__The Loop__
- For the class to work, you need to call the button's `loop()` member function in your sketch's `loop()` function.
- Please see the examples for more details.
Notes
-----
- To see the latest changes to the library please take a look at the [Changelog](https://github.com/LennartHennigs/Button2/blob/master/CHANGELOG.md).
- And if you find this library helpful, please consider giving it a star at [GitHub](https://github.com/LennartHennigs/Button2). Thanks!
Class Definition
----------------
These are the constructors and the member functions the library provides:
```
Button2();
Button2(byte attachTo, byte buttonMode = INPUT_PULLUP, boolean isCapacitive = false, boolean activeLow = true);
void begin(byte attachTo, byte buttonMode = INPUT_PULLUP, boolean isCapacitive = false , boolean activeLow = true);
void setDebounceTime(unsigned int ms);
void setLongClickTime(unsigned int ms);
void setDoubleClickTime(unsigned int ms);
unsigned int getDebounceTime();
unsigned int getLongClickTime();
unsigned int getDoubleClickTime();
byte getAttachPin();
void setLongClickDetectedRetriggerable(bool retriggerable);
void reset();
void setChangedHandler(CallbackFunction f);
void setPressedHandler(CallbackFunction f);
void setReleasedHandler(CallbackFunction f);
void setTapHandler(CallbackFunction f);
void setClickHandler(CallbackFunction f);
void setDoubleClickHandler(CallbackFunction f);
void setTripleClickHandler(CallbackFunction f);
void setLongClickHandler(CallbackFunction f);
void setLongClickDetectedHandler(CallbackFunction f);
unsigned int wasPressedFor() const;
boolean isPressed() const;
boolean isPressedRaw() const;
byte getNumberOfClicks() const;
byte getClickType() const;
bool operator==(Button2 &rhs);
void loop();
```
Installation
------------
Open the Arduino IDE choose "Sketch > Include Library" and search for "Button2".
Or download the ZIP archive (https://github.com/lennarthennigs/Button2/zipball/master), and choose "Sketch > Include Library > Add .ZIP Library..." and select the downloaded file.
License
-------
MIT License
Copyright (c) 2017-2021 Lennart Hennigs
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,50 @@
/////////////////////////////////////////////////////////////////
#include "Button2.h"
/////////////////////////////////////////////////////////////////
#define BUTTON_PIN 2
/////////////////////////////////////////////////////////////////
Button2 button = Button2(BUTTON_PIN);
/////////////////////////////////////////////////////////////////
void setup() {
Serial.begin(9600);
while (!Serial) {
delay(20);
}
Serial.println("\n\nLongpress Handler Demo");
button.setLongClickHandler(longpress);
}
/////////////////////////////////////////////////////////////////
void loop() {
button.loop();
}
/////////////////////////////////////////////////////////////////
void longpress(Button2& btn) {
unsigned int time = btn.wasPressedFor();
Serial.print("You clicked ");
if (time > 1500) {
Serial.print("a really really long time.");
} else if (time > 1000) {
Serial.print("a really long time.");
} else if (time > 500) {
Serial.print("a long time.");
} else {
Serial.print("long.");
}
Serial.print(" (");
Serial.print(time);
Serial.println(" ms)");
}
/////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,53 @@
/////////////////////////////////////////////////////////////////
#include "Button2.h"
/////////////////////////////////////////////////////////////////
#define BUTTON_PIN 2
/////////////////////////////////////////////////////////////////
Button2 button = Button2(BUTTON_PIN);
/////////////////////////////////////////////////////////////////
void setup() {
Serial.begin(9600);
delay(50);
Serial.println("\n\nMulti Handler Demo");
button.setClickHandler(handler);
button.setLongClickHandler(handler);
button.setDoubleClickHandler(handler);
button.setTripleClickHandler(handler);
}
/////////////////////////////////////////////////////////////////
void loop() {
button.loop();
}
/////////////////////////////////////////////////////////////////
void handler(Button2& btn) {
switch (btn.getClickType()) {
case SINGLE_CLICK:
break;
case DOUBLE_CLICK:
Serial.print("double ");
break;
case TRIPLE_CLICK:
Serial.print("triple ");
break;
case LONG_CLICK:
Serial.print("long");
break;
}
Serial.print("click");
Serial.print(" (");
Serial.print(btn.getNumberOfClicks());
Serial.println(")");
}
/////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,43 @@
/////////////////////////////////////////////////////////////////
#include "Button2.h"
/////////////////////////////////////////////////////////////////
#define BUTTON_A_PIN 2
#define BUTTON_B_PIN 0
/////////////////////////////////////////////////////////////////
Button2 buttonA = Button2(BUTTON_A_PIN);
Button2 buttonB = Button2(BUTTON_B_PIN);
/////////////////////////////////////////////////////////////////
void setup() {
Serial.begin(9600);
delay(50);
Serial.println("\n\nMultiple Buttons Demo");
buttonA.setClickHandler(click);
buttonB.setClickHandler(click);
}
/////////////////////////////////////////////////////////////////
void loop() {
buttonA.loop();
buttonB.loop();
}
/////////////////////////////////////////////////////////////////
void click(Button2& btn) {
if (btn == buttonA) {
Serial.println("A clicked");
} else if (btn == buttonB) {
Serial.println("B clicked");
}
}
/////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,77 @@
/////////////////////////////////////////////////////////////////
#include "Button2.h"
/////////////////////////////////////////////////////////////////
#define BUTTON_PIN 36
/////////////////////////////////////////////////////////////////
Button2 button = Button2(BUTTON_PIN);
/////////////////////////////////////////////////////////////////
void setup() {
Serial.begin(9600);
delay(50);
Serial.println("\n\nButton Demo");
// button.setLongClickTime(1000);
// button.setDoubleClickTime(400);
Serial.println(" Longpress Time: " + String(button.getLongClickTime()) + "ms");
Serial.println(" DoubleClick Time: " + String(button.getDoubleClickTime()) + "ms");
// button.setChangedHandler(changed);
// button.setPressedHandler(pressed);
button.setReleasedHandler(released);
// button.setTapHandler(tap);
button.setClickHandler(click);
button.setLongClickDetectedHandler(longClickDetected);
button.setLongClickHandler(longClick);
button.setDoubleClickHandler(doubleClick);
button.setTripleClickHandler(tripleClick);
}
/////////////////////////////////////////////////////////////////
void loop() {
button.loop();
}
/////////////////////////////////////////////////////////////////
void pressed(Button2& btn) {
Serial.println("pressed");
}
void released(Button2& btn) {
Serial.print("released: ");
Serial.println(btn.wasPressedFor());
}
void changed(Button2& btn) {
Serial.println("changed");
}
void click(Button2& btn) {
Serial.println("click\n");
}
void longClickDetected(Button2& btn) {
Serial.println("long click detected\n");
}
void longClick(Button2& btn) {
Serial.println("long click\n");
}
void doubleClick(Button2& btn) {
Serial.println("double click\n");
}
void tripleClick(Button2& btn) {
Serial.println("triple click\n");
}
void tap(Button2& btn) {
Serial.println("tap");
}
/////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,50 @@
/////////////////////////////////////////////////////////////////
#include "Button2.h"
/////////////////////////////////////////////////////////////////
#define BUTTON_PIN 2
/////////////////////////////////////////////////////////////////
Button2 button = Button2(BUTTON_PIN);
/////////////////////////////////////////////////////////////////
void setup() {
Serial.begin(9600);
delay(50);
Serial.println("\n\nButton Demo");
button.setChangedHandler(changed);
//button.setPressedHandler(pressed);
//button.setReleasedHandler(released);
// captures any type of click, longpress or shortpress
button.setTapHandler(tap);
}
/////////////////////////////////////////////////////////////////
void loop() {
button.loop();
}
/////////////////////////////////////////////////////////////////
void pressed(Button2& btn) {
Serial.println("pressed");
}
void released(Button2& btn) {
Serial.print("released: ");
Serial.println(btn.wasPressedFor());
}
void changed(Button2& btn) {
Serial.println("changed");
}
void tap(Button2& btn) {
Serial.println("tap");
}
/////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,33 @@
Button2 KEYWORD1
begin KEYWORD2
setDebounceTime KEYWORD2
setLongClickTime KEYWORD2
setDoubleClickTime KEYWORD2
getDebounceTime KEYWORD2
getLongClickTime KEYWORD2
getDoubleClickTime KEYWORD2
getAttachPin KEYWORD2
setLongClickDetectedRetriggerable KEYWORD2
reset KEYWORD2
setChangedHandler KEYWORD2
setPressedHandler KEYWORD2
setReleasedHandler KEYWORD2
setTapHandler KEYWORD2
setClickHandler KEYWORD2
setDoubleClickHandler KEYWORD2
setTripleClickHandler KEYWORD2
setLongClickHandler KEYWORD2
setLongClickDetectedHandler KEYWORD2
wasPressedFor KEYWORD2
isPressed KEYWORD2
isPressedRaw KEYWORD2
getNumberOfClicks KEYWORD2
getClickType KEYWORD2
loop KEYWORD2
DEBOUNCE_MS LITERAL1
LONGCLICK_MS LITERAL1
DOUBLECLICK_MS LITERAL1
SINGLE_CLICK LITERAL1
DOUBLE_CLICK LITERAL1
TRIPLE_CLICK LITERAL1
LONG_CLICK LITERAL1

View File

@@ -0,0 +1,17 @@
{
"name": "Button2",
"version": "1.6.2",
"keywords": "button",
"description": "Arduino Library to simplify working with buttons.",
"homepage": "https://github.com/LennartHennigs/Button2",
"repository": {
"type": "git",
"url": "https://github.com/LennartHennigs/Button2"
},
"authors": {
"name": "Lennart Hennigs",
"url": "https://lennarthennigs.de"
},
"frameworks": "arduino",
"platforms": "*"
}

View File

@@ -0,0 +1,9 @@
name=Button2
version=1.6.2
author=Lennart Hennigs
maintainer=Lennart Hennigs <mail@lennarthennigs.de>
sentence=Arduino/ESP library to simplify working with buttons.
paragraph=It allows you to use callback functions to track single, double, triple and long clicks. It takes care of debouncing. It will reduce and simplify your souce code significantly. Tested with Arduino, ESP8266 and ESP32.
category=Communication
url=https://github.com/LennartHennigs/Button2
architectures=*

View File

@@ -0,0 +1,293 @@
/////////////////////////////////////////////////////////////////
/*
Button2.cpp - Arduino Library to simplify working with buttons.
Created by Lennart Hennigs.
*/
/////////////////////////////////////////////////////////////////
#include "Button2.h"
/////////////////////////////////////////////////////////////////
Button2::Button2() {
pin = 255;
}
/////////////////////////////////////////////////////////////////
Button2::Button2(byte attachTo, byte buttonMode /* = INPUT_PULLUP */, boolean isCapacitive /* = false */, boolean activeLow /* = true */) {
begin(attachTo, buttonMode, isCapacitive, activeLow);
}
/////////////////////////////////////////////////////////////////
void Button2::begin(byte attachTo, byte buttonMode /* = INPUT_PULLUP */, boolean isCapacitive /* = false */, boolean activeLow /* = true */) {
pin = attachTo;
longclick_detected_retriggerable = false;
setDebounceTime(DEBOUNCE_MS);
setLongClickTime(LONGCLICK_MS);
setDoubleClickTime(DOUBLECLICK_MS);
pressed = activeLow ? LOW : HIGH;
state = activeLow ? HIGH : LOW;
if (!isCapacitive) {
pinMode(attachTo, buttonMode);
} else {
capacitive = true;
}
}
/////////////////////////////////////////////////////////////////
void Button2::setDebounceTime(unsigned int ms) {
debounce_time_ms = ms;
}
/////////////////////////////////////////////////////////////////
void Button2::setLongClickTime(unsigned int ms) {
longclick_time_ms = ms;
}
/////////////////////////////////////////////////////////////////
void Button2::setDoubleClickTime(unsigned int ms) {
doubleclick_time_ms = ms;
}
/////////////////////////////////////////////////////////////////
unsigned int Button2::getDebounceTime() const {
return debounce_time_ms;
}
/////////////////////////////////////////////////////////////////
unsigned int Button2::getLongClickTime() const {
return longclick_time_ms;
}
/////////////////////////////////////////////////////////////////
unsigned int Button2::getDoubleClickTime() const {
return doubleclick_time_ms;
}
/////////////////////////////////////////////////////////////////
byte Button2::getAttachPin() const {
return pin;
}
/////////////////////////////////////////////////////////////////
bool Button2::operator==(Button2 &rhs) {
return (this==&rhs);
}
/////////////////////////////////////////////////////////////////
void Button2::setLongClickDetectedRetriggerable(bool retriggerable) {
longclick_detected_retriggerable = retriggerable;
}
/////////////////////////////////////////////////////////////////
void Button2::setChangedHandler(CallbackFunction f)
{
change_cb = f;
}
/////////////////////////////////////////////////////////////////
void Button2::setPressedHandler(CallbackFunction f) {
pressed_cb = f;
}
/////////////////////////////////////////////////////////////////
void Button2::setReleasedHandler(CallbackFunction f) {
released_cb = f;
}
/////////////////////////////////////////////////////////////////
void Button2::setClickHandler(CallbackFunction f) {
click_cb = f;
}
/////////////////////////////////////////////////////////////////
void Button2::setTapHandler(CallbackFunction f) {
tap_cb = f;
}
/////////////////////////////////////////////////////////////////
void Button2::setLongClickHandler(CallbackFunction f) {
long_cb = f;
}
/////////////////////////////////////////////////////////////////
void Button2::setDoubleClickHandler(CallbackFunction f) {
double_cb = f;
}
/////////////////////////////////////////////////////////////////
void Button2::setTripleClickHandler(CallbackFunction f) {
triple_cb = f;
}
/////////////////////////////////////////////////////////////////
void Button2::setLongClickDetectedHandler(CallbackFunction f) {
longclick_detected_cb = f;
}
/////////////////////////////////////////////////////////////////
unsigned int Button2::wasPressedFor() const {
return down_time_ms;
}
/////////////////////////////////////////////////////////////////
boolean Button2::isPressed() const {
return (state == pressed);
}
/////////////////////////////////////////////////////////////////
boolean Button2::isPressedRaw() const {
return (digitalRead(pin) == pressed);
}
/////////////////////////////////////////////////////////////////
byte Button2::getNumberOfClicks() const {
return click_count;
}
/////////////////////////////////////////////////////////////////
byte Button2::getClickType() const {
return last_click_type;
}
/////////////////////////////////////////////////////////////////
void Button2::loop() {
if (pin != 255) {
prev_state = state;
unsigned long now = millis();
if (!capacitive) {
state = digitalRead(pin);
} else {
#if defined(ARDUINO_ARCH_ESP32)
int capa = touchRead(pin);
state = capa < CAPACITIVE_TOUCH_THRESHOLD ? LOW : HIGH;
#endif
}
// is button pressed?
if (state == pressed && prev_state != pressed) {
down_ms = now;
pressed_triggered = false;
click_ms = down_ms;
// trigger pressed event (after debounce has passed)
} else if (state == pressed && !pressed_triggered && (now - down_ms >= debounce_time_ms)) {
pressed_triggered = true;
click_count++;
if (change_cb != NULL) change_cb (*this);
if (pressed_cb != NULL) pressed_cb (*this);
// is the button released?
} else if (state != pressed && prev_state == pressed) {
down_time_ms = now - down_ms;
// is it beyond debounce time?
if (down_time_ms >= debounce_time_ms) {
// trigger release
if (change_cb != NULL) change_cb (*this);
if (released_cb != NULL) released_cb (*this);
// trigger tap
if (tap_cb != NULL) tap_cb (*this);
// was it a longclick? (preceeds single / double / triple clicks)
if (down_time_ms >= longclick_time_ms) {
longclick_detected = true;
}
}
// is the button released and the time has passed for multiple clicks?
} else if (state != pressed && now - click_ms > doubleclick_time_ms) {
// was there a longclick?
if (longclick_detected) {
// was it part of a combination?
if (click_count == 1) {
last_click_type = LONG_CLICK;
if (long_cb != NULL) long_cb (*this);
}
longclick_detected = false;
longclick_detected_reported = false;
longclick_detected_counter = 0;
// determine the number of single clicks
} else if (click_count > 0) {
switch (click_count) {
case 1:
last_click_type = SINGLE_CLICK;
if (click_cb != NULL) click_cb (*this);
break;
case 2:
last_click_type = DOUBLE_CLICK;
if (double_cb != NULL) double_cb (*this);
break;
case 3:
last_click_type = TRIPLE_CLICK;
if (triple_cb != NULL) triple_cb (*this);
break;
}
}
click_count = 0;
click_ms = 0;
}
bool longclick_period_detected = now - down_ms >= (longclick_time_ms * (longclick_detected_counter + 1));
// check to see that the longclick_ms period has been exceeded and call the appropriate callback
if (state == pressed && longclick_period_detected && !longclick_detected_reported) {
longclick_detected_reported = true;
longclick_detected = true;
if (longclick_detected_retriggerable) {
// if it's retriggerable then we bump the counter and reset the "reported" flag (as the counter will stop the false trigger)
longclick_detected_counter++;
longclick_detected_reported = false;
}
// longpress_detected_ms = now;
if (longclick_detected_cb != NULL)
longclick_detected_cb(*this);
}
}
}
/////////////////////////////////////////////////////////////////
void Button2::reset() {
pin = 255;
click_count = 0;
last_click_type = 0;
down_time_ms = 0;
pressed_triggered = false;
longclick_detected = false;
longclick_detected_reported = false;
pressed_cb = NULL;
released_cb = NULL;
change_cb = NULL;
tap_cb = NULL;
click_cb = NULL;
long_cb = NULL;
double_cb = NULL;
triple_cb = NULL;
longclick_detected_cb = NULL;
}
/////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,110 @@
/////////////////////////////////////////////////////////////////
/*
Button2.cpp - Arduino Library to simplify working with buttons.
Created by Lennart Hennigs.
*/
/////////////////////////////////////////////////////////////////
#pragma once
#ifndef Button2_h
#define Button2_h
/////////////////////////////////////////////////////////////////
#include "Arduino.h"
/////////////////////////////////////////////////////////////////
#define DEBOUNCE_MS 50
#define LONGCLICK_MS 200
#define DOUBLECLICK_MS 300
#define CAPACITIVE_TOUCH_THRESHOLD 35
#define SINGLE_CLICK 1
#define DOUBLE_CLICK 2
#define TRIPLE_CLICK 3
#define LONG_CLICK 4
/////////////////////////////////////////////////////////////////
class Button2 {
protected:
byte pin;
bool capacitive = false;
byte prev_state;
byte state;
byte pressed;
byte click_count = 0;
byte last_click_type = 0;
unsigned long click_ms;
unsigned long down_ms;
bool longclick_detected_retriggerable;
uint16_t longclick_detected_counter;
bool longclick_detected = false;
bool longclick_detected_reported = false;
unsigned int debounce_time_ms;
unsigned int longclick_time_ms;
unsigned int doubleclick_time_ms;
unsigned int down_time_ms = 0;
bool pressed_triggered = false;
typedef void (*CallbackFunction)(Button2 &);
CallbackFunction pressed_cb = NULL;
CallbackFunction released_cb = NULL;
CallbackFunction change_cb = NULL;
CallbackFunction tap_cb = NULL;
CallbackFunction click_cb = NULL;
CallbackFunction long_cb = NULL;
CallbackFunction double_cb = NULL;
CallbackFunction triple_cb = NULL;
CallbackFunction longclick_detected_cb = NULL;
public:
Button2();
Button2(byte attachTo, byte buttonMode = INPUT_PULLUP, boolean isCapacitive = false, boolean activeLow = true);
void begin(byte attachTo, byte buttonMode = INPUT_PULLUP, boolean isCapacitive = false , boolean activeLow = true);
void setDebounceTime(unsigned int ms);
void setLongClickTime(unsigned int ms);
void setDoubleClickTime(unsigned int ms);
unsigned int getDebounceTime() const;
unsigned int getLongClickTime() const;
unsigned int getDoubleClickTime() const;
byte getAttachPin() const;
void setLongClickDetectedRetriggerable(bool retriggerable);
void reset();
void setChangedHandler(CallbackFunction f);
void setPressedHandler(CallbackFunction f);
void setReleasedHandler(CallbackFunction f);
void setTapHandler(CallbackFunction f);
void setClickHandler(CallbackFunction f);
void setDoubleClickHandler(CallbackFunction f);
void setTripleClickHandler(CallbackFunction f);
void setLongClickHandler(CallbackFunction f);
void setLongClickDetectedHandler(CallbackFunction f);
unsigned int wasPressedFor() const;
boolean isPressed() const;
boolean isPressedRaw() const;
byte getNumberOfClicks() const;
byte getClickType() const;
bool operator==(Button2 &rhs);
void loop();
};
/////////////////////////////////////////////////////////////////
#endif
/////////////////////////////////////////////////////////////////