172 lines
5.0 KiB
C++
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;
|
|
}
|
|
} |