EmbeddedRelated.com
Forums

Rotary encoder interfacing to a micro

Started by Colin MacDougall April 18, 2004
Hello,

I am trying to connect an ALPS two phase mechanical encoder to
a small micro ( AVR 90s2313 ). I can get it to work pretty much
how I want - at the moment it causes a row of eight LED's to
run back and forth. The problem I come across is that turning
the shaft to the next detent position sometimes causes the LED's
to double count. Looking at the output from the encoder on a scope
reveals a bit of noise on the outputs. I have set my micro to
interrupt on a falling edge of one of the phases and tried using
a 7 mS software timer but this does not totally cure the problem.
Does anyone have some tips for using these devices ? Is it usual to
hook the outputs straight on to a micro or should a Schmitt trigger
or similar be used first ? I have thought about using a 'best of three'
approach where the phase is sampled three times and a decision made
if all three results are the same.

TIA

Colin


"Colin MacDougall" <colin |D0T| macdougall@btinternet.com> wrote:

>Hello, > >I am trying to connect an ALPS two phase mechanical encoder to >a small micro ( AVR 90s2313 ). I can get it to work pretty much >how I want - at the moment it causes a row of eight LED's to >run back and forth. The problem I come across is that turning >the shaft to the next detent position sometimes causes the LED's >to double count.
If is not possible to track an incremental encoder while only checking its state on one edge of one channel. You can not tell if the edge was generated by the encoder advancing through a whole cycle or just reversing slightly and advancing through the edge again. For a low speed application a simple way of tracking is to sample the channels in a regular timer interrupt. The current state of the channels combined with their state on the previous sample gives 16 cases. Of these 2 * 4 indicate movement in either direction, 4 indicate no movement and the remaining 4 should be impossible. This scheme is pretty simple to code.
On Sunday, in article
     <xHDgc.9$6T5.8@news-binary.blueyonder.co.uk>
     colin|D0T|macdougall@btinternet.com "Colin MacDougall"
     wrote:
>Hello, > >I am trying to connect an ALPS two phase mechanical encoder to >a small micro ( AVR 90s2313 ). I can get it to work pretty much >how I want - at the moment it causes a row of eight LED's to >run back and forth. The problem I come across is that turning >the shaft to the next detent position sometimes causes the LED's >to double count. Looking at the output from the encoder on a scope >reveals a bit of noise on the outputs. I have set my micro to >interrupt on a falling edge of one of the phases and tried using >a 7 mS software timer but this does not totally cure the problem. >Does anyone have some tips for using these devices ? Is it usual to >hook the outputs straight on to a micro or should a Schmitt trigger >or similar be used first ? I have thought about using a 'best of three' >approach where the phase is sampled three times and a decision made >if all three results are the same.
Both approaches sound good as you seem to be using a encoder that is a switch that will have switch bounce so using the timer to do several successive readings to check for several identical readings before using it would be good. This of course depends on how much processing time you have available. I assume this an 8 bit o/p encoder, so if adding external chips you might consider putting some form of debouncer chip to alleviate your software overhead if that is important. A typical one to use could be the Maxim MAX6818, which also has internal pull-up resistors. -- Paul Carpenter | paul@pcserv.demon.co.uk <http://www.pcserv.demon.co.uk/> Main Site <http://www.gnuh8.org.uk/> GNU H8 & mailing list info. <http://www.badweb.org.uk/> For those web sites you hate.
On Sun, 18 Apr 2004 23:55:34 +0100, "Colin MacDougall" <colin |D0T|
macdougall@btinternet.com> wrote in comp.arch.embedded:

> Hello, > > I am trying to connect an ALPS two phase mechanical encoder to > a small micro ( AVR 90s2313 ). I can get it to work pretty much > how I want - at the moment it causes a row of eight LED's to > run back and forth. The problem I come across is that turning > the shaft to the next detent position sometimes causes the LED's > to double count. Looking at the output from the encoder on a scope > reveals a bit of noise on the outputs. I have set my micro to > interrupt on a falling edge of one of the phases and tried using > a 7 mS software timer but this does not totally cure the problem. > Does anyone have some tips for using these devices ? Is it usual to > hook the outputs straight on to a micro or should a Schmitt trigger > or similar be used first ? I have thought about using a 'best of three' > approach where the phase is sampled three times and a decision made > if all three results are the same. > > TIA > > Colin
As others have already said, to get true quadrature decoding (speed and direction) you need to look at least at both edges of one pulse. A lot depends on the speed with which the encoder pulse train comes. About 10 years ago I did a project for a special type of printer. The pin feed paper was driven by an AC motor and tracked by an encoder, approximately 4000 quadrature edges per second. A step motor had to be controlled by a state machine to synchronize to the paper in various complicated ways. We did this with an 8051 running at 12 MHz. The quadrature inputs were connected each connected to one input of an exclusive-or gate, the other input to each exclusive-or gate was connected to a separate port pin, and the outputs of the two gates were connected to the two external interrupt lines of the chip. When one phase changed state, it generated the corresponding interrupt. The ISR read the input a few times to make sure it was stable. Then, based on the direction of the change and the state of the other phase, it generated an up or down count to the position counter. Finally it toggled the output port pin driving the other input to the exclusive-or gate to clear the interrupt input until that phase changed state again. Again as others have pointed out, if you need high speed encoder tracking, there are dedicated chips. US Digital and Agilent (formerly Hewlett Packard) are some sources. -- Jack Klein Home: http://JK-Technology.Com FAQs for comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html comp.lang.c++ http://www.parashift.com/c++-faq-lite/ alt.comp.lang.learn.c-c++ http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
In comp.arch.embedded, "Colin MacDougall" <colin |D0T|
macdougall@btinternet.com> wrote:

>Hello, > >I am trying to connect an ALPS two phase mechanical encoder to >a small micro ( AVR 90s2313 ). I can get it to work pretty much >how I want - at the moment it causes a row of eight LED's to >run back and forth. The problem I come across is that turning >the shaft to the next detent position sometimes causes the LED's >to double count. Looking at the output from the encoder on a scope >reveals a bit of noise on the outputs. I have set my micro to >interrupt on a falling edge of one of the phases and tried using >a 7 mS software timer but this does not totally cure the problem. >Does anyone have some tips for using these devices ? Is it usual to >hook the outputs straight on to a micro or should a Schmitt trigger >or similar be used first ?
If there's some the micro can't devote a few extra cycles to debouncing, then you should perhaps add extra hardware (or look into raising the clock speed!), but a good software-only debounce works fine for me.
>I have thought about using a 'best of three' >approach where the phase is sampled three times and a decision made >if all three results are the same.
I do something similar. I've gotten a mechanical encoder to work quite reliably, with switches directly into the microcontroller port pins, with the chip's internal pullups enabled (no external resistors or capacitors). I read the two lines inside a once-every-1-mS timer interrupt, and read it each time for ten times through (giving an 'actual switch value' every 10mS). Since the switch goes to ground and the internal pullup goes to VCC, the switch 'on' is read as a zero. I initialize a buffer to all 1's and do an 'and' of each reading with the buffer so that if a bit value is zero (switch on) during any of those reads, I presume the switch is on (and all the other 1 readings were due to a scratchy switch - if the switch contacts are nowhere near each other, then ALL readings of it will be 1, correctly indicating switch off). At the end of the tenth reading I pass this off as The Encoder Value, then reinit the buffer and counter. I had looked at the switch output with a scope, both turning slowly (to see any noise, as well as the rise time of the pullups) and quickly (to see how fast the quadrature signals might reasonably change at maximum hand-turning speed), so this code is the result of Deliberate Research into Cheap Mechanical Rotary Encoders (these are made by Panasonic, digikey part# P10859-ND). It's AVR 90S1200 assembly code, I wrote it on my own time, as opposed to being paid to do it, so I have full rights to the code. If someone asks nicely I coould put the whole thing online, I might even add some [more!] documentation to it.
>TIA > >Colin
On Sun, 18 Apr 2004 23:55:34 +0100, the renowned "Colin MacDougall"
<colin |D0T| macdougall@btinternet.com> wrote:

>Hello, > >I am trying to connect an ALPS two phase mechanical encoder to >a small micro ( AVR 90s2313 ). I can get it to work pretty much >how I want - at the moment it causes a row of eight LED's to >run back and forth. The problem I come across is that turning >the shaft to the next detent position sometimes causes the LED's >to double count. Looking at the output from the encoder on a scope >reveals a bit of noise on the outputs. I have set my micro to >interrupt on a falling edge of one of the phases and tried using >a 7 mS software timer but this does not totally cure the problem. >Does anyone have some tips for using these devices ? Is it usual to >hook the outputs straight on to a micro or should a Schmitt trigger >or similar be used first ? I have thought about using a 'best of three' >approach where the phase is sampled three times and a decision made >if all three results are the same.
Sample both inputs @~400Hz and debounce (store previous reading and accepted reading) to get rid of the rated contact bounce (usually something like 5msec). You can then determine up/down/ignore from the transition of states. It's possible to get illegal states if the knob is turned too fast, in which case you are best to just ignore. Note also that one input may be guaranteed stable at the detent, wheras the other may not. Here's the encoders we have, which are probably similar to the ones you have: http://www.trexon.com/pdfs/trexon_encoder_revA. Best regards, Spehro Pefhany -- "it's the network..." "The Journey is the reward" speff@interlog.com Info for manufacturers: http://www.trexon.com Embedded software/hardware/analog Info for designers: http://www.speff.com
You should make a sampling rate that is fast enough for your encoder,
lets say 10ms or something like that, and when you detect that current
state is "0", and previous state was "1" then you have a negative edge.

Mickey

> I am trying to connect an ALPS two phase mechanical encoder to > a small micro ( AVR 90s2313 ). I can get it to work pretty much > how I want - at the moment it causes a row of eight LED's to > run back and forth. The problem I come across is that turning > the shaft to the next detent position sometimes causes the LED's > to double count. Looking at the output from the encoder on a scope > reveals a bit of noise on the outputs. I have set my micro to > interrupt on a falling edge of one of the phases and tried using > a 7 mS software timer but this does not totally cure the problem. > Does anyone have some tips for using these devices ? Is it usual to > hook the outputs straight on to a micro or should a Schmitt trigger > or similar be used first ? I have thought about using a 'best of three' > approach where the phase is sampled three times and a decision made > if all three results are the same.
On Sun, 18 Apr 2004 23:55:34 +0100, "Colin MacDougall" <colin |D0T|
macdougall@btinternet.com> wrote:

>Hello, > >I am trying to connect an ALPS two phase mechanical encoder to >a small micro ( AVR 90s2313 )....
A few months ago I posted about this schematic: http://www.tunelab-world.com/decode.gif It converts quadrature into up-counts and down-counts. If your micro has two counters that each can count external edges, then the quadrature position count can be calculated at any time by subtracting the two counters. The only problem becomes how to read often enough to handle overflow and how to read two counters on the fly while one or both of them may be counting. I solved the second problem by reading both counters twice and checking that the readings didn't change. For fast enough quadrate, this may need to be refined. -Robert Scott Ypsilanti, Michigan (Reply through this forum, not by direct e-mail to me, as automatic reply address is fake.)
That link appears to be dead.

On Mon, 19 Apr 2004 09:02:53 -0400, the renowned Joe Legris
<jalegris@xympatico.ca> wrote:

>That link appears to be dead.
Sorry, it should be: http://www.trexon.com/pdfs/trexon_encoder_revA.pdf Best regards, Spehro Pefhany -- "it's the network..." "The Journey is the reward" speff@interlog.com Info for manufacturers: http://www.trexon.com Embedded software/hardware/analog Info for designers: http://www.speff.com