Files
DeautherX-SRAciJa/DeautherX/src/SimpleButton/Buttons/RotaryEncoder.cpp
2025-12-02 18:52:45 +03:00

172 lines
5.0 KiB
C++

#include "RotaryEncoder.h"
namespace simplebutton {
RotaryEncoder::RotaryEncoder() {
setButtons(NULL, NULL, NULL);
}
RotaryEncoder::RotaryEncoder(uint8_t channelA, uint8_t channelB, uint8_t button) {
setup(channelA, channelB, button);
}
RotaryEncoder::RotaryEncoder(GPIOExpander* pcf, uint8_t channelA, uint8_t channelB, uint8_t button) {
setup(pcf, channelA, channelB, button);
}
RotaryEncoder::RotaryEncoder(Button* clockwise, Button* anticlockwise, Button* button) {
setup(clockwise, anticlockwise, button);
}
RotaryEncoder::~RotaryEncoder() {
if (this->clockwise) delete this->clockwise;
if (this->anticlockwise) delete this->anticlockwise;
if (this->button) delete this->button;
}
void RotaryEncoder::setup(uint8_t channelA, uint8_t channelB, uint8_t button) {
this->clockwise = new ButtonPullup(channelA);
this->anticlockwise = new ButtonPullup(channelB);
this->button = new ButtonPullup(button);
prevA = clockwise->read();
prevB = anticlockwise->read();
}
void RotaryEncoder::setup(GPIOExpander* pcf, uint8_t channelA, uint8_t channelB, uint8_t button) {
this->clockwise = new ButtonPullupGPIOExpander(pcf, channelA);
this->anticlockwise = new ButtonPullupGPIOExpander(pcf, channelB);
this->button = new ButtonPullupGPIOExpander(pcf, button);
prevA = clockwise->read();
prevB = anticlockwise->read();
}
void RotaryEncoder::setup(Button* clockwise, Button* anticlockwise, Button* button) {
setButtons(clockwise, anticlockwise, button);
prevA = clockwise->read();
prevB = anticlockwise->read();
}
void RotaryEncoder::update() {
update(clockwise->read(), anticlockwise->read(), button->read());
}
void RotaryEncoder::update(bool stateA, bool stateB, bool buttonState) {
button->update(buttonState);
if (curState == State::STILL) {
if ((stateA != prevA) && (stateB == prevB)) {
prevA = stateA;
curState = State::ANTICLOCKWISE;
} else if ((stateA == prevA) && (stateB != prevB)) {
prevB = stateB;
curState = State::CLOCKWISE;
}
} else if ((curState != State::STILL) && (stateA == stateB)) {
prevA = stateA;
prevB = stateB;
if (curState == prevState) steps++;
else steps = 1;
if (steps >= button_steps) {
if (curState == State::CLOCKWISE) {
if (!inverted) goClockwise();
else goAnticlockwise();
} else if (curState == State::ANTICLOCKWISE) {
if (!inverted) goAnticlockwise();
else goClockwise();
}
steps = 0;
}
prevState = curState;
curState = State::STILL;
}
}
void RotaryEncoder::reset() {
button->reset();
clockwise->reset();
anticlockwise->reset();
curState = State::STILL;
prevState = State::STILL;
steps = 0;
}
int32_t RotaryEncoder::getPos() {
return pos;
}
void RotaryEncoder::setButtons(Button* clockwise, Button* anticlockwise, Button* button) {
if (this->clockwise) delete this->clockwise;
if (this->anticlockwise) delete this->anticlockwise;
if (this->button) delete this->button;
this->clockwise = clockwise ? clockwise : new Button();
this->anticlockwise = anticlockwise ? anticlockwise : new Button();
this->button = button ? button : new Button();
}
void RotaryEncoder::setPos(int32_t pos) {
this->pos = pos;
}
void RotaryEncoder::setMin(int32_t value) {
this->min = value;
}
void RotaryEncoder::setMax(int32_t value) {
this->max = value;
}
void RotaryEncoder::setEncoding(uint8_t steps) {
if ((steps == 1) || (steps == 2) || (steps == 4)) this->button_steps = steps;
}
void RotaryEncoder::enableLoop(bool loop) {
this->loop = loop;
}
void RotaryEncoder::setInverted(bool inverted) {
this->inverted = inverted;
}
void RotaryEncoder::goClockwise() {
clockwise->click();
anticlockwise->reset();
if (pos < max) pos++;
else if (loop) pos = min;
}
void RotaryEncoder::goAnticlockwise() {
anticlockwise->click();
clockwise->reset();
if (pos > min) pos--;
else if (loop) pos = max;
}
bool RotaryEncoder::clicked() {
return button->clicked();
}
bool RotaryEncoder::incremented() {
return clockwise->clicked();
}
bool RotaryEncoder::decremented() {
return anticlockwise->clicked();
}
bool RotaryEncoder::minVal() {
return pos == min;
}
bool RotaryEncoder::maxVal() {
return pos == max;
}
}