feat: 全量同步 254 个常用的 Arduino 扩展库文件
This commit is contained in:
332
arduino-libs/arduino-cli/libraries/OneButton/src/OneButton.cpp
Normal file
332
arduino-libs/arduino-cli/libraries/OneButton/src/OneButton.cpp
Normal file
@@ -0,0 +1,332 @@
|
||||
/**
|
||||
* @file OneButton.cpp
|
||||
*
|
||||
* @brief Library for detecting button clicks, doubleclicks and long press
|
||||
* pattern on a single button.
|
||||
*
|
||||
* @author Matthias Hertel, https://www.mathertel.de
|
||||
* @Copyright Copyright (c) by Matthias Hertel, https://www.mathertel.de.
|
||||
*
|
||||
* This work is licensed under a BSD style license. See
|
||||
* http://www.mathertel.de/License.aspx
|
||||
*
|
||||
* More information on: https://www.mathertel.de/Arduino/OneButtonLibrary.aspx
|
||||
*
|
||||
* Changelog: see OneButton.h
|
||||
*/
|
||||
|
||||
#include "OneButton.h"
|
||||
|
||||
// ----- Initialization and Default Values -----
|
||||
|
||||
/**
|
||||
* @brief Construct a new OneButton object but not (yet) initialize the IO pin.
|
||||
*/
|
||||
OneButton::OneButton()
|
||||
{
|
||||
_pin = -1;
|
||||
// further initialization has moved to OneButton.h
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the OneButton library.
|
||||
* @param pin The pin to be used for input from a momentary button.
|
||||
* @param activeLow Set to true when the input level is LOW when the button is pressed, Default is true.
|
||||
* @param pullupActive Activate the internal pullup when available. Default is true.
|
||||
*/
|
||||
OneButton::OneButton(const int pin, const boolean activeLow, const bool pullupActive)
|
||||
{
|
||||
// OneButton();
|
||||
_pin = pin;
|
||||
|
||||
if (activeLow) {
|
||||
// the button connects the input pin to GND when pressed.
|
||||
_buttonPressed = LOW;
|
||||
|
||||
} else {
|
||||
// the button connects the input pin to VCC when pressed.
|
||||
_buttonPressed = HIGH;
|
||||
} // if
|
||||
|
||||
if (pullupActive) {
|
||||
// use the given pin as input and activate internal PULLUP resistor.
|
||||
pinMode(pin, INPUT_PULLUP);
|
||||
} else {
|
||||
// use the given pin as input
|
||||
pinMode(pin, INPUT);
|
||||
} // if
|
||||
} // OneButton
|
||||
|
||||
|
||||
// explicitly set the number of millisec that have to pass by before a click is assumed stable.
|
||||
void OneButton::setDebounceTicks(const int ticks)
|
||||
{
|
||||
_debounceTicks = ticks;
|
||||
} // setDebounceTicks
|
||||
|
||||
|
||||
// explicitly set the number of millisec that have to pass by before a click is detected.
|
||||
void OneButton::setClickTicks(const int ticks)
|
||||
{
|
||||
_clickTicks = ticks;
|
||||
} // setClickTicks
|
||||
|
||||
|
||||
// explicitly set the number of millisec that have to pass by before a long button press is detected.
|
||||
void OneButton::setPressTicks(const int ticks)
|
||||
{
|
||||
_pressTicks = ticks;
|
||||
} // setPressTicks
|
||||
|
||||
|
||||
// save function for click event
|
||||
void OneButton::attachClick(callbackFunction newFunction)
|
||||
{
|
||||
_clickFunc = newFunction;
|
||||
} // attachClick
|
||||
|
||||
|
||||
// save function for parameterized click event
|
||||
void OneButton::attachClick(parameterizedCallbackFunction newFunction, void *parameter)
|
||||
{
|
||||
_paramClickFunc = newFunction;
|
||||
_clickFuncParam = parameter;
|
||||
} // attachClick
|
||||
|
||||
|
||||
// save function for doubleClick event
|
||||
void OneButton::attachDoubleClick(callbackFunction newFunction)
|
||||
{
|
||||
_doubleClickFunc = newFunction;
|
||||
_maxClicks = max(_maxClicks, 2);
|
||||
} // attachDoubleClick
|
||||
|
||||
|
||||
// save function for parameterized doubleClick event
|
||||
void OneButton::attachDoubleClick(parameterizedCallbackFunction newFunction, void *parameter)
|
||||
{
|
||||
_paramDoubleClickFunc = newFunction;
|
||||
_doubleClickFuncParam = parameter;
|
||||
_maxClicks = max(_maxClicks, 2);
|
||||
} // attachDoubleClick
|
||||
|
||||
|
||||
// save function for multiClick event
|
||||
void OneButton::attachMultiClick(callbackFunction newFunction)
|
||||
{
|
||||
_multiClickFunc = newFunction;
|
||||
_maxClicks = max(_maxClicks, 100);
|
||||
} // attachMultiClick
|
||||
|
||||
|
||||
// save function for parameterized MultiClick event
|
||||
void OneButton::attachMultiClick(parameterizedCallbackFunction newFunction, void *parameter)
|
||||
{
|
||||
_paramMultiClickFunc = newFunction;
|
||||
_multiClickFuncParam = parameter;
|
||||
_maxClicks = max(_maxClicks, 100);
|
||||
} // attachMultiClick
|
||||
|
||||
|
||||
// save function for longPressStart event
|
||||
void OneButton::attachLongPressStart(callbackFunction newFunction)
|
||||
{
|
||||
_longPressStartFunc = newFunction;
|
||||
} // attachLongPressStart
|
||||
|
||||
|
||||
// save function for parameterized longPressStart event
|
||||
void OneButton::attachLongPressStart(parameterizedCallbackFunction newFunction, void *parameter)
|
||||
{
|
||||
_paramLongPressStartFunc = newFunction;
|
||||
_longPressStartFuncParam = parameter;
|
||||
} // attachLongPressStart
|
||||
|
||||
|
||||
// save function for longPressStop event
|
||||
void OneButton::attachLongPressStop(callbackFunction newFunction)
|
||||
{
|
||||
_longPressStopFunc = newFunction;
|
||||
} // attachLongPressStop
|
||||
|
||||
|
||||
// save function for parameterized longPressStop event
|
||||
void OneButton::attachLongPressStop(parameterizedCallbackFunction newFunction, void *parameter)
|
||||
{
|
||||
_paramLongPressStopFunc = newFunction;
|
||||
_longPressStopFuncParam = parameter;
|
||||
} // attachLongPressStop
|
||||
|
||||
|
||||
// save function for during longPress event
|
||||
void OneButton::attachDuringLongPress(callbackFunction newFunction)
|
||||
{
|
||||
_duringLongPressFunc = newFunction;
|
||||
} // attachDuringLongPress
|
||||
|
||||
|
||||
// save function for parameterized during longPress event
|
||||
void OneButton::attachDuringLongPress(parameterizedCallbackFunction newFunction, void *parameter)
|
||||
{
|
||||
_paramDuringLongPressFunc = newFunction;
|
||||
_duringLongPressFuncParam = parameter;
|
||||
} // attachDuringLongPress
|
||||
|
||||
|
||||
void OneButton::reset(void)
|
||||
{
|
||||
_state = OneButton::OCS_INIT;
|
||||
_lastState = OneButton::OCS_INIT;
|
||||
_nClicks = 0;
|
||||
_startTime = 0;
|
||||
}
|
||||
|
||||
|
||||
// ShaggyDog ---- return number of clicks in any case: single or multiple clicks
|
||||
int OneButton::getNumberClicks(void)
|
||||
{
|
||||
return _nClicks;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Check input of the configured pin and then advance the finite state
|
||||
* machine (FSM).
|
||||
*/
|
||||
void OneButton::tick(void)
|
||||
{
|
||||
if (_pin >= 0) {
|
||||
tick(digitalRead(_pin) == _buttonPressed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Advance to a new state and save the last one to come back in cas of bouncing detection.
|
||||
*/
|
||||
void OneButton::_newState(stateMachine_t nextState)
|
||||
{
|
||||
_lastState = _state;
|
||||
_state = nextState;
|
||||
} // _newState()
|
||||
|
||||
|
||||
/**
|
||||
* @brief Run the finite state machine (FSM) using the given level.
|
||||
*/
|
||||
void OneButton::tick(bool activeLevel)
|
||||
{
|
||||
unsigned long now = millis(); // current (relative) time in msecs.
|
||||
unsigned long waitTime = (now - _startTime);
|
||||
|
||||
// Implementation of the state machine
|
||||
switch (_state) {
|
||||
case OneButton::OCS_INIT:
|
||||
// waiting for level to become active.
|
||||
if (activeLevel) {
|
||||
_newState(OneButton::OCS_DOWN);
|
||||
_startTime = now; // remember starting time
|
||||
_nClicks = 0;
|
||||
} // if
|
||||
break;
|
||||
|
||||
case OneButton::OCS_DOWN:
|
||||
// waiting for level to become inactive.
|
||||
|
||||
if ((!activeLevel) && (waitTime < _debounceTicks)) {
|
||||
// button was released to quickly so I assume some bouncing.
|
||||
_newState(_lastState);
|
||||
|
||||
} else if (!activeLevel) {
|
||||
_newState(OneButton::OCS_UP);
|
||||
_startTime = now; // remember starting time
|
||||
|
||||
} else if ((activeLevel) && (waitTime > _pressTicks)) {
|
||||
if (_longPressStartFunc) _longPressStartFunc();
|
||||
if (_paramLongPressStartFunc) _paramLongPressStartFunc(_longPressStartFuncParam);
|
||||
_newState(OneButton::OCS_PRESS);
|
||||
} // if
|
||||
break;
|
||||
|
||||
case OneButton::OCS_UP:
|
||||
// level is inactive
|
||||
|
||||
if ((activeLevel) && (waitTime < _debounceTicks)) {
|
||||
// button was pressed to quickly so I assume some bouncing.
|
||||
_newState(_lastState); // go back
|
||||
|
||||
} else if (waitTime >= _debounceTicks) {
|
||||
// count as a short button down
|
||||
_nClicks++;
|
||||
_newState(OneButton::OCS_COUNT);
|
||||
} // if
|
||||
break;
|
||||
|
||||
case OneButton::OCS_COUNT:
|
||||
// dobounce time is over, count clicks
|
||||
|
||||
if (activeLevel) {
|
||||
// button is down again
|
||||
_newState(OneButton::OCS_DOWN);
|
||||
_startTime = now; // remember starting time
|
||||
|
||||
} else if ((waitTime > _clickTicks) || (_nClicks == _maxClicks)) {
|
||||
// now we know how many clicks have been made.
|
||||
|
||||
if (_nClicks == 1) {
|
||||
// this was 1 click only.
|
||||
if (_clickFunc) _clickFunc();
|
||||
if (_paramClickFunc) _paramClickFunc(_clickFuncParam);
|
||||
|
||||
} else if (_nClicks == 2) {
|
||||
// this was a 2 click sequence.
|
||||
if (_doubleClickFunc) _doubleClickFunc();
|
||||
if (_paramDoubleClickFunc) _paramDoubleClickFunc(_doubleClickFuncParam);
|
||||
|
||||
} else {
|
||||
// this was a multi click sequence.
|
||||
if (_multiClickFunc) _multiClickFunc();
|
||||
if (_paramMultiClickFunc) _paramMultiClickFunc(_doubleClickFuncParam);
|
||||
} // if
|
||||
|
||||
reset();
|
||||
} // if
|
||||
break;
|
||||
|
||||
case OneButton::OCS_PRESS:
|
||||
// waiting for menu pin being release after long press.
|
||||
|
||||
if (!activeLevel) {
|
||||
_newState(OneButton::OCS_PRESSEND);
|
||||
_startTime = now;
|
||||
|
||||
} else {
|
||||
// still the button is pressed
|
||||
if (_duringLongPressFunc) _duringLongPressFunc();
|
||||
if (_paramDuringLongPressFunc) _paramDuringLongPressFunc(_duringLongPressFuncParam);
|
||||
} // if
|
||||
break;
|
||||
|
||||
case OneButton::OCS_PRESSEND:
|
||||
// button was released.
|
||||
|
||||
if ((activeLevel) && (waitTime < _debounceTicks)) {
|
||||
// button was released to quickly so I assume some bouncing.
|
||||
_newState(_lastState); // go back
|
||||
|
||||
} else if (waitTime >= _debounceTicks) {
|
||||
if (_longPressStopFunc) _longPressStopFunc();
|
||||
if (_paramLongPressStopFunc) _paramLongPressStopFunc(_longPressStopFuncParam);
|
||||
reset();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// nothing to do.
|
||||
break;
|
||||
} // if
|
||||
|
||||
} // OneButton.tick()
|
||||
|
||||
|
||||
// end.
|
||||
Reference in New Issue
Block a user