LCOV - code coverage report
Current view: top level - src/Selectors - EncoderSelector.hpp (source / functions) Coverage Total Hit
Test: 73449d9b107c772cf65493691543348214e5d5eb Lines: 17.9 % 28 5
Test Date: 2026-06-06 17:44:35 Functions: 42.9 % 7 3
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 2.4-beta