221 lines
5.9 KiB
C++
221 lines
5.9 KiB
C++
/////////////////////////////////////////////////////////////////
|
|
/*
|
|
ESP8266/Arduino Library for reading rotary encoder values.
|
|
Copyright 2017-2021 Lennart Hennigs.
|
|
*/
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
#include "ESPRotary.h"
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// initialize static counter
|
|
|
|
int ESPRotary::_nextID = 0;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
ESPRotary::ESPRotary() {
|
|
id = _nextID++;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
ESPRotary::ESPRotary(byte pin1, byte pin2, byte steps_per_click /* = 1 */, int lower_bound /* = INT16_MIN */, int upper_bound /* = INT16_MAX */, int inital_pos /* = 0 */, int increment /* = 1 */) {
|
|
id = _nextID++;
|
|
begin(pin1, pin2, steps_per_click, lower_bound, upper_bound, inital_pos, increment);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
void ESPRotary::begin(byte pin1, byte pin2, byte steps_per_click /* = 1 */, int lower_bound /* = INT16_MIN */, int upper_bound /* = INT16_MAX */, int inital_pos /* = 0 */, int increment /* = 1 */) {
|
|
this->pin1 = pin1;
|
|
this->pin2 = pin2;
|
|
pinMode(pin1, INPUT_PULLUP);
|
|
pinMode(pin2, INPUT_PULLUP);
|
|
|
|
setUpperBound(upper_bound);
|
|
setLowerBound(lower_bound);
|
|
setIncrement(increment);
|
|
setStepsPerClick(steps_per_click);
|
|
|
|
loop();
|
|
resetPosition(inital_pos, false);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
void ESPRotary::setUpperBound(int upper_bound) {
|
|
this->upper_bound = (lower_bound < upper_bound) ? upper_bound: lower_bound;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
void ESPRotary::setLowerBound(int lower_bound) {
|
|
this->lower_bound = (lower_bound < upper_bound) ? lower_bound : upper_bound;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
int ESPRotary::getUpperBound() const {
|
|
return this->upper_bound;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
int ESPRotary::getLowerBound() const {
|
|
return this->lower_bound;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
void ESPRotary::setChangedHandler(CallbackFunction f) {
|
|
change_cb = f;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
void ESPRotary::setRightRotationHandler(CallbackFunction f) {
|
|
right_cb = f;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
void ESPRotary::setLeftRotationHandler(CallbackFunction f) {
|
|
left_cb = f;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
void ESPRotary::setUpperOverflowHandler(CallbackFunction f) {
|
|
upper_cb = f;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
void ESPRotary::setLowerOverflowHandler(CallbackFunction f) {
|
|
lower_cb = f;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
void ESPRotary::resetPosition(int p /* = 0 */, bool fireCallback /* = true */) {
|
|
if (p > upper_bound) {
|
|
last_position = upper_bound * steps_per_click;
|
|
} else {
|
|
last_position = (lower_bound > p) ? lower_bound * steps_per_click : p * steps_per_click;
|
|
}
|
|
|
|
if (position != last_position) {
|
|
position = last_position;
|
|
if (fireCallback && change_cb != NULL) change_cb (*this);
|
|
}
|
|
direction = 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
void ESPRotary::setIncrement(int inc) {
|
|
increment = inc;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
int ESPRotary::getIncrement() const {
|
|
return increment;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
void ESPRotary::setStepsPerClick(int steps) {
|
|
steps_per_click = (steps < 1) ? 1 : steps;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
int ESPRotary::getStepsPerClick() const {
|
|
return steps_per_click;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
byte ESPRotary::getDirection() const {
|
|
return direction;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
String ESPRotary::directionToString(byte direction) const {
|
|
if (direction == RE_LEFT) {
|
|
return "LEFT";
|
|
} else {
|
|
return "RIGHT";
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
int ESPRotary::getPosition() const {
|
|
return position / steps_per_click;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
int ESPRotary::getID() const {
|
|
return id;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
void ESPRotary::setID(int newID) {
|
|
id = newID;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
bool ESPRotary::operator == (ESPRotary &rhs) {
|
|
return (this == &rhs);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
void ESPRotary::loop() {
|
|
int s = state & 3;
|
|
if (digitalRead(pin1)) s |= 4;
|
|
if (digitalRead(pin2)) s |= 8;
|
|
|
|
switch (s) {
|
|
case 0: case 5: case 10: case 15:
|
|
break;
|
|
case 1: case 7: case 8: case 14:
|
|
position += increment; break;
|
|
case 2: case 4: case 11: case 13:
|
|
position -= increment; break;
|
|
case 3: case 12:
|
|
position += 2 * increment; break;
|
|
default:
|
|
position -= 2 * increment; break;
|
|
}
|
|
state = (s >> 2);
|
|
|
|
if (position != last_position && (abs(position - last_position) >= steps_per_click * increment)) {
|
|
int current_position = getPosition();
|
|
if (current_position >= lower_bound && current_position <= upper_bound) {
|
|
if (position > last_position) {
|
|
direction = RE_RIGHT;
|
|
if (right_cb != NULL) right_cb (*this);
|
|
} else {
|
|
direction = RE_LEFT;
|
|
if (left_cb != NULL) left_cb (*this);
|
|
}
|
|
last_position = position;
|
|
if (change_cb != NULL) change_cb (*this);
|
|
} else {
|
|
position = last_position;
|
|
if (current_position < lower_bound && lower_cb != NULL) lower_cb (*this);
|
|
if (current_position > upper_bound && upper_cb != NULL) upper_cb (*this);
|
|
}
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|