-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathButton.cpp
More file actions
127 lines (106 loc) · 3.75 KB
/
Button.cpp
File metadata and controls
127 lines (106 loc) · 3.75 KB
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
#include "Button.h"
/************************************************************
* pinAddress: Arduino Pin which it is connected to
* resistorPull: Voltage when button is open, accepted values:
* LOW, HIGH and INPUT_PULLUP to indicate to use internal resistor
************************************************************/
Button::Button(uint8_t pinAddress, uint8_t resistorPull) {
this->pinAddress = pinAddress;
if (resistorPull == INPUT_PULLUP) {
this->resistorPull = HIGH;
pinMode(pinAddress, resistorPull);
} else {
this->resistorPull = resistorPull;
pinMode(pinAddress, INPUT);
}
};
void Button::setOnClick(void(*onClick)()) {
this->onClick = onClick;
}
bool Button::isClicked() {
return stateTransition(Enums::STATE_INACTIVE, Enums::STATE_ACTIVE);
}
unsigned int Button::getClickCount() {
return clickCount;
}
/************************************************************
* The amount of time before a button is considered to be
* released. Accepted values: [0 - 255 milliseconds]
************************************************************/
void Button::setDebounceDelay(uint8_t ms) {
this->debounceDelay = ms;
}
/************************************************************
* The amount of time between button polls.
* Accepted values: [0 - 255 milliseconds]
************************************************************/
void Button::setPollInterval(uint8_t ms) {
this->pollInterval = ms;
}
/************************************************************
* The amount of time before a button can be clicked again.
* Accepted values: [0 - 65535 milliseconds]
************************************************************/
void Button::setOnClickInterval(uint16_t ms) {
this->onClickInterval = ms;
}
/************************************************************
* Checks the Button value for a maximum number of times of
* <UPDATE_RATE_MS> per second.
* Inverts the value if button is pulled up.
************************************************************/
Enums Button::readButtonVal() {
return (digitalRead(pinAddress) == resistorPull) ? Enums::BUTTON_UP : Enums::BUTTON_DOWN;
}
/************************************************************
* Checks to make sure that the button has been released for
* <debounceDelay> milliseconds.
************************************************************/
bool Button::checkIfReleased(Enums buttonVal) {
if (buttonVal == Enums::BUTTON_UP) {
if (debounceStartTime == 0) {
debounceStartTime = millis();
} else if ((millis() - debounceStartTime) >= debounceDelay) {
debounceStartTime = 0;
return true;
}
} else {
debounceStartTime = 0;
}
return false;
}
Enums Button::determineButtonState(Enums buttonVal) {
if (state == Enums::STATE_INACTIVE) {
if (buttonVal == Enums::BUTTON_DOWN && ((millis() - lastClickTime) >= onClickInterval)) {
return Enums::STATE_ACTIVE;
}
} else if (checkIfReleased(buttonVal)) {
return Enums::STATE_INACTIVE;
}
return state;
}
bool Button::stateTransition(Enums lastState, Enums state) {
if (this->lastState == lastState && this->state == state) {
return true;
}
return false;
}
/************************************************************
* Determines button state and triggers onClick actions.
************************************************************/
void Button::update() {
if (millis() - lastPollTime < pollInterval) {
return;
}
Enums buttonVal = readButtonVal();
lastPollTime = millis();
lastState = state;
state = determineButtonState(buttonVal);
if (lastState != state) {
if (stateTransition(Enums::STATE_INACTIVE, Enums::STATE_ACTIVE)) {
clickCount++;
lastClickTime = millis();
if (onClick != nullptr) onClick();
}
}
}