Files

94 lines
2.0 KiB
C++

#pragma once
// 3rdparty lib includes
#include <espchrono.h>
// local includes
#include "globals.h"
#include "types.h"
namespace {
template<typename HANDLER, pin_t CLK, pin_t DT, pin_t SW>
class Rotary
{
public:
static constexpr auto ClkPin = CLK;
static constexpr auto DtPin = DT;
static constexpr auto SwPin = SW;
void begin();
void updateRotate();
void updateSwitch();
private:
espchrono::millis_clock::time_point m_lastMillis;
bool m_lastClk;
bool m_lastSw{};
};
template<typename HANDLER, pin_t CLK, pin_t DT, pin_t SW>
void Rotary<HANDLER, CLK, DT, SW>::begin()
{
m_lastMillis = espchrono::millis_clock::now();
pinMode(ClkPin, INPUT_PULLUP);
pinMode(DtPin, INPUT_PULLUP);
pinMode(SwPin, INPUT_PULLUP);
m_lastClk = digitalRead(ClkPin);
}
template<typename HANDLER, pin_t CLK, pin_t DT, pin_t SW>
void Rotary<HANDLER, CLK, DT, SW>::updateRotate()
{
const auto now = espchrono::millis_clock::now();
if (now - m_lastMillis < 1ms)
return;
m_lastMillis = now;
const bool currentClk = digitalRead(ClkPin);
if (currentClk != m_lastClk)
{
HANDLER::rotate(digitalRead(DtPin) != currentClk ? 1 : -1);
m_lastClk = currentClk;
}
}
template<typename HANDLER, pin_t CLK, pin_t DT, pin_t SW>
void Rotary<HANDLER, CLK, DT, SW>::updateSwitch()
{
const auto now = espchrono::millis_clock::now();
if (now - m_lastMillis < 1ms)
return;
m_lastMillis = now;
const bool currentSw = !bool(digitalRead(SwPin));
if (currentSw != m_lastSw)
{
HANDLER::button(currentSw);
m_lastSw = currentSw;
}
}
#ifdef FEATURE_ROTARY
Rotary<InputDispatcher, PINS_ROTARY_CLK, PINS_ROTARY_DT, PINS_ROTARY_SW> rotary;
void updateRotate() { rotary.updateRotate(); }
void updateSwitch() { rotary.updateSwitch(); }
void initRotary()
{
rotary.begin();
attachInterrupt(decltype(rotary)::ClkPin, updateRotate, CHANGE);
attachInterrupt(decltype(rotary)::SwPin, updateSwitch, CHANGE);
}
void updateRotary()
{
}
#endif
}