Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Rotary Pulse Encoder input

Status
Not open for further replies.
Updated the code (now 35 instructions, 28 if you lop off all Testbit0 code for only detent based results) to permit both no-detent 'full' quad OR single detent, single pulse results.

thx mike!

Hi Ancel (Mosaic),

I just had a look at your updated code in the Quadrature Encoder Debounce in ASM thread in the Code Repository. May I ask if you're open to criticism/suggestions, either via PM or comments in that thread?

Cheerful regards, Mike
 
For newer PIC16F, wich have BRW instruction. Everything else the same:

Code:
movf PORTA,w        ; load readings from RA0 and RA1
andlw 0x03          ; remove all unneeded bits
xorwf LastSample,f  ; test if this sample is different from the last
movwf LastSample    ; store the new sample
skpz                ; if new sample is the same as old, check on debouncing
clrf DbCount        ; if samples are different, reset debouncing
incf DbCount        ; advance our debouncing counter
btfss DbCount,5     ; is debouncing complete? Change the bit number to suit the timing
retlw 0             ; debouncing is still rolling; return with nothing
lslf LastState      ; debouncing is done; start preparing for lookup
lslf LastState      ; shift the previous encoder state to bits 2&3
iorwf LastState,f   ; add the new state to bits 0&1
movf LastState,w    ; retrieve the old state
andlw 0x0f          ; remove unneeded bits
brw                 ; jump; if it doesn't get the direction right, swap 0xff and 0x01
retlw 0x00   ; 00->00
retlw 0x01   ; 00->01
retlw 0xff   ; 00->10
retlw 0x00   ; 00->11 error
retlw 0xff   ; 01->00
retlw 0x00   ; 01->01
retlw 0x00   ; 01->10 error
retlw 0x01   ; 01->11
retlw 0x01   ; 10->00
retlw 0x00   ; 10->01 error
retlw 0x00   ; 10->10
retlw 0xff   ; 10->11
retlw 0x00   ; 11->00 error
retlw 0xff   ; 11->01
retlw 0x01   ; 11->10
retlw 0x00   ; 11->11

Didn't try to compile it. Feel free to try.
 
I like the "table method" but I always thought it had a bit too much 'overhead'. Here's some notes I made several years ago about eliminating the table;

Code:
;
;  XOR 'old' and 'new' AB values and exclude readings with
;  a '00' (same) or '11' (skip) result.  XOR 'new' A or B
;  bit with opposite 'old' bit for direction (+1 or -1).
;
; old new                <-- dec     inc -->
;  AB AB                 ---         -------
;  00^00 = 00 (same)    A   |       |
;  00^01 = 01 (  -1)         -------
;  00^10 = 10 (  +1)     -------         ---
;  00^11 = 11 (skip)    B       |       |
;  01^00 = 01 (  +1)             -------
;  01^01 = 00 (same)      ^   ^   ^   ^   ^
;  01^10 = 11 (skip)      0   1   2   3   0
;  01^11 = 10 (  -1)
;  10^00 = 10 (  -1)
;  10^01 = 11 (skip)
;  10^10 = 00 (same)
;  10^11 = 01 (  +1)
;  11^00 = 11 (skip)
;  11^01 = 10 (  +1)
;  11^10 = 01 (  -1)
;  11^11 = 00 (same)
;

I wrote code for the concept but I'm not sure I ever tested it (code is same size as the 16 word table alone);

Code:
;
;  B on RB1, A on RB0
;
        movf    PORTB,W         ; get new AB
        andlw   0x03            ; only RB1 and RB0 bits
        xorwf   encold,W        ; any change?
        skpz                    ; no, skip, else
        xorlw   0x03            ; both changed?
        skpnz                   ; no, skip, else
        retlw   0               ; exit (same or skip)

        xorlw   0x03            ; restore new AB bits in WREG
        xorwf   encold,W        ;  "
        rrf     encold,F        ; encold.0 = old B bit
        xorwf   encold,F        ; encold.0 = new A ^ old B
        rrf     encold,F        ; put bit 0 (dir) into C
        movwf   encold          ; update encoder latch
        skpnc                   ; C = direction
        retlw   -1              ; return -1
        retlw   1               ; return +1

Food for thought... I suspect there may be smaller, faster, more elegant ways to do it...

Regards, Mike
 
Last edited:
Very good thinking Mike!!!

There's a little bug with encold left in the old state when both bits has changed, but this should never happen anyway.
 
Very good thinking Mike!!!

There's a little bug with encold left in the old state when both bits has changed, but this should never happen anyway.

Where is the error, please?

Can I assume both AB bits might change when (1) you sample too slow and miss a transition, (2) you experience encoder contact bounce, or, (3) you experience noise?

Perhaps I haven't thought this out far enough. Would saving the invalid AB state in my "encold" state latch help me recover from the invalid state?
 
Last edited:
Perhaps I haven't thought this out far enough. Would saving the invalid AB state in my "encold" state latch help me recover from the invalid state?

No. If it moved too fast and you skipped one transition, you cannot recover from this (although if you really try you can figure the direction - if it moves fast in some direction and skipped a position it is likely to be a skip in the direction of the predominant movement).

However, if you do not update the state after the skip, your next count will be in the opposite direction. Say you transitioned 00->11 (that was a skip but nonetheless you're now in quadrant 11). If the next move is to 01, you'll process it as 00->01, which is directly opposite to the real move 11->01.

I don't think it's important. If everything is designed well it shouldn't skip at all.
 
You're right. It's been awhile, though I seem to remember that I wanted to test a modified "table method" routine that would track the number of times both A and B changed, if any.

Thanks... Mike
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top