Line data Source code
1 : /* ✔ */ 2 : 3 : #pragma once 4 : 5 : #include <AH/Settings/Warnings.hpp> 6 : AH_DIAGNOSTIC_WERROR() // Enable errors on warnings 7 : 8 : #include <AH/Hardware/ExtendedInputOutput/ExtendedInputOutput.hpp> 9 : #include <AH/Settings/SettingsWrapper.hpp> 10 : 11 : BEGIN_AH_NAMESPACE 12 : 13 : /** 14 : * @brief A class for reading and debouncing buttons and switches. 15 : * 16 : * @ingroup AH_HardwareUtils 17 : */ 18 : class Button { 19 : public: 20 : /** 21 : * @brief Construct a new Button object. 22 : * 23 : * **This constructor should not be used.** 24 : * It is just a way to easily create arrays of buttons, and initializing 25 : * them later. 26 : */ 27 12 : Button() : pin(NO_PIN) {} 28 : 29 : /** 30 : * @brief Construct a new Button object. 31 : * 32 : * @param pin 33 : * The digital pin to read from. The internal pull-up resistor 34 : * will be enabled when `begin` is called. 35 : */ 36 : Button(pin_t pin); 37 : /// @copydoc Button(pin_t) 38 32 : Button(ArduinoPin_t pin) : Button(pin_t(pin)) {} 39 : 40 : /// @brief Initialize (enable the internal pull-up resistor). 41 : void begin(); 42 : 43 : /** 44 : * @brief Invert the input state of this button 45 : * (button pressed is `HIGH` instead of `LOW`). 46 : */ 47 : void invert(); 48 : 49 : /// @brief An enumeration of the different states a button can be in. 50 : enum State { 51 : Pressed = 0b00, ///< Input went from low to low (0,0) 52 : Released = 0b11, ///< Input went from high to high (1,1) 53 : Falling = 0b10, ///< Input went from high to low (1,0) 54 : Rising = 0b01 ///< Input went from low to high (0,1) 55 : }; 56 : 57 : /** 58 : * @brief Read the button and return its new state. 59 : * 60 : * The button is debounced, the debounce time can be set in 61 : * Settings.hpp: #BUTTON_DEBOUNCE_TIME. 62 : * 63 : * ``` 64 : * Debounce time: ├────┤ 65 : * 66 : * Raw input: 67 : * HIGH ──────┐ ┌──────┐ ┌─┐ ┌─┐ ┌──────┐ ┌──────── 68 : * LOW └──────┘ └─┘ └──────┘ └─┘ └─┘ 69 : * ├────┤ ├────┤ ├─┼─┼────┤ ├─┼─┼────┤ ├─┼────┤ 70 : * 71 : * Debounced output: 72 : * HIGH ──────┐ ┌──────┐ ┌──────────┐ ┌─── 73 : * LOW └──────┘ └──────────┘ └──────┘ 74 : * 75 : * States: 76 : * HIGH ────────────────┐ ┌───────────────── 77 : * LOW └──────────────────┘ 78 : * Released Falling Pressed Rising 79 : * ``` 80 : * 81 : * @return The state of the button, either Button::Pressed, 82 : * Button::Released, Button::Falling or Button::Rising. 83 : */ 84 : State update(); 85 : 86 : /** 87 : * @brief Get the state of the button, without updating it. 88 : * Returns the same value as the last call to @ref update. 89 : * 90 : * @return The state of the button, either Button::Pressed, 91 : * Button::Released, Button::Falling or Button::Rising. 92 : */ 93 : State getState() const; 94 : 95 : /// @brief Return the name of the state as a string. 96 : static FlashString_t getName(State state); 97 : 98 : /// Return the time point (in milliseconds) when the button last bounced. 99 : unsigned long previousBounceTime() const; 100 : 101 : /// Return the time (in milliseconds) that the button has been stable for, 102 : /// compared to the given time point. 103 : unsigned long stableTime(unsigned long now) const; 104 : 105 : /// Return the time (in milliseconds) that the button has been stable for. 106 : unsigned long stableTime() const; 107 : 108 : /** 109 : * @brief Set the debounce time for all Button%s. 110 : * 111 : * @note This function affects **all** Button objects. 112 : * 113 : * @param debounceTime 114 : * The new debounce time in milliseconds. 115 : */ 116 : static void 117 : setDebounceTime(unsigned long debounceTime = BUTTON_DEBOUNCE_TIME); 118 : 119 : /** 120 : * @brief Get the debounce time. 121 : * @return The debounce time in milliseconds. 122 : * @see setDebounceTime 123 : */ 124 : static unsigned long getDebounceTime(); 125 : 126 : private: 127 : pin_t pin; 128 : 129 : struct InternalState { 130 111 : InternalState() 131 111 : : debounced(0b11), bouncing(true), prevInput(HIGH), invert(false), 132 111 : prevBounceTime(0) {} 133 : uint8_t debounced : 2; 134 : bool bouncing : 1; 135 : bool prevInput : 1; 136 : bool invert : 1; 137 : unsigned long prevBounceTime; 138 : } state; 139 : 140 : /// Edit this in Settings.hpp 141 : /// @see BUTTON_DEBOUNCE_TIME 142 : static unsigned long debounceTime; 143 : }; 144 : 145 : END_AH_NAMESPACE 146 : 147 : AH_DIAGNOSTIC_POP()