94 lines
2.0 KiB
C++
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
|
|
}
|