Electronic – Incremental encoder – polling or interrupts

cencoderpic

I took over a project including PIC18f25k80 microcontrollers and incremental encoders. Basically I just need to follow the position of the motor using the encoder, and drive a device to specific locations. I know that there are more methods to read an encoder and update the position. The motor does not turn fast at all, no high speeds are involved here.

If I were to develop the whole thing from scratch, I probably would hang one channel of the encoder to an interrupt pin on let's say port B, and in the ISR I would check for the state of the other pin. To me, this seems to be the cleanest solution, this method probably catches all position changes, correct me if I am wrong.

Another method would be to poll the 2 channels in the main loop. There is not much in the main loop, basically just adjusting the motor speed and direction based on the position, so at slow speeds, I guess that I would not miss position changes, but it bothers me, that it is still a possibility to miss changes in the encoder channels.

A third option could be to initialize a timer interrupt, and in that interrupt routine, I could check for the pin states. This interrupt could occure twice as fast as a state change would occur at the highest speed, so I guess I would not miss any changes with this method as well.

Now that being said, my question is as follows: which option should I chose?

As I said, I would go with the first one, the encoder channels are attached to RB4 and RB5, so I could just enable the interrupts on port B. But as far as I know, and this is where I am not sure, I can only enable the interrupt for the whole port B on a PIC18f25k80, and not for single pins. That means that all pins on port B would create an interrupt, not just the one I want. And not just the other channel of the encoder, but all of the pins on port B are attached to something, and I cannot change the layout, only the software. Do I see it right, that in this case this method is out, because all pins would cause an interrupt on port B and that would be too much overhead?

And the end of my question: if I see the above problem correctly, which method would you chose, polling of fixed timer interrupts? We are talking about 5 rotations per second tops.

Thanks for the answers in advance!

This is the encoder in question: https://www.power-tronic.com/wp-content/uploads/2019/11/Type-Magnetic-Incremental-2019-01-08.pdf

Best Answer

Now that being said, my question is as follows: which option should I chose?

Poll at "high" speeds where the poll has a likely chance of catching an event rather than being wasted, and interrupt at low speed. Both methods suck equally though.

A third option could be to initialize a timer interrupt, and in that interrupt routine, I could check for the pin states. This interrupt could occure twice as fast as a state change would occur at the highest speed, so I guess I would not miss any changes with this method as well.

No! No! Timer interrupt is pointless. You might as well just poll and not have the overhead of the interrupt context switch. You would just have to make your main loop tight, or insert multiple polling points in your main loop. If you are going to the trouble of interrupting, just interrupt off the directly GPIO.

If I were to develop the whole thing from scratch, I probably would hang one channel of the encoder to an interrupt pin on let's say port B, and in the ISR I would check for the state of the other pin. To me, this seems to be the cleanest solution, this method probably catches all position changes, correct me if I am wrong.

No, use a different PIC with a QEI. Might not be too late to switch for a code and pin compatible PIC.

EDIT: I actually looked at your encoder datasheet. Your encoder is super low res. I'm used to encoders with thousands of pulses per revolution. For you, go direct GPIO interrupts, no question.