Simply put, I'm controlling a DC-motor with a dual-channel encoder with a microcontroller for a personal project, and I'm trying to find the "best" software-based implementation of the following state-machine given in this TI reference manual:
Before doing any actual research on the topic, I, being a hot-headed idiot, quickly tried to use a (software implementation of a) D-flip-flop to get the motor direction, and then increment or decrement a counter according to the direction. Half C, half pseudo-code here:
uint16_t counter = 0;
uint8_t direction = 0;
void interruptEncoderA(void){
if(getInput(encoder_a) == 1){
direction = getPinValue(encoder_b);
}
direction ? counter++ : counter--;
}
void interruptEncoderB(void){
direction ? counter++ : counter--;
}
The interrupts happen on both edges of the corresponding channel. This naive implementation has some very clear problems. For instance, when the motor is going back and forth between the edges of encoder B, it will keep counting on the same direction.
I know that this question may actually be somewhat subjective, or maybe even dependent on hardware architecture. What I'm really looking for are your takes on efficient, elegant and simple solutions. If possible, provide a short description of the pros and cons of your answer, or any other insights which you think might prove useful.
Also, feel free to change how the interrupts work. If it is more suitable to only have one interrupt that fires at each clock edge of either encoder A or B, or maybe if you prefer 4 interrupts (one per edge, per channel), go for it. Just make sure it's obvious.
Also, just to make it clear, this question is about a microcontroller implementation, not HDLs.
This question actually has a really nice solution to this problem. My take on this implementation will be in the answers.