AbleButtons V0.4.0
Lightweight button library for Arduino.
 
Loading...
Searching...
No Matches
Button.h
Go to the documentation of this file.
1/**
2 * @file Button.h Definition of the core Able Button template class.
3 *
4 * @copyright Copyright (c) 2022 John Scott.
5 */
6#pragma once
7#include "Circuits.h"
8#include "Pins.h"
9
10namespace able {
11 /**
12 * Core Button class. It supports pulldown and pull-up resistor circuits
13 * specified using the Circuit template parameter and different pin features
14 * using the Pin template parameter.
15 *
16 * @param Circuit Either a PullupResistorCircuit or PulldownResistorCircuit
17 * class matching the resistor circuit used with the button.
18 * @param Pin The Pin class, or a subclass (DebouncedPin or ClickerPin)
19 * providing additional debounced readings and clicked states.
20 */
21 template <typename Circuit, typename Pin>
22 class Button: public Pin {
23 public:
24 //
25 // Constants...
26 //
27 enum {
28 BUTTON_PRESSED = Circuit::BUTTON_PRESSED,
29 BUTTON_RELEASED = Circuit::BUTTON_RELEASED
30 };
31
32 public:
33 //
34 // Creators...
35 //
36
37 /**
38 * Create a button on the specified pin.
39 *
40 * @param pin The pin connected to the button.
41 */
42 Button(uint8_t pin)
43 :Pin(pin, Circuit::BUTTON_RELEASED) {}
44
45 private:
46 //
47 // Copying and assignment (not supported)...
48 //
49 Button(const Button &cpy) = delete; ///< Copying is not supported.
50 Button &operator=(const Button &) = delete; ///< Assigning buttons is not supported.
51
52 public:
53 //
54 // Modifiers...
55 //
56
57 /**
58 * Initialise the button. Called from setup() of an Arduino program.
59 */
60 void begin() {
61 pinMode(this->pin_, Circuit::PIN_MODE);
62 }
63
64 /**
65 * Handle the button. Called from loop() of an Arduino program.
66 */
67 void handle() {
68 this->readPin();
69 }
70
71 /**
72 * Reset the clicked state of the button, returning what is was. This
73 * allows the click state to be effectively read once so that a clicked
74 * state only triggers something once, when checked. For example toggling
75 * something on/off when the button is clicked. For buttons that don't
76 * support clicking, the compile will fail with errors.
77 *
78 * @return True if the button was clicked, else false.
79 */
80 bool resetClicked() {
81 bool rc = this->isClicked();
82 this->prevState_ = this->currState_;
83 return rc;
84 }
85
86 /**
87 * Reset the clicked state of the button, returning what is was. This
88 * allows the click state to be effectively read once so that a clicked
89 * state only triggers something once, when checked. For example toggling
90 * something on/off when the button is clicked. For buttons that don't
91 * support clicking, the compile will fail with errors.
92 *
93 * @return True if the button was clicked, else false.
94 */
96 bool rc = this->isSingleClicked();
97 if(rc) this->stateCount_ = 0;
98 return rc;
99 }
100
101 /**
102 * Reset the double-clicked state of the button, returning what is was.
103 * This allows the double-click state to be effectively read once so that
104 * a double-clicked state only triggers something once, when checked.
105 * For example toggling something on/off when the button is double-
106 * clicked. For buttons that don't support double-clicking, the compile
107 * will fail with errors.
108 *
109 * @return True if the button was double-clicked, else false.
110 */
112 bool rc = this->isDoubleClicked();
113 if(rc) this->stateCount_ = 0;
114 return rc;
115 }
116
117 public:
118 //
119 // Accessors...
120 //
121
122 /**
123 * Determine if the button is currently pressed.
124 *
125 * @return True if pressed, else false.
126 */
127 bool isPressed() const {
128 return this->currState_ == Circuit::BUTTON_PRESSED;
129 }
130
131 /**
132 * Determine if the button is currently held down.
133 *
134 * @return True if held, else false.
135 */
136 bool isHeld() const {
137 return isPressed() && ((millis() - this->millisStart_) >= this->heldTime_);
138 }
139
140 /**
141 * Determine if the button is currently idle (unpressed for a "long" time).
142 *
143 * @return True if idle, else false.
144 */
145 bool isIdle() const {
146 return !isPressed() && ((millis() - this->millisStart_) >= this->idleTime_);
147 }
148
149 /**
150 * Determine if the button is clicked. Clicks are registered as a press
151 * then release. If the ClickerPin (or subclass) is used, the button
152 * returns the click state, otherwise the compile will fail with errors.
153 *
154 * @return True if clicked else false.
155 */
156 bool isClicked() const {
157 return this->currState_ == Circuit::BUTTON_RELEASED && this->prevState_ == Circuit::BUTTON_PRESSED;
158 }
159
160 /**
161 * Determine if the button is exclusively single-clicked. Clicks are
162 * registered as a press then release. Single-clicks wait until any
163 * double-click time has passed to ensure it's exclusively a click and not
164 * the first click in a double-click sequence. If the DoubleClickerPin is
165 * used, the button returns the single-click state, otherwise the compile
166 * will fail with errors.
167 *
168 * @return True if exclusively clicked else false.
169 */
170 bool isSingleClicked() const {
171 return this->stateCount_ == 2 && ((millis() - this->millisStart_) >= this->clickTime_);
172 }
173
174 /**
175 * Determine if the button is double-clicked. Double-clicks are registered
176 * as two clicks within the double-click time. If the DoubleClickPin is
177 * used, the button returns the double-click state, otherwise the compile
178 * will fail with errors.
179 *
180 * @return True if double-clicked else false.
181 */
182 bool isDoubleClicked() const {
183 return this->stateCount_ >= 4;
184 }
185 };
186}
Definition of Pulldown and pull-up ressitor circuits.
Definition of the Pin class and subclasses (DebouncedPin, ClickerPin), providing debounce logic when ...
Core Button class.
Definition: Button.h:22
void begin()
Initialise the button.
Definition: Button.h:60
void handle()
Handle the button.
Definition: Button.h:67
bool resetDoubleClicked()
Reset the double-clicked state of the button, returning what is was.
Definition: Button.h:111
bool resetClicked()
Reset the clicked state of the button, returning what is was.
Definition: Button.h:80
bool isClicked() const
Determine if the button is clicked.
Definition: Button.h:156
bool isHeld() const
Determine if the button is currently held down.
Definition: Button.h:136
bool isIdle() const
Determine if the button is currently idle (unpressed for a "long" time).
Definition: Button.h:145
bool isSingleClicked() const
Determine if the button is exclusively single-clicked.
Definition: Button.h:170
bool isDoubleClicked() const
Determine if the button is double-clicked.
Definition: Button.h:182
bool isPressed() const
Determine if the button is currently pressed.
Definition: Button.h:127
Button(uint8_t pin)
Create a button on the specified pin.
Definition: Button.h:42
bool resetSingleClicked()
Reset the clicked state of the button, returning what is was.
Definition: Button.h:95
Resistor circuit base class.
Definition: Circuits.h:16
Pin base class reading direct from the pin (without debouncing).
Definition: Pins.h:17
uint8_t pin_
The Arduino pin connected to the button.
Definition: Pins.h:93
void readPin()
Read the pin directly.
Definition: Pins.h:66
uint8_t currState_
The reading of the pin.
Definition: Pins.h:94