Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 62 additions & 39 deletions src/clickButton.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/* ClickButton

A library that decodes multiple clicks on one button.
Also copes with long clicks and click-and-hold.

Usage: ClickButton buttonObject(pin [LOW/HIGH, [CLICKBTN_PULLUP]]);

where LOW/HIGH denotes active LOW or HIGH button (default is LOW)
CLICKBTN_PULLUP is only possible with active low buttons.

Returned click counts:

A positive number denotes the number of (short) clicks after a released button
A negative number denotes the number of "long" clicks

NOTE!
This is the OPPOSITE/negative of click codes from the last pre-2013 versions!
(this seemed more logical and simpler, so I finally changed it)
Expand All @@ -22,17 +22,17 @@ NOTE!
Copyright (C) 2010,2012, 2013 raron

GNU GPLv3 license

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

Expand All @@ -51,6 +51,21 @@ NOTE!

#include "clickButton.h"

ClickButton::ClickButton(bool (*readFunc)(uint8_t), uint8_t pin, bool activeType){
_pin = pin;
_activeHigh = activeType; // Assume active-low button
_btnState = !_activeHigh; // initial button state in active-high logic
_lastState = _btnState;
_clickCount = 0;
clicks = 0;
depressed = false;
_lastBounceTime= 0;
debounceTime = 20; // Debounce timer in ms
multiclickTime = 250; // Time limit for multi clicks
longClickTime = 1000; // time until long clicks register
_readFunction = readFunc;
}

ClickButton::ClickButton(uint8_t buttonPin)
{
_pin = buttonPin;
Expand Down Expand Up @@ -110,38 +125,46 @@ ClickButton::ClickButton(uint8_t buttonPin, boolean activeType, boolean internal
void ClickButton::Update()
{
long now = (long)millis(); // get current time
_btnState = digitalRead(_pin); // current appearant button state

// Make the button logic active-high in code
if (!_activeHigh) _btnState = !_btnState;

// If the switch changed, due to noise or a button press, reset the debounce timer
if (_btnState != _lastState) _lastBounceTime = now;


// debounce the button (Check if a stable, changed state has occured)
if (now - _lastBounceTime > debounceTime && _btnState != depressed)
{
depressed = _btnState;
if (depressed) _clickCount++;
}

// If the button released state is stable, report nr of clicks and start new cycle
if (!depressed && (now - _lastBounceTime) > multiclickTime)
{
// positive count for released buttons
clicks = _clickCount;
_clickCount = 0;
bool didRead = false;
if(_readFunction){
_btnState = _readFunction(_pin);
didRead = true;
} else {
_btnState = pinReadFast(_pin); // current appearant button state
didRead = true;
}

// Check for "long click"
if (depressed && (now - _lastBounceTime > longClickTime))
{
// negative count for long clicks
clicks = 0 - _clickCount;
_clickCount = 0;
if(didRead){
// Make the button logic active-high in code
if (!_activeHigh) _btnState = !_btnState;

// If the switch changed, due to noise or a button press, reset the debounce timer
if (_btnState != _lastState) _lastBounceTime = now;


// debounce the button (Check if a stable, changed state has occured)
if (now - _lastBounceTime > debounceTime && _btnState != depressed)
{
depressed = _btnState;
if (depressed) _clickCount++;
}

// If the button released state is stable, report nr of clicks and start new cycle
if (!depressed && (now - _lastBounceTime) > multiclickTime)
{
// positive count for released buttons
clicks = _clickCount;
_clickCount = 0;
}

// Check for "long click"
if (depressed && (now - _lastBounceTime > longClickTime))
{
// negative count for long clicks
clicks = 0 - _clickCount;
_clickCount = 0;
}

_lastState = _btnState;
}

_lastState = _btnState;
}

19 changes: 11 additions & 8 deletions src/clickButton.h
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/* ClickButton

A library that decodes multiple clicks on one button.
Also copes with long clicks and click-and-hold.

Usage: ClickButton buttonObject(pin [LOW/HIGH, [CLICKBTN_PULLUP]]);

where LOW/HIGH denotes active LOW or HIGH button (default is LOW)
CLICKBTN_PULLUP is only possible with active low buttons.

Returned click counts:

A positive number denotes the number of (short) clicks after a released button
A negative number denotes the number of "long" clicks

NOTE!
This is the OPPOSITE/negative of click codes from the last pre-2013 versions!
(this seemed more logical and simpler, so I finally changed it)
Expand All @@ -22,17 +22,17 @@ NOTE!
Copyright (C) 2010,2012, 2013 raron

GNU GPLv3 license

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

Expand All @@ -57,6 +57,7 @@ NOTE!
class ClickButton
{
public:
ClickButton(bool (*readFunc)(uint8_t), uint8_t pin, bool activeType);
ClickButton(uint8_t buttonPin);
ClickButton(uint8_t buttonPin, boolean active);
ClickButton(uint8_t buttonPin, boolean active, boolean internalPullup);
Expand All @@ -73,6 +74,8 @@ class ClickButton
boolean _lastState; // previous button reading
int _clickCount; // Number of button clicks within multiclickTime milliseconds
long _lastBounceTime; // the last time the button input pin was toggled, due to noise or a press
bool (*_readFunction)(uint8_t) = NULL; // read function, must have single paramter uint8_t and return bool
uint32_t _lastRead;
};

// -------- end clickButton.h --------