LCOV - code coverage report
Current view: top level - src/Helpers - Hysteresis.hpp (source / functions) Hit Total Coverage
Test: 19d2efc7037c2e176feca44750a12594c76f466f Lines: 12 12 100.0 %
Date: 2019-11-24 14:50:27 Functions: 12 12 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <stdint.h>
       4             : 
       5             : /// @addtogroup    Utilities
       6             : /// @{
       7             : 
       8             : /**
       9             :  * @brief   A class for applying hysteresis to a given input.
      10             :  *
      11             :  * This reduces the noise by decreasing the resolution, and it prevents flipping
      12             :  * back and forth between two values.
      13             :  *
      14             :  * <b>An example for `BITS` = 7 and an input from 0 to 1023</b>
      15             :  * ```
      16             :  *    7                                                     ┌───◄───┬───
      17             :  * o  6                                             ┌───◄───┼───►───┘
      18             :  * u  5                                     ┌───◄───┼───►───┘
      19             :  * t  4                             ┌───◄───┼───►───┘
      20             :  * p  3                     ┌───◄───┼───►───┘
      21             :  * u  2             ┌───◄───┼───►───┘
      22             :  * t  1     ┌───◄───┼───►───┘
      23             :  *    0 ────┴───►───┘
      24             :  *      0      128     256     384     512     640     768     896    1023
      25             :  *                                  i n p u t
      26             :  * ```
      27             :  *
      28             :  * @tparam  BITS
      29             :  *          The number of bits to decrease in resolution.
      30             :  *          Increasing this number will result in a decrease in fluctuations.
      31             :  */
      32             : template <uint8_t BITS, class T_in = uint16_t, class T_out = uint8_t>
      33          17 : class Hysteresis {
      34             :   public:
      35             :     /**
      36             :      * @brief   Update the hysteresis output with a new input value.
      37             :      *
      38             :      * @param   inputLevel
      39             :      *          The input to calculate the output level from.
      40             :      * @retval  true
      41             :      *          The output level has changed.
      42             :      * @retval  false
      43             :      *          The output level is still the same.
      44             :      */
      45          94 :     bool update(T_in inputLevel) {
      46          94 :         T_in prevLevelFull = (T_in(prevLevel) << BITS) | offset;
      47          94 :         T_in lowerbound = prevLevel > 0 ? prevLevelFull - margin : 0;
      48          94 :         T_in upperbound = prevLevel < max_out ? prevLevelFull + margin : max_in;
      49          94 :         if (inputLevel < lowerbound || inputLevel > upperbound) {
      50          40 :             prevLevel = inputLevel >> BITS;
      51          40 :             return true;
      52             :         }
      53          54 :         return false;
      54          94 :     }
      55             : 
      56             :     /**
      57             :      * @brief   Get the current output level.
      58             :      *
      59             :      * @return  The output level.
      60             :      */
      61          94 :     T_out getValue() const { return prevLevel; }
      62             : 
      63             :   private:
      64          17 :     T_out prevLevel = 0;
      65             :     constexpr static T_in margin = (1 << BITS) - 1;
      66             :     constexpr static T_in offset = 1 << (BITS - 1);
      67             :     constexpr static T_in max_in = -1;
      68             :     constexpr static T_out max_out = static_cast<T_out>(max_in >> BITS);
      69             :     static_assert(max_in > 0, "Error: only unsigned types are supported");
      70             : };
      71             : 
      72             : /// @}

Generated by: LCOV version 1.14-5-g4ff2ed6