LCOV - code coverage report
Current view: top level - src/Selectors - EncoderSelector.hpp (source / functions) Hit Total Coverage
Test: b8a30b4b7040ae1abf162fd0a258beaa2de43626 Lines: 5 28 17.9 %
Date: 2024-12-21 21:28:55 Functions: 3 7 42.9 %
Legend: Lines: hit not hit

          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

Generated by: LCOV version 1.15