1
\$\begingroup\$

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

\$\endgroup\$
3
  • \$\begingroup\$ You will want to define a, v, x targets or contact limits and use current feedback for g and RPM for v so you have a well-controlled motor. \$\endgroup\$
    – D.A.S.
    Commented Jan 23, 2021 at 22:27
  • 1
    \$\begingroup\$ It's actually a little tricky to make the position sensing perfect (no loss of position information under any circumstances), without dedicated hardware, whether on-chip or not. I can't think of any reason not to use interrupts however. You would need to trigger on both lines, maybe both edges too. \$\endgroup\$
    – Pete W
    Commented Jan 24, 2021 at 2:21
  • \$\begingroup\$ First thing to consider here is EMC and noise, how much of that you expect and how you plan to deal with it. If software filters are part of the solution, then interrupts won't work well, in case you get interrupts triggered on spikes. \$\endgroup\$
    – Lundin
    Commented Jan 25, 2021 at 11:54

2 Answers 2

2
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks, this is very helpful. It is my first time with such encoder, I did not even think about QEI, nor did the one who designed the thing I guess, so thank you. \$\endgroup\$ Commented Jan 23, 2021 at 22:36
1
\$\begingroup\$

You should first calculate the error that each method would produce. There is so called frequency measurement and period measurement. Some MCUs have built-in a special unit QEP, QEI,.(manufacturer specific names) that switch form these two methods to give best results.

  1. frequency measurement: Within a fixed period of time you measure the incoming pulses. The relative measurement error is \$\varepsilon = \pm \dfrac{1}{N}\$, where N is the number of counted pulses

  2. period measurement: A measured signal is used to start/stop counting an internal clock generated pulses. The relative measurement error is \$\varepsilon = \pm \dfrac{1}{N}\$ where N is the number of counted pulses.

The clever way of solving the problem would compromise of using both methods and then compare the relative error, then switch the method of measuring with regard of the lower error. Alternatively you could compute these errors based with known input measurement signal frequency and 1st fixed measuring time, and 2nd fixed internal clock generator frequency. You do choose which method gives the lower error.

For high frequency measurement the method 1. is more suitable, for low frequency measurement the 2. method is more suitable.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.