1
\$\begingroup\$

I have a quadrature encoder with an index pulse, and I would like to keep track of angular position over multiple turns. The microcontroller I am using has counters that count both index pulses (revolutions) and phase edges. Each time an index pulse is seen, the revolution counter is incremented (or decremented if going in reverse) and the edge counter is reset to zero.

Everything works fine for a normal 'clean' transition through the index pulse. However, if I am unlucky and the direction changes during an index pulse, then the counter that tracks revolutions (i.e. counts index pulse edges) becomes incorrect. It increments the revolution count at the rising edge of the index, but does not decrement it at the falling edge (which corresponds with the same physical position as the rising edge). The result is that the revolution counter is one count higher than it should be.

Is it common to use encoders with an index pulse to track multiple turns? What can be done to avoid this problem?

I am considering using only the first index pulse to reset the edge counter, and then ignoring all subsequent index pulses (just allow phase edges to accumulate instead). The downside is that without the index pulse to reset counts, the accumulated counts may drift over time if used for long periods with occasional missed pulses.

\$\endgroup\$
  • \$\begingroup\$ You did not say how much control you have because you can implement an index reset using interrupts instead of through the counter. It's not as tight but you have a lot more control if your MCU is lacking somehow. \$\endgroup\$ – DKNguyen Aug 7 at 1:55
  • \$\begingroup\$ I do have the ability to handle some of the logic in interrupts. For example, I can maintain a rotations_offset variable which is added to the rotation measurement from the counter and is used to correct for this issue. I would need to be able to detect when the error has occurred and increment/decrement rotations_offset accordingly. Interrupts are available for direction change and index pulse. \$\endgroup\$ – knick Aug 7 at 2:20
1
\$\begingroup\$

The proposal in your last paragraph is a good and common way to handle this. For increased robustness, you can detect index pulses after the first and compare them to the accumulated location, modulo one full revolution. If they don't match to within the ambiguity of one quadrature count, you have a couple of options for how to respond. I would start by simply throwing some kind of alarm, so that after some duration of testing you'll be able to decide whether or not you actually do ever get periods of missed quadrature pulses. If it turns out you do, you can do a little math to have it snap the accumulated position to the nearest integer number of revolutions.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I went with this solution in the end. It is simple, and doesn't require a lot of software overhead. \$\endgroup\$ – knick Aug 8 at 11:58
1
\$\begingroup\$

It sounds like your index reset is happening in hardware and you can't control what edge(s) to trigger on. You could always move it out into a software interrupt instead.

A concept I ran into only after programming quad encoders for FPGAs and STM32s (they have a A-B counter but the index and all the nitty gritty features must be done in software with interrupts), was found in the dsPIC hardware Quadrature Encoder Interface:

enter image description here http://ww1.microchip.com/downloads/en/DeviceDoc/70000601c.pdf

The feature is called "Index Match" although most of the time it is referred to simply as "match" in the document so don't try and only search "Index Match" or you will miss the bulk of the important material.

Basically, it does not responds to an index pulse alone. It only responds to the index pulse when when the A and B channels are a particular state. It uses this so that the exact same point is used for a reset regardless of the direction you are approaching the index pulse from.

You can manually select ahead of time what you want the A and B states to be, or record them when the first index pulse is received. The catch with this is that it is a lot easier to implement in hardware than in software since (I think) the optimal way is to search for the correct A-B state while the index pulse is the appropriate level. That's super easy to do in hardware but would bog down your processor in software.

In software it's much less expensive to use interrupts but those are edge triggered. Obviously, the bad way to do it is to furiously hunt for the proper A-B state while the index is active, and the worst way is to furiously hunt for the index whenever the the A-B state is correct. You could perhaps have an edge-triggered interrupt on the index pulse that disables itself after enabling an edge-triggered interrupt on the A and/or B channels to check the A-B state. Then after it finds it, it can disable itself and re-enable the index interrupt.


Alternatively, you could set the index interrupt to trigger on both rising and falling edges, inside the interrupt, only reset the counter if the type of edge matches the direction of rotation (there would be two valid combinations, and the other two would be rejected). That would effectively turn your index pulse into an index-edge. Sounds like a lot less work than what I described above.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks for the detailed response. I can see some merits to the first solution you describe. It helps to narrow down where the count gets reset within the index pulse. Without it (i.e. resetting on the rising edge of the index pulse) the 'zero' position will shift a little depending on which direction you are travelling. However, I can't see how it will help with the reversal problem I am encountering. If the direction were to invert the instant after the QEI interrupt, it seems that there wouldn't be a second QEI interrupt generated immediately after to drop the revolution count back down? \$\endgroup\$ – knick Aug 7 at 3:14
  • \$\begingroup\$ Your second solution (selecting index edge based on rotation) sounds like it would solve the reversal issue. But it might also increase the shift in the zero position between forwards and backwards travel? \$\endgroup\$ – knick Aug 7 at 3:16
  • \$\begingroup\$ @knick I don't understand what you mean about the second solution. There's already uncertainty since you are measuring analog distance with discrete steps. But the second solution treats an edge no matter what direction you are coming from, so I don't follow how it would increase the distance back to itself in one direction over the other. \$\endgroup\$ – DKNguyen Aug 7 at 3:18
  • \$\begingroup\$ I don't think it would be a problem with the first solution since its level sensitive. I think the uncertainty is still 1/2 a pulse which is the uncertainty you have anyways since you are measuring analog angles with discrete counts. \$\endgroup\$ – DKNguyen Aug 7 at 3:22
  • \$\begingroup\$ There are 3 phase edges that fall within an index pulse. I was thinking that if you flip the edge of the index pulse that you start counting from then there could be a discrepancy of 3 counts between counting up and counting down (assuming every edge is being counted, i.e. 4x resolution). I need to think more about this to get my head around it. \$\endgroup\$ – knick Aug 7 at 3:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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