EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Rotary encoder interfacing to a micro

Started by Colin MacDougall April 18, 2004
> I have set my micro to >interrupt on a falling edge of one of the phases
If you want to use interupts then you need to use both edges of one channel or use the falling (or rising) edges of both channels. For low speed work polling would work, for high speed you should consider a processor with an onboard up/down counter.
> It converts quadrature into up-counts and down-counts. If your micro > has two counters that each can count external edges, then the
IMHO the simple hardware counter is not a good solution unless you have hardware debouncing of the switch inputs. BTW, you can do it more simply with a counter that has a direction input - connect one quad output to the counter's clock and the other to the direction input. IN THEORY, if everything is debounced perfectly, the state of B at an edge on A is high for one direction, or low for the other. In practice, these switches - at least the hand-operated ones like the Matsushita EVQ series - are horribly bouncy and have dead zones around the detents. If you want to do it with the minimum hardware, use two GPIOs and have an ISR that maintains a history of state-changes on the GPIOs. A falling edge on A followed by a falling edge on B with no intervening rising edge on A is a count in (say) the + direction. A falling edge on B followed by a falling edge on A with no intervening rising edge on B is a count in the other direction. Any other sequence of state-changes is ignored. I used this method in a low-speed polled interrupt handler for a thumbwheel (front panel) type encoder and it worked very well. I was constrained by evil factors - no interruptible GPIOs and my ISR couldn't run faster than approximately once every 50ms. But the end result was very good <http://www.digi-frame.com/df560.html> (out of production for a couple of years, so I'm absolved from any charge of shilling :).
On 19 Apr 2004 17:35:21 -0700, larwe@larwe.com (Lewin A.R.W. Edwards)
wrote:

>> It converts quadrature into up-counts and down-counts. If your micro >> has two counters that each can count external edges, then the > >IMHO the simple hardware counter is not a good solution unless you >have hardware debouncing of the switch inputs.
In my schematic, the synchronization shift register on the input ensures that all "bounces" are either recognized as full pulses or not recognized at all. If they are recognized as full pulses, they will result in both an up-count and a down-count. In either case, the difference between the two counters will always represent the correct count. No other debouncing is necessary.
> BTW, you can do it more >simply with a counter that has a direction input -
Perhaps. But I was designing toward the kind of counters built-in to common micros. Those counters do not have direction inputs.
>If you want to do it with the minimum hardware, use two GPIOs and have >an ISR that maintains a history of state-changes on the GPIOs. A >falling edge on A followed by a falling edge on B with no intervening >rising edge on A is a count in (say) the + direction. A falling edge >on B followed by a falling edge on A with no intervening rising edge >on B is a count in the other direction. Any other sequence of >state-changes is ignored.
This can work fine for low encoders speeds. You just have to see what the worst-case time is between ISRs and make sure that time is less than the shortest possible time between a transition on the A-phase and a transition on the B-phase. The software solution may work fine for manually-operated dials. But all the applications I see are in industrial machine control where the encoder is on some shaft turned by a motor. 500 nsec. pulse times are not uncommon. -Robert Scott Ypsilanti, Michigan (Reply through this forum, not by direct e-mail to me, as automatic reply address is fake.)
In comp.arch.embedded, no-one@dont-mail-me.com (Robert Scott) wrote:

>On 19 Apr 2004 17:35:21 -0700, larwe@larwe.com (Lewin A.R.W. Edwards) >wrote: > >>> It converts quadrature into up-counts and down-counts. If your micro >>> has two counters that each can count external edges, then the >> >>IMHO the simple hardware counter is not a good solution unless you >>have hardware debouncing of the switch inputs. > >In my schematic, the synchronization shift register on the input >ensures that all "bounces" are either recognized as full pulses or not >recognized at all. If they are recognized as full pulses, they will >result in both an up-count and a down-count. In either case, the >difference between the two counters will always represent the correct >count. No other debouncing is necessary. > >> BTW, you can do it more >>simply with a counter that has a direction input - > >Perhaps. But I was designing toward the kind of counters built-in to >common micros. Those counters do not have direction inputs. > >>If you want to do it with the minimum hardware, use two GPIOs and have >>an ISR that maintains a history of state-changes on the GPIOs. A >>falling edge on A followed by a falling edge on B with no intervening >>rising edge on A is a count in (say) the + direction. A falling edge >>on B followed by a falling edge on A with no intervening rising edge >>on B is a count in the other direction. Any other sequence of >>state-changes is ignored.
A problem with this scheme is the encoder can be 'teased' by moving it halfway off of a detent then back, causing the falling-A-falling-B sequence, causing a count increase, without the corresponging falling-B-falling-A sequence to give a corresponding count decrease. It may not be that big a deal to some people or in some apps, but I consider it a 'bug' in the interface. I decode the whole sequence (after the debouncing in my earlier post), as described by nospam@nospam.invalid. I shift the previous state two bits to the left, or in the current state, and use this four-bit value in a lookup table with four values, meaning: do nothing, decrement count, increment count, error (I increment an error count for debugging/performance measurement). This causes a count change of four for every detent. When the sequence goes to the detent value, I give the app the count divided by four. This causes a change as the encoder falls into the detent in either direction, so it has a good 'feel' (like an old TV tuner, the value changes when it 'clicks') and it can't be teased. There's this article: http://www.circuitcellar.com/library/print/0303/millier152/index.htm that talks about partial decoding for encoders with detents and mentions 'teasing' with encoders without detents. I really think full decoding is the right thing to do regardless.
>This can work fine for low encoders speeds. You just have to see what >the worst-case time is between ISRs and make sure that time is less >than the shortest possible time between a transition on the A-phase >and a transition on the B-phase. The software solution may work fine >for manually-operated dials.
It does...
>But all the applications I see are in >industrial machine control where the encoder is on some shaft turned >by a motor. 500 nsec. pulse times are not uncommon.
That kind of application is 'in principle' the same function of quadrature decoding, but in practice is quite different - it obviously demands hardware (or a very fast processor). Also, such high speed encoders invariably use optical detection (or some other non-contact method), so there's no need for debouncing. Optical encoders are available for front-panel applications, but they're rather expensive and used in scopes and logic analyzers, where engineers with five thumbs on each hand would easily break the shaft of a cheap encoder. I've been frustrated that I haven't found an optical encoder in the under-five-dollar range when for years computer mouses were sold in that price range which had TWO encoders in it.
>-Robert Scott > Ypsilanti, Michigan >(Reply through this forum, not by direct e-mail to me, as automatic reply address is fake.)
On Tue, 20 Apr 2004 12:40:47 -0400, Ben Bradley
<ben_nospam_bradley@mindspring.example.com> wrote:

>..Also, such high speed >encoders invariably use optical detection (or some other non-contact >method), so there's no need for debouncing...
Actually, there is. The same "teasing" that you talked about earlier can happen with an optical encoder when it is coupled with a motion that is periodically changing direction. At the point where the direction changes, you can get signals just as jumpy as with a contact encoder. The shift register method that I use in hardware and that you described in a software implementation acts as adequate debouncing. -Robert Scott Ypsilanti, Michigan (Reply through this forum, not by direct e-mail to me, as automatic reply address is fake.)
Ben Bradley <ben_nospam_bradley@mindspring.example.com> wrote in message news:<area80his0nmae1thj5dcug6ecdt0asn7n@4ax.com>...

> >>falling edge on A followed by a falling edge on B with no intervening > >>rising edge on A is a count in (say) the + direction. A falling edge > > A problem with this scheme is the encoder can be 'teased' by moving > it halfway off of a detent then back, causing the falling-A-falling-B > sequence, causing a count increase, without the corresponging > falling-B-falling-A sequence to give a corresponding count decrease.
Is that a problem in my scheme (requoted above) or in Robert's Scheme O'Bafflingly Numerous Gates? I don't see how my system is susceptible to that problem, because tease-n-return will not lead to a valid abA or aBA sequence. I got so curious about this little issue that I spent a few minutes fiddling with my car stereo, and my wife's. They are probably geneologically close, because both are from Visteon (Ford vehicles). BOTH of them will either miss a count or count the wrong way if you tease-n-release to the original detent. Interestingly, if you turn the wheel *very* slowly from one detent to the next, my car's stereo will "wake up" and show "VOL +9" or whatever, but won't actually change the value - it recognizes that some activity is going on at the wheel, but can't work out what direction it's being turned in.
> of a cheap encoder. I've been frustrated that I haven't found an > optical encoder in the under-five-dollar range when for years computer > mouses were sold in that price range which had TWO encoders in it.
The EVQ-WK is about $0.80, but it's not convenient to mount it on a front panel (it's flat and bitty, has a "click" function as well as quadrature, and is designed to stick out of a corner of something).

The 2024 Embedded Online Conference