forked from JChristensen/JC_Button
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Button.cpp
146 lines (134 loc) · 5.89 KB
/
Button.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*----------------------------------------------------------------------*
* Arduino Button Library v1.0 *
* Jack Christensen May 2011, published Mar 2012 *
* *
* Library for reading momentary contact switches like tactile button *
* switches. Intended for use in state machine constructs. *
* Use the read() function to read all buttons in the main loop, *
* which should execute as fast as possible. *
* *
* This work is licensed under the Creative Commons Attribution- *
* ShareAlike 3.0 Unported License. To view a copy of this license, *
* visit http://creativecommons.org/licenses/by-sa/3.0/ or send a *
* letter to Creative Commons, 171 Second Street, Suite 300, *
* San Francisco, California, 94105, USA. *
*----------------------------------------------------------------------*/
#include "Button.h"
/*----------------------------------------------------------------------*
* Button(pin, puEnable, invert, dbTime) instantiates a button object. *
* pin Is the Arduino pin the button is connected to. *
* puEnable Enables the AVR internal pullup resistor if != 0 (can also *
* use true or false). *
* invert If invert == 0, interprets a high state as pressed, low as *
* released. If invert != 0, interprets a high state as *
* released, low as pressed (can also use true or false). *
* dbTime Is the debounce time in milliseconds. *
* *
* (Note that invert cannot be implied from puEnable since an external *
* pullup could be used.) *
*----------------------------------------------------------------------*/
Button::Button(uint8_t pin, uint8_t puEnable, uint8_t invert, uint32_t dbTime)
{
_pin = pin;
_puEnable = puEnable;
_invert = invert;
_dbTime = dbTime;
pinMode(_pin, INPUT);
if (_puEnable != 0)
digitalWrite(_pin, HIGH); //enable pullup resistor
_state = digitalRead(_pin);
if (_invert != 0) _state = !_state;
_time = millis();
_lastState = _state;
_changed = 0;
_lastChange = _time;
}
/*----------------------------------------------------------------------*
* read() returns the state of the button, 1==pressed, 0==released, *
* does debouncing, captures and maintains times, previous states, etc. *
*----------------------------------------------------------------------*/
uint8_t Button::read(void)
{
static uint32_t ms;
static uint8_t pinVal;
ms = millis();
pinVal = digitalRead(_pin);
if (_invert != 0) pinVal = !pinVal;
if (ms - _lastChange < _dbTime) {
_time = ms;
_changed = 0;
return _state;
}
else {
_lastState = _state;
_state = pinVal;
_time = ms;
if (_state != _lastState) {
_changeDuration = ms - _lastChange;
_lastChange = ms;
_changed = 1;
}
else {
_changed = 0;
}
return _state;
}
}
/*----------------------------------------------------------------------*
* isPressed() and isReleased() check the button state when it was last *
* read, and return false (0) or true (!=0) accordingly. *
* These functions do not cause the button to be read. *
*----------------------------------------------------------------------*/
uint8_t Button::isPressed(void)
{
return _state == 0 ? 0 : 1;
}
uint8_t Button::isReleased(void)
{
return _state == 0 ? 1 : 0;
}
/*----------------------------------------------------------------------*
* wasPressed() and wasReleased() check the button state to see if it *
* changed between the last two reads and return false (0) or *
* true (!=0) accordingly. *
* These functions do not cause the button to be read. *
*----------------------------------------------------------------------*/
uint8_t Button::wasPressed(void)
{
return _state && _changed;
}
uint8_t Button::wasReleased(void)
{
return !_state && _changed;
}
/*----------------------------------------------------------------------*
* pressedFor(ms) and releasedFor(ms) check to see if the button is *
* pressed (or released), and has been in that state for the specified *
* time in milliseconds. Returns false (0) or true (1) accordingly. *
* These functions do not cause the button to be read. *
*----------------------------------------------------------------------*/
uint8_t Button::pressedFor(uint32_t ms)
{
return (_state == 1 && _time - _lastChange >= ms) ? 1 : 0;
}
uint8_t Button::releasedFor(uint32_t ms)
{
return (_state == 0 && _time - _lastChange >= ms) ? 1 : 0;
}
/*----------------------------------------------------------------------*
* wasPressedOrReleasedFor(ms) check to see how long the button was *
* pressed (or released). Returns false (0) or true (1) accordingly. *
* These functions do not cause the button to be read. *
*----------------------------------------------------------------------*/
uint8_t Button::wasPressedOrReleasedFor(uint32_t ms)
{
return ( _changeDuration >= ms) ? 1 : 0;
}
/*----------------------------------------------------------------------*
* lastChange() returns the time the button last changed state, *
* in milliseconds. *
*----------------------------------------------------------------------*/
uint32_t Button::lastChange(void)
{
return _lastChange;
}