Most definitely not overthinking, because my microcontroller is busy for 20ms sampling audio data every loop, and then spends 1-2ms at most sending that data over a radio connection.
I experienced from my own testing, that trying to handle inputs from the encoder or a button during the remaining time in the loop leaves a lot to be desired in terms of user experience.
I definitely need interrupts, and I have solved my problem, using this library:
I was unable to configure another pin like the ones I did.
I realize that I was not even using the hardware interrupt pins (D2, D3), but instead the A2, and A3 pins, so technically, I had it working, but for reasons that I do not understand I was not able to translate that to a third input, without said library.
I can say though that this library makes for nicely readable code, and there is not much in it anways, so I will stick with it.
Thanks also to @groundFungus for mentioning again that PCI can be used for every pin. I found that out by myself, eventually, but I think the documentation could be a bit more forthcoming about this.
Code that I am using, resulting in perfect user experience, no bouncing, instant reaction, always.
Of course the audio sampling suffers, when I turn the encoder quickly, but that is not actually a concern.
// Rotary encoder
#include "RotaryEncoder.h"
#include "YetAnotherPcInt.h"
#define RTRY_ENC_SW A1
#define RTRY_ENC_CLK A2
#define RTRY_ENC_DT A3
RotaryEncoder encoder(RTRY_ENC_CLK, RTRY_ENC_DT);
void onSwitch();
void onRotate();
void setup () {
pinMode(RTRY_ENC_SW, INPUT_PULLUP);
PcInt::attachInterrupt(RTRY_ENC_SW, onSwitch, FALLING);
PcInt::attachInterrupt(RTRY_ENC_CLK, onRotate, CHANGE);
PcInt::attachInterrupt(RTRY_ENC_DT, onRotate, CHANGE);
// ...
}
bool hasInputs = false;
void loop () {
if (hasInputs) {
hasInputs = false;
handleButtonInputs();
}
// ...
}
void handleButtonInputs() {
if (switchPressed) {
switchPressed = false;
// react ...
}
RotaryEncoder::Direction direction = encoder.getDirection();
if (direction == RotaryEncoder::Direction::CLOCKWISE) {
// react ...
} else if (direction == RotaryEncoder::Direction::COUNTERCLOCKWISE) {
// react ...
}
}
void onSwitch() {
hasInputs = true;
switchPressed = true;
}
void onRotate() {
hasInputs = true;
encoder.tick();
}