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;
125 positions[i] += delta;
142 EncoderPositionType
read(uint8_t idx)
const {
145 EncoderPositionType ret = positions[idx];
149 return positions[idx];
166 EncoderPositionType ret = positions[idx];
171 EncoderPositionType ret = positions[idx];
187 void write(uint8_t idx, EncoderPositionType pos) {
190 positions[idx] = pos;
193 positions[idx] = 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
268 return &positions[index];
#define BEGIN_AH_NAMESPACE
#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.
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.
static constexpr int8_t RegisterEncodersLUT[16]
Lookup table that maps rotary encoder (2-bit gray code) state changes to position deltas.