Skip to content

Commit

Permalink
#165 support steps in encoder, #136 support raw interrupt handling us…
Browse files Browse the repository at this point in the history
…ing std::function on ESP32 and STM32 boards
  • Loading branch information
davetcc committed Sep 25, 2022
1 parent 3179ae3 commit 8975b99
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 26 deletions.
18 changes: 12 additions & 6 deletions examples/buttonRotaryEncoder/buttonRotaryEncoder.ino
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,23 @@
const pinid_t spinwheelClickPin = 0;

// The pin onto which we connected the repeat button switch
const pinid_t repeatButtonPin = 1;
const pinid_t repeatButtonPin = PC9;

// The two pins where we connected the A and B pins of the encoder, the A pin must support interrupts.
const pinid_t encoderAPin = 16;
const pinid_t encoderBPin = 17;
const pinid_t encoderAPin = PC8;
const pinid_t encoderBPin = PC10;

// the maximum (0 based) value that we want the encoder to represent.
const int maximumEncoderValue = 128;

// an LED that flashes as the encoder changes
const int ledOutputPin = 12;
const int ledOutputPin = LED_BLUE;

// You can change the step rate of the encoder, it defaults to 1, but can be changed during a precision change
const int stepSize = 2;

// You can set the encoder to wrap around at min/max values, or just to stop there.
const bool wrapAround = true;

auto boardIo = internalDigitalIo();

Expand Down Expand Up @@ -69,7 +75,7 @@ void setup() {
// our next task is to initialise swtiches, do this BEFORE doing anything else with switches.
// We choose to initialise in poll everything (requires no interrupts), but there are other modes too:
// (SWITCHES_NO_POLLING - interrupt only) or (SWITCHES_POLL_KEYS_ONLY - encoders on interrupt)
switches.init(boardIo, SWITCHES_POLL_EVERYTHING, true);
switches.init(boardIo, SWITCHES_POLL_KEYS_ONLY, true);

// now we add the switches, we don't want the spin-wheel button to repeat, so leave off the last parameter
// which is the repeat interval (millis / 20 basically) Repeat button does repeat as we can see.
Expand All @@ -80,7 +86,7 @@ void setup() {
// we give the encoder a max value of 128, always minimum of 0.
auto hwEncoder = new HardwareRotaryEncoder(encoderAPin, encoderBPin, onEncoderChange);
switches.setEncoder(0, hwEncoder);
hwEncoder->changePrecision(maximumEncoderValue, 100);
hwEncoder->changePrecision(maximumEncoderValue, 100, wrapAround, stepSize);
}

void loop() {
Expand Down
35 changes: 18 additions & 17 deletions src/SwitchInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,15 +225,15 @@ void SwitchInput::pushSwitch(pinid_t pin, bool held) {
keys.getByKey(pin)->trigger(held);
}

void SwitchInput::changeEncoderPrecision(uint8_t slot, uint16_t precision, uint16_t currentValue, bool rollover) {
void SwitchInput::changeEncoderPrecision(uint8_t slot, uint16_t precision, uint16_t currentValue, bool rollover, int step) {
if (slot < MAX_ROTARY_ENCODERS && encoder[slot] != nullptr) {
encoder[slot]->changePrecision(precision, currentValue, rollover);
encoder[slot]->changePrecision(precision, (int)currentValue, rollover, step);
}
}

void SwitchInput::setEncoder(uint8_t slot, RotaryEncoder* encoder) {
void SwitchInput::setEncoder(uint8_t slot, RotaryEncoder* enc) {
if (slot < MAX_ROTARY_ENCODERS) {
this->encoder[slot] = encoder;
this->encoder[slot] = enc;
}
}

Expand Down Expand Up @@ -276,15 +276,17 @@ RotaryEncoder::RotaryEncoder(EncoderListener* listener) : notify{} {
this->notify.encoderListener = listener;
this->currentReading = 0;
this->maximumValue = 0;
this->stepSize = 1;
this->flags = 0U;
bitWrite(flags, LAST_SYNC_STATUS, 1);
bitWrite(flags, OO_LISTENER_CALLBACK, 1);
this->intent = CHANGE_VALUE;
}

void RotaryEncoder::changePrecision(uint16_t maxValue, int currentValue, bool rolloverOnMax) {
void RotaryEncoder::changePrecision(uint16_t maxValue, int currentValue, bool rolloverOnMax, int step) {
this->maximumValue = maxValue;
this->currentReading = currentValue;
this->stepSize = step;
bitWrite(flags, WRAP_AROUND_MODE, rolloverOnMax);
if(maxValue == 0U && currentValue == 0) intent = DIRECTION_ONLY;
runCallback((int)currentReading);
Expand Down Expand Up @@ -387,22 +389,21 @@ void onSwitchesInterrupt(__attribute__((unused)) pinid_t pin) {
}

int HardwareRotaryEncoder::amountFromChange(unsigned long change) {
if(change > 250000 || maximumValue < ONE_TURN_OF_ENCODER) return 1;
if(change > 250000 || maximumValue < ONE_TURN_OF_ENCODER) return stepSize;

if(accelerationMode == HWACCEL_NONE) {
return 1;
return stepSize;
}
else if(accelerationMode == HWACCEL_REGULAR) {
if(change > 120000) return 2;
else if (change > 70000) return 4;
else if (change > 30000) return 6;
else return 10;
if(change > 120000) return stepSize + stepSize;
else if (change > 70000) return stepSize << 2;
else if (change > 30000) return stepSize << 3;
else return stepSize << 4;
}
else { // slower, very slight acceleration..

if(change > 100000) return 2;
else if (change > 30000) return 3;
else return 4;
if(change > 100000) return stepSize + stepSize;
else if (change > 30000) return stepSize + stepSize + stepSize;
else return stepSize << 2;
}

}
Expand Down Expand Up @@ -452,10 +453,10 @@ EncoderUpDownButtons::EncoderUpDownButtons(pinid_t pinUp, pinid_t pinDown, Encod

void EncoderUpDownButtons::onPressed(pinid_t pin, bool held) {
if(pin == upPin) {
int8_t dir = (switches.getEncoder()->getUserIntention() == SCROLL_THROUGH_ITEMS) ? -1 : 1;
int8_t dir = (switches.getEncoder()->getUserIntention() == SCROLL_THROUGH_ITEMS) ? -stepSize : stepSize;
increment(dir);
} else if(pin == downPin) {
int8_t dir = (switches.getEncoder()->getUserIntention() == SCROLL_THROUGH_ITEMS) ? 1 : -1;
int8_t dir = (switches.getEncoder()->getUserIntention() == SCROLL_THROUGH_ITEMS) ? stepSize : -stepSize;
increment(dir);
}
}
Expand Down
10 changes: 7 additions & 3 deletions src/SwitchInput.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ class RotaryEncoder {
enum EncoderFlagBits { LAST_SYNC_STATUS=0, WRAP_AROUND_MODE, OO_LISTENER_CALLBACK };
uint16_t maximumValue;
uint16_t currentReading;
uint8_t stepSize;
union {
EncoderCallbackFn callback;
EncoderListener* encoderListener;
Expand All @@ -202,7 +203,7 @@ class RotaryEncoder {
* @param maxValue the largest value allowed or zero for direction only mode
* @param currentValue the current value (zero for direction mode)
*/
void changePrecision(uint16_t maxValue, int currentValue, bool rolloverOnMax = false);
void changePrecision(uint16_t maxValue, int currentValue, bool rolloverOnMax = false, int step = 1);

/**
* Change the callback that will be used to notify of changes in the encoder value, this must never be null.
Expand Down Expand Up @@ -480,8 +481,9 @@ class SwitchInput {
* maximum value that can be represented and also the current value of the encoder.
* @param precision the maximum value to be set
* @param currentValue the current value to be set.
* @param step the size of each step of the encoder, default is 1
*/
void changeEncoderPrecision(uint16_t precision, uint16_t currentValue) { changeEncoderPrecision(0, precision, currentValue); }
void changeEncoderPrecision(uint16_t precision, uint16_t currentValue, int step=1) { changeEncoderPrecision(0, precision, currentValue, step); }

/**
* Use this version of changeEncoderPrecision if you are working with more than one rotary encoder.
Expand All @@ -490,8 +492,10 @@ class SwitchInput {
* @param slot the index of the desired encoder, zero based
* @param precision the maximum value to be set
* @param currentValue the current value to be set.
* @param rollover if the encoder should wrap around at min/max values or stop
* @param step the size of each step of the encoder, default is 1
*/
void changeEncoderPrecision(uint8_t slot, uint16_t precision, uint16_t currentValue, bool rollover = false);
void changeEncoderPrecision(uint8_t slot, uint16_t precision, uint16_t currentValue, bool rollover = false, int step = 1);

/**
* Simulates a switch press by calling the callback directly without changing the internal state
Expand Down

0 comments on commit 8975b99

Please sign in to comment.