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 : 38 : /// @brief Initialize (enable the internal pull-up resistor). 39 : void begin(); 40 : 41 : /** 42 : * @brief Invert the input state of this button 43 : * (button pressed is `HIGH` instead of `LOW`). 44 : */ 45 : void invert(); 46 : 47 : /// @brief An enumeration of the different states a button can be in. 48 : enum State { 49 : Pressed = 0b00, ///< Input went from low to low (0,0) 50 : Released = 0b11, ///< Input went from high to high (1,1) 51 : Falling = 0b10, ///< Input went from high to low (1,0) 52 : Rising = 0b01 ///< Input went from low to high (0,1) 53 : }; 54 : 55 : /** 56 : * @brief Read the button and return its new state. 57 : * 58 : * The button is debounced, the debounce time can be set in 59 : * Settings.hpp: #BUTTON_DEBOUNCE_TIME. 60 : * 61 : * ``` 62 : * Debounce time: ├────┤ 63 : * 64 : * Raw input: 65 : * HIGH ──────┐ ┌──────┐ ┌─┐ ┌─┐ ┌──────┐ ┌──────── 66 : * LOW └──────┘ └─┘ └──────┘ └─┘ └─┘ 67 : * ├────┤ ├────┤ ├─┼─┼────┤ ├─┼─┼────┤ ├─┼────┤ 68 : * 69 : * Debounced output: 70 : * HIGH ──────┐ ┌──────┐ ┌──────────┐ ┌─── 71 : * LOW └──────┘ └──────────┘ └──────┘ 72 : * 73 : * States: 74 : * HIGH ────────────────┐ ┌───────────────── 75 : * LOW └──────────────────┘ 76 : * Released Falling Pressed Rising 77 : * ``` 78 : * 79 : * @return The state of the button, either Button::Pressed, 80 : * Button::Released, Button::Falling or Button::Rising. 81 : */ 82 : State update(); 83 : 84 : /** 85 : * @brief Get the state of the button, without updating it. 86 : * Returns the same value as the last call to @ref update. 87 : * 88 : * @return The state of the button, either Button::Pressed, 89 : * Button::Released, Button::Falling or Button::Rising. 90 : */ 91 : State getState() const; 92 : 93 : /// @brief Return the name of the state as a string. 94 : static FlashString_t getName(State state); 95 : 96 : /// Return the time point (in milliseconds) when the button last bounced. 97 : unsigned long previousBounceTime() const; 98 : 99 : /// Return the time (in milliseconds) that the button has been stable for, 100 : /// compared to the given time point. 101 : unsigned long stableTime(unsigned long now) const; 102 : 103 : /// Return the time (in milliseconds) that the button has been stable for. 104 : unsigned long stableTime() const; 105 : 106 : /** 107 : * @brief Set the debounce time for all Button%s. 108 : * 109 : * @note This function affects **all** Button objects. 110 : * 111 : * @param debounceTime 112 : * The new debounce time in milliseconds. 113 : */ 114 : static void 115 : setDebounceTime(unsigned long debounceTime = BUTTON_DEBOUNCE_TIME); 116 : 117 : /** 118 : * @brief Get the debounce time. 119 : * @return The debounce time in milliseconds. 120 : * @see setDebounceTime 121 : */ 122 : static unsigned long getDebounceTime(); 123 : 124 : private: 125 : pin_t pin; 126 : 127 : struct InternalState { 128 111 : InternalState() 129 111 : : debounced(0b11), bouncing(true), prevInput(HIGH), invert(false), 130 111 : prevBounceTime(0) {} 131 : uint8_t debounced : 2; 132 : bool bouncing : 1; 133 : bool prevInput : 1; 134 : bool invert : 1; 135 : unsigned long prevBounceTime; 136 : } state; 137 : 138 : /// Edit this in Settings.hpp 139 : /// @see BUTTON_DEBOUNCE_TIME 140 : static unsigned long debounceTime; 141 : }; 142 : 143 : END_AH_NAMESPACE 144 : 145 : AH_DIAGNOSTIC_POP()