Line data Source code
1 : #pragma once 2 : 3 : #include "Selector.hpp" 4 : #include <AH/Hardware/ExtendedInputOutput/ExtendedInputOutput.hpp> 5 : #include <Def/Def.hpp> 6 : #include <Def/TypeTraits.hpp> 7 : 8 : #ifdef ARDUINO 9 : #include <Submodules/Encoder/AHEncoder.hpp> 10 : #else 11 : #include <Encoder.h> // Mock 12 : #endif 13 : 14 : BEGIN_CS_NAMESPACE 15 : 16 : template <setting_t N, class Callback = EmptySelectorCallback> 17 : class GenericEncoderSelector : public GenericSelector<N, Callback> { 18 : using Parent = GenericSelector<N, Callback>; 19 : 20 : public: 21 2 : GenericEncoderSelector(Selectable<N> &selectable, const Callback &callback, 22 : const EncoderSwitchPinList &pins, 23 : int8_t pulsesPerStep = 4, Wrap wrap = Wrap::Wrap) 24 : : GenericSelector<N, Callback> {selectable, callback}, 25 2 : encoder {pins.A, pins.B}, switchPin(pins.switchPin), 26 4 : pulsesPerStep(pulsesPerStep), wrap(wrap) {} 27 : 28 0 : void begin() override { 29 0 : Parent::begin(); 30 0 : if (switchPin != NO_PIN) 31 0 : AH::ExtIO::pinMode(switchPin, INPUT_PULLUP); 32 0 : begin_if_possible(encoder); 33 0 : } 34 : 35 0 : void update() override { 36 0 : Parent::update(); 37 : // TODO: use EncoderState 38 0 : long currentPosition = encoder.read(); 39 0 : long difference = (currentPosition - previousPosition) / pulsesPerStep; 40 0 : if (difference) { 41 0 : previousPosition += difference * pulsesPerStep; 42 0 : if (difference > 0) 43 0 : while (difference-- > 0) 44 0 : this->increment(wrap); 45 : else 46 0 : while (difference++ < 0) 47 0 : this->decrement(wrap); 48 : } 49 : 50 0 : if (switchPin != NO_PIN) { 51 0 : bool currentState = AH::ExtIO::digitalRead(switchPin); 52 0 : if (previousSwitchState == HIGH && currentState == LOW) { 53 : // TODO: invert? 54 0 : this->reset(); 55 : } 56 0 : previousSwitchState = currentState; 57 : } 58 0 : } 59 : 60 : private: 61 : AHEncoder encoder; 62 : pin_t switchPin; 63 : int8_t pulsesPerStep; 64 : Wrap wrap; 65 : 66 : long previousPosition = 0; 67 : bool previousSwitchState = HIGH; 68 : }; 69 : 70 : // -------------------------------------------------------------------------- // 71 : 72 : /** 73 : * @brief Selector that reads from a rotary encoder. 74 : * 75 : * @ingroup Selectors 76 : * 77 : * @tparam N 78 : * The number of settings. 79 : */ 80 : template <setting_t N> 81 : class EncoderSelector : public GenericEncoderSelector<N> { 82 : public: 83 1 : EncoderSelector(Selectable<N> &selectable, const EncoderSwitchPinList &pins, 84 : int8_t pulsesPerStep = 4, Wrap wrap = Wrap::Wrap) 85 : : GenericEncoderSelector<N> { 86 : selectable, {}, pins, pulsesPerStep, wrap, 87 1 : } {} 88 : }; 89 : 90 : END_CS_NAMESPACE