Searching \ for '[EE] Rotary encoders: advanced decoding (skipping' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: massmind.org/techref/io/sensors.htm?key=encoder
Search entire site for: 'Rotary encoders: advanced decoding (skipping'.

Exact match. Not showing close matches.
PICList Thread
'[EE] Rotary encoders: advanced decoding (skipping '
2007\01\18@150014 by M. Adam Davis

face picon face
It occurred to me while I wrote up my latest rotary encoder decoding
routine that one could do a small amount of error correction as well.
I wanted to see if anyone had run into such an attempt before, and had
any advice or thoughts regarding it.

This is concerning a normal rotary encoder with gray encoding - one
output is 90 degrees out pf phase from the other, and only one bit
changes at a time:
A B
0  0
0  1
1  1
1  0
0  0

My current method takes the previous state (two bits) and the new
state (two bits) and concatenates them into a four bit number.  I then
use a 16 position RETLW table to return -1, 0, or 1 depending on the 4
bit number.

Encoder state byte:
0 0 0 0 Aold Bold Anew Bnew

This works great, and is very quick.  My particular method holds the
old state in an 8 bit variable, and simply shifts it over two bits
when a new state is ready, then chops off the top four bits.

It occurred to me, though, that if I didn't chop off the top four bits
(which are the results of the last two states, or in others words I
have three old states and the new state in one 8 bit block) then I
could use that history to determine the direction the encoder was
going when it skipped bits.

If the four samples were
A B
0  0 (oldest state)
0  1 (older state)
1  1 (last state)
0  0  (newest state)

Then this last state change from 1  1 to 0  0 could be counted as 2,
rather than thrown away as an illegal change.  This would take a 64 or
256 entry table, rather than 16 entries, but it would be just as fast.
Faster, even, since I wouldn't have to clear the top four bits every
time I got a new sample.

Of course, I've done the calculations and this shouldn't occur (ie,
I'm polling them faster than they should change - no interrupts at the
moment), but I'd like to be able to lower the processor speed and the
overhead of the polling routine as much as possible.

I don't see any obvious problems, but I imagine this is not a new idea
and there must be a reason why I haven't seen it discussed before.  I
can see why this wouldn't be on hardware decoders (event driven state
machine, not polling - usually with glitch suppression), and very fast
interrupt driven routines might never need it.

-Adam

--
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
Moving in southeast Michigan? Buy my house: http://ubasics.com/house/

Interested in electronics? Check out the projects at http://ubasics.com

Building your own house? Check out http://ubasics.com/home/

2007\01\18@165314 by Dave Wheeler

flavicon
face
Hi Adam,

I have been working on a similar problem. My main problem is 'noisy'
encoders so I was working on a predictive idea but am ending up in a mess.
Would be very interested to see your full routine

TIA

Dave


M. Adam Davis wrote:
{Quote hidden}

2007\01\18@173101 by Harold Hallikainen

face
flavicon
face
This sounds a lot like the approach at
http://www.piclist.org/techref/microchip/qenc.htm , which I've used. It
works great!

Harold

{Quote hidden}

> -

2007\01\18@181003 by James Newtons Massmind

face picon face

> If the four samples were
> A B
> 0  0 (oldest state)
> 0  1 (older state)
> 1  1 (last state)
> 0  0  (newest state)
>
> Then this last state change from 1  1 to 0  0 could be
> counted as 2, rather than thrown away as an illegal change.  
> This would take a 64 or
> 256 entry table, rather than 16 entries, but it would be just as fast.
>  Faster, even, since I wouldn't have to clear the top four
> bits every time I got a new sample.

You could also record the direction as a simple 0 or one in the 5th bit
(over the top of the "older state" lsb) and then use a 32 entry table. Your
example above would become

A B
x  1 (oldest direction)
x  1 (older direction)
1  1 (last state)
0  0  (newest state)

Or you could use a 16 entry table which returns an "invalid" value. When
"invalid" is returned, it causes the direction bit to be used to load a 2 or
-2 as appropriate. If you pick the invalid value to be 2 then a bit test and
negate are all that is required.

Actually...

EncWait:
       mov w,Enc                ;Port "Enc" 2 lsb's = encoder pins
       and w,#%00000011  ;get rid of all but 2 enc bits
       mov temp,w                ;save the new reading
       xor w, old                ;compare it to the old
       snz                        ;Any change?
        jp EncWait          ; if not, go back and wait
       xor w,#%00000011
       snz
        jp EncErr                ;
;Table? TABLE!?!? We don't need no stinken table!
       clc                        ;get ready for right shift
       rl  old                ;align bits
       xor old,temp        ;check for direction and save new with old
EncCount
       jb  old.1,EncUp        ;The second to lsb: 1=up direction, 0=down
EncDown:
       dec Pos                ;we be going down: -1
       ret                        ;return so action is taken
EncUp:
       inc Pos                ;we be mov'n on up: +1
     ret                        ;return so our caller can take action
Err:
       call EncCount        ;just leave the direction as is and take action
       jp EncCount                ;  ...twice

Sorry, parallax mnemonics. Based on code from Matthew Ballinger at
http://www.piclist.com/techref/microchip/qenc.htm

Old        Enc        old'
0000        0 0        0000
0000        0 1        0001
0001        1 1        0001        ;note: old was rotated left before xor
0001        0 0        0001
0001        0 0   0000        ;note: old.0 zeros out on first no change.
0001  1 0        0010        
0010  1 1        0111        


Old.1 (the lsb of Old) holds the direction at all times. The rotating old
left one bit and xoring with the new encoder reading is weird, but just
happens to work. (I'm pretty sure)

---
James.


2007\01\19@122641 by Álvaro Deibe Díaz

picon face
I posted a solution to the encoder problem some time ago
(www.piclist.org/techref/postbot.asp?by=thread&id=%25quadrature%25en
code%25). This solution seems very simmilar to the one you use, but do not
need the ROM table.

It uses the (two) bits from the previous encoder state and the (two) new
state bits, and do a "cross-XOR" between them (normal XOR, but with the
previous two bits interchanged). The result are two bits. If one of them is
"1", then rotate left. If the other is "1" then rotate right. If both are
"0", no change. If both are "1", this is your skipping situation. Easy to
detect. Easy to follow. Without table.

I can try to translate the (original) Spanish comments in the code (see,
this post is from 1998, the PIC was a 16C54, and I was not using C or other
fancy programming language):

#define encx   PORTA,1    ; Encoder is in PORTA,
#define ency   PORTA,2    ; pins 1 and 2, i.e.
;
; Encoder reading routine (only here for readability).
      clrf    auxint     ; Clears the aux byte,
      btfsc   encx       ; and "put" in it both of the
      bsf     auxint,0   ; bits of the new encoder
      btfsc   ency       ; state ('x' and 'x')
      bsf     auxint,1   ; (this part can clearly be done better)
;
; Variable 'encod' has in its two LSB the previus encoder state. Cross-XOR
is done:
      movf    auxint,W   ; XOR is done between previous
      xorwf   encod,F    ; and new encoder state
                         ; (note auxint only uses the (two) LSB)
;
; Using rotations, the order of the new encoder state bits is reversed
; and stored in encod, to be used in the next iteration...
      rrf     auxint,F   ; I think this part is obvious...
      rlf     encod,F
      rrf     auxint,F
      rlf     encod,F
;
; Work done.
; Put here your motion detection routine. A simple example could be:
      btfsc   encod,2    ; Movement in "x" direction...
      incf    posenc,F   ; ('posenc' holds the position information)
      btfsc   encod,3    ; ...or in 'y' direction...
      decf    posenc,F

In previous posts of the encoder problem, I had no response to this routine
from the list, so I don't know if anybody used it. I did, and with success.

Regards,

Álvaro Deibe Díaz.

{Quote hidden}

>

2007\01\19@124736 by M. Adam Davis

face picon face
I'll have to take a closer look at this one later, I did read it in
the techref and was intrigued.

It appears to take 15 instruction cycles.  I suspect a jump table
takes more space, but should take less time.  Of course, I see that
your routine can be optimized further depending on the particular
requirements.

Thanks for posting a translation, I wasn't looking forward to decoding
the routine without clues.  :-)

-Adam

On 1/19/07, Álvaro Deibe Díaz <adeibespamKILLspamudc.es> wrote:
{Quote hidden}

> > --

2007\01\19@133957 by Marcel Birthelmer

picon face
I have a semi-related question for all youse guys. Where do you get
the rotary encoders? I've tried a few online stores, and most of them
have a very limited selection (digikey: 2, newark: 2). Am I just not
using the right search terms?
Thanks,
- Marcel

2007\01\19@140126 by M. Adam Davis

face picon face
Try
http://catalog.digikey.com/scripts/partsearch.dll?PV=65880

Use the term "encoder" or "encoders" instead of "rotary encoders".

I'm using the new AMT series from CUI, but I've used the little
encoders meant for user interfacing with knobs as well.  They have a
pretty good selection.

I usually refer to the catalog when I'm after something I can't find,
then I look up a representative product online and find out what
category they're filed in, then go to that category.  Some places put
them under switches, some put them under sensors, others put them
elsewhere, and a few places separate the encoders into motor mountable
vs human interface vs etc, so you can't see them all at once.

-Adam

On 1/19/07, Marcel Birthelmer <marcelb.listsspamspam_OUTgmail.com> wrote:
> I have a semi-related question for all youse guys. Where do you get
> the rotary encoders? I've tried a few online stores, and most of them
> have a very limited selection (digikey: 2, newark: 2). Am I just not
> using the right search terms?
> Thanks,
> - Marcel
> -

2007\01\19@170456 by Bob Axtell

face picon face
Marcel Birthelmer wrote:
> I have a semi-related question for all youse guys. Where do you get
> the rotary encoders? I've tried a few online stores, and most of them
> have a very limited selection (digikey: 2, newark: 2). Am I just not
> using the right search terms?
> Thanks,
> - Marcel
>  
Lookup Baldwin Electronics. They make the best encoders in the world.

--Bob

2007\01\19@172155 by M. Adam Davis

face picon face
Now http://www.bei-tech.com/

Interesting back story on the company found here:
http://www.answers.com/topic/bei-technologies-inc

-Adam

On 1/19/07, Bob Axtell <@spam@engineerKILLspamspamneomailbox.com> wrote:
> Marcel Birthelmer wrote:
> > I have a semi-related question for all youse guys. Where do you get
> > the rotary encoders?
> >
> Lookup Baldwin Electronics. They make the best encoders in the world.
> --Bob
--
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
Moving in southeast Michigan? Buy my house: http://ubasics.com/house/

Interested in electronics? Check out the projects at http://ubasics.com

Building your own house? Check out http://ubasics.com/home/

More... (looser matching)
- Last day of these posts
- In 2007 , 2008 only
- Today
- New search...