9#include <AH/Arduino-Wrapper.h>
12#include <AH/Containers/Array.hpp>
13#include <AH/STL/limits>
14#include <AH/STL/type_traits>
56template <
class RegisterType, uint8_t NumEnc,
57 class EncoderPositionType = int32_t,
bool InterruptSafe =
false>
60 static_assert(std::is_unsigned<RegisterType>::value,
61 "RegisterType should be an unsigned integer type");
64 typename std::conditional<InterruptSafe,
volatile EncoderPositionType,
65 EncoderPositionType>::type;
68 typename std::conditional<InterruptSafe,
volatile RegisterType,
82 void reset(RegisterType resetstate) {
103 RegisterType oldstate =
state;
106 if (newstate == oldstate)
116 for (uint8_t i = 0; i < NumEnc; ++i) {
118 uint8_t change =
static_cast<uint8_t
>(newstate) & 0b11;
121 change |=
static_cast<uint8_t
>(oldstate) & 0b11;
142 EncoderPositionType
read(uint8_t idx)
const {
145 EncoderPositionType ret =
positions[idx];
166 EncoderPositionType ret =
positions[idx];
171 EncoderPositionType ret =
positions[idx];
187 void write(uint8_t idx, EncoderPositionType pos) {
213 EncoderPositionType
read()
const {
216 EncoderPositionType ret = *
position;
229 EncoderPositionType ret = *
position;
234 EncoderPositionType ret = *
position;
242 void write(EncoderPositionType pos) {
252#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5
#define BEGIN_AH_NAMESPACE
static constexpr int8_t RegisterEncodersLUT[16]
Lookup table that maps rotary encoder (2-bit gray code) state changes to position deltas.
#define AH_DIAGNOSTIC_EXTERNAL_HEADER()
#define AH_DIAGNOSTIC_POP()
#define AH_DIAGNOSTIC_WERROR()
Proxy to access a single encoder of the encoders managed by RegisterEncoders.
EncoderPositionStorageType * position
A pointer to the position value inside of the RegisterEncoders class.
void write(EncoderPositionType pos)
Set the position of the encoder.
EncoderPositionType read() const
Read the position of the encoder.
EncoderPositionType readAndReset()
Read the position of the encoder and reset it to zero.
Encoder(EncoderPositionStorageType *position)
Class for keeping track of the position of multiple rotary encoders.
Encoder operator[](uint8_t index)
Get a proxy to one of the encoders managed by this object.
typename std::conditional< InterruptSafe, volatile EncoderPositionType, EncoderPositionType >::type EncoderPositionStorageType
typename std::conditional< InterruptSafe, volatile RegisterType, RegisterType >::type StateStorageType
void reset(RegisterType resetstate)
Reset the positions to zero and the state to the given value.
EncoderPositionType read(uint8_t idx) const
Read the position of the given encoder.
Array< EncoderPositionStorageType, NumEnc > positions
bool update(RegisterType newstate)
Update the encoder positions based on the new state.
EncoderPositionType readAndReset(uint8_t idx)
Read the position of the given encoder and reset it to zero.
void reset()
Reset the positions to zero and the state to 0xFF...FF.
void write(uint8_t idx, EncoderPositionType pos)
Set the position of the given encoder.
constexpr auto max(const T &a, const U &b) -> decltype(a< b ? b :a)
Return the larger of two numbers/objects.