#ifndef _BUTTON_H_ #define _BUTTON_H_ #include #include #include using namespace admux; class Joystick; // forward declaration enum ButtonType { BUTTON_PASSTHRU = 0x1, // always use the (debounced) absolute state of the input BUTTON_PULSED = 0x2, // on button press, send an on signal followed immediately by an off signal. BUTTON_PULSED_DOUBLE_ACTION = 0x4, // Send a button press twice - once for press and once for release. BUTTON_PULSED_DOUBLE_ACTION_SPLIT = 0x8, // Send two separate button presses - one button on press, another on release. BUTTON_LATCHED_MOMENTARY = 0x10, ENCODER_PULSED_SPLIT = 0x20 // A rotary encoder that should be treated as two different pulsed/momentary buttons, one for each direction }; // The abstract button base class. A button must have, at a minimum: // * a button *type* (typically automatically assigned by the constructor) // * at least one "virtual button" - that is, a Joystick input that it controls // * an update method. class Button { public: Button(uint8_t vbutton); virtual bool Update(Joystick* js) = 0; virtual void ReleaseButtons(Joystick* js); ButtonType type; protected: uint8_t vbutton; }; // An abstract class for a momentary/pushbutton or toggle switch. Special properties: // * needs to be explicitly debounced // * may use the microcontroller's built-in pullup resistor mode to eliminate noise // * may be attached to a multiplexer. In this case, the `pin` value will be treated as a multiplexer channel, // and the multiplexer logic will be automatically invoked by Update() class SwitchButton : public Button { public: SwitchButton(uint8_t pin, uint8_t vbutton, bool pullup, Mux* mux); bool BouncerUpdate(); // returns true if the pin's status has changed bool On(); protected: Bounce bouncer; bool inverted; Mux *mux; uint8_t channel_id; }; class PassthruButton : public SwitchButton { public: PassthruButton(uint8_t pin, uint8_t vbutton, bool pullup = true, Mux* mux = NULL); bool Update(Joystick* js); }; class LatchedButton : public SwitchButton { public: LatchedButton(uint8_t pin, uint8_t vbutton, bool pullup = true, Mux* mux = NULL); bool Update(Joystick* js); protected: bool pressed; }; class PulsedButton : public SwitchButton { public: PulsedButton(uint8_t pin, uint8_t vbutton, bool double_action = false, bool split = false, bool pullup = true, Mux* mux = NULL); bool Update(Joystick* js); void ReleaseButtons(Joystick* js); protected: bool double_action; bool split; uint8_t vbutton2; }; class EncoderButton : public Button { public: EncoderButton(uint8_t pin1, uint8_t pin2, uint8_t vbutton); bool Update(Joystick* js); void ReleaseButtons(Joystick* js); protected: Encoder* encoder; long last_value; uint8_t vbutton2; }; // Internal use only. #define _BUTTON_PULSED_TYPES (BUTTON_PULSED | BUTTON_PULSED_DOUBLE_ACTION | BUTTON_PULSED_DOUBLE_ACTION_SPLIT | ENCODER_PULSED_SPLIT) #endif