LCOV - code coverage report
Current view: top level - src/Selectors - EncoderSelector.hpp (source / functions) Hit Total Coverage
Test: 19d2efc7037c2e176feca44750a12594c76f466f Lines: 12 37 32.4 %
Date: 2019-11-24 14:50:27 Functions: 6 13 46.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14-5-g4ff2ed6