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