1. 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.
    Dismiss Notice

Quadrature Encoder Debounce in ASM

Discussion in 'Code Repository' started by Mosaic, May 30, 2014.

  1. Mosaic

    Mosaic Well-Known Member

    Joined:
    Jun 3, 2010
    Messages:
    2,568
    Likes:
    128
    Location:
    Caribbean
    Here is some code I tested in Proteus (using the motor encoder for the signal)
    It is full quadrature with a variable debounce. Uses 3 GPR bytes.
    Commented.
    Code (text):

    ScanEncoderPort   ;_________ Eg. Bourns PEC11 series_________________________________________________________________________________________________________
             ; Quadrature (full or detent) rotary encoder signals (A=RA0,B=RA1) , debounced. R_dbcount is an interrupt increment variable, used to tgt a >4ms debounce period.
             ; If rapidly turning the encoder causes a lack of response, try reducing the debounce time a bit. Use 10 - 47K weak pullups on pulse lines.
             ; R_Dbstate tracks the valid debounced condition of the encoder bits RA0,1.
             ; If the encoder bits cannot be placed on the matching portA bits as coded here, read the bits & map them into a RAM byte  (bits 0,1) and replace the below PORTA read with the RAM byte read.
             ; Returns W-register = 0 for no change, .255 for CCW and 1 for CW changes per pulse. Simple to add W-reg to any integer variables  afterward.
             ;______________________________________________________________________________________________________________________________
         movf PORTA,w     ; replace with the mapped RAM byte as mentioned if required..
         andlw d'3'         ; filter bit 0,1 for a change.
         xorwf LastSample,w    ; set changed bits
         xorwf LastSample,f    ; lastsample=currentsample. Affects zero flag.
         andlw d'3'       ; w-reg filter bit 0,1 for a change. Refresh zero flag
         skpz
         clrf R_dbcount       ; start the debounce countdown.
         btfss R_dbcount,2     ;Debounce  period in this example. Depends on particular interrupt speed. (suggest  this:  >4 ms by choosing an appropriate R_dbcount bit)
         retlw 0
         ;______________________________________________________________________________________________________________________________
         ; debounce time has passed. Processing validated changes.
         ;______________________________________________________________________________________________________________________________
         movf LastSample,w   ; fetch the recent encoder bits sample.
         xorwf R_Dbstate,w   ; get changes bet. current state and debounced state.
         xorwf R_Dbstate,f     ; apply them to DB state
         andlw d'3'       ; w-reg filter bit 0,1 for any change.
         skpnz
         retlw 0         ; no debounced change.
         ;______________________________________________________________________________________________________________________________
         ;Else Test each Encoder bit to determine change direction.
         ;______________________________________________________________________________________________________________________________
         clrc
         andlw d'2'        ; filter bit 1
         skpnz
         ;---------------------------------------------------------------------------------------------------------------------------------------------------
         ;********************QUADRATURE MODE CODE:  No Detent (full) or Detent mode (1/4)
         ;---------------------------------------------------------------------------------------------------------------------------------------------------
         ;goto Testbit0     ; ************* Enable this line for full quadrature, AND ALSO,
             ;--------comment out this block for full quadrature--------------
         retlw 0
         movf R_Dbstate,w;
         andlw d'2';
         skpnz;
         retlw 0
             ;---------------block end -----------------
         
         rlf R_Dbstate,w      ; align encoder debounced bits
         xorwf R_Dbstate,w    ; compare bits
         andlw d'2'        ; filter bit 1
         skpnz
         retlw 1         ; 1=> 1 clockwise pulse
         retlw d'255'     ; 255=> 1 anticlockwise pulse.
       Testbit0
         rrf R_Dbstate,w     ; align encoder debounced bits
         xorwf R_Dbstate,w    ; compare bits
         andlw d'1'       ; filter bit 0
         skpz
         retlw 1         ; 1=> 1 clockwise pulse
         retlw d'255'      ; 255=> 1 anticlockwise pulse.
         ;______________________________________________________________________________________________________________________________
     
     
    Last edited: Jun 1, 2014
  2. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,077
    Likes:
    899
    Location:
    Rochdale UK
    ONLINE
    You don't need a debounce....

    All I do is create a state machine.... Monitor the inputs and set the outputs accordingly..

    Take the previous state and the new state and act accordingly... It doesn't need debouncing.

    Code (Pseudo):


    shift old input left twice
    add new input
    If the 4 bit code = 7, 1, 8, 14
    then go in direction 1
    If the 4 bit code = 9, 2, 4, 13
    then go direction 2
    If the 4 bit code = anything else
    do nothing
     
    If the edge bounces.... Who cares... it will just change the direction very quickly...
     
  3. MikeMl

    MikeMl Well-Known Member Most Helpful Member

    Joined:
    Mar 17, 2009
    Messages:
    11,004
    Likes:
    538
    Location:
    AZ 86334
    The output of a quadrature encoder is a two bit Gray code. By definition, a Gray code does not need to be de-bounced. If the encoder stops where one of the two signals is alternating between a 0 and 1 due to noise, the up-down counter gets count-up, count-down, count-up,... commands which just causes it to toggle between two sequential states, i. e. 357, 358, 357, 358,...
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. atferrari

    atferrari Well-Known Member

    Joined:
    Oct 8, 2003
    Messages:
    2,794
    Likes:
    119
    Location:
    Buenos Aires - Argentina


    Hola Mike

    May I take for granted that any quadrature encoder will output Gray code?
     
  6. Tony Stewart

    Tony Stewart Well-Known Member Most Helpful Member

    Joined:
    Aug 31, 2012
    Messages:
    3,151
    Likes:
    281
    Location:
    Richmond Hill , ON Canada near Toronto
    Yes and quadrature is the precursor to modem schemes called Trellis encoding with minimal bit changes in parallel codes bigger than 2.
     
  7. MikeMl

    MikeMl Well-Known Member Most Helpful Member

    Joined:
    Mar 17, 2009
    Messages:
    11,004
    Likes:
    538
    Location:
    AZ 86334
    quadrature = (special case of) Gray
     
  8. Tony Stewart

    Tony Stewart Well-Known Member Most Helpful Member

    Joined:
    Aug 31, 2012
    Messages:
    3,151
    Likes:
    281
    Location:
    Richmond Hill , ON Canada near Toronto
    Last edited: May 5, 2015
  9. JimB

    JimB Super Moderator Most Helpful Member

    Joined:
    Sep 11, 2004
    Messages:
    6,287
    Likes:
    579
    Location:
    Peterhead, Scotland
    ATF wrote:
    Sadly no, I have been burnt with this a couple of times, most recently in the past week or so.

    The first instance was a CHEAP encoder which uses mechanical switches which bounced and scratched in an horrific manner.
    Not only that, but at the detent position both of the switch contacts were open circuit. Thus the output was not a standard two bit Grey code.
    I gave up on these and abandoned them in favour of a more expensive encoder with optos.

    Recently, and also touching on the current milling machine thread, as part of my rebuild of the controls for my mill I am implementing an MPG (Manual Pulse Generator). In CNC speak this is a rotary control used for manually jogging the machine axes to the required position.
    I found a suitable encoder on ebay and the published specifications appeared to show that it gave the two bit Gray code.
    However, on testing it out, when the control is sitting at the detent positions, both outputs are 0v.
    Turning the control one way gives pulses on one of the outputs and a 0v on the other output.
    Turning the control the other way gives the pulses again but the other output is now at 5v.
    Happilly there is no contact bounce or other nastiness, just nice clean edges.

    Of course this discovery gave rise to a very ill tempered outburst on my part, I think that it even caused my parrot to blush! :)

    However, all was not lost as I am using a PIC to direct the MPG pulses to one of three inputs in the control software. One input for each of the three machine axes. As a result I just had to write the PIC code to read the Step and Direction from the encoder and output Gray code to the machine controller software (Mach3).

    JimB
     
    • Informative Informative x 1
  10. MikeMl

    MikeMl Well-Known Member Most Helpful Member

    Joined:
    Mar 17, 2009
    Messages:
    11,004
    Likes:
    538
    Location:
    AZ 86334
    Re Jim's: Not all encoders are quadrature...

    A lot of ham radios use a (cheap) rotary encoder (to control a synthesiser) as the main tuning dial. Over time, as something wears, these stop putting out proper quadrature, and tuning gets erratic...

    I once paid several thousand $ for an optical incremental encoder that had 2^18 steps per revolution.
     
  11. manoj soorya

    manoj soorya Member

    Joined:
    Aug 23, 2014
    Messages:
    238
    Likes:
    4
    Location:
    India
    can someone provide the schematic too for the code shown in the first thread?

    Thank you very much
     
  12. atferrari

    atferrari Well-Known Member

    Joined:
    Oct 8, 2003
    Messages:
    2,794
    Likes:
    119
    Location:
    Buenos Aires - Argentina
    Well, it seems that I need to do some reading...;) The closest I've been was when playing with a mouse and the scroll wheel. I did not dig too much as I can see.

    Gracias Mike.
     
  13. atferrari

    atferrari Well-Known Member

    Joined:
    Oct 8, 2003
    Messages:
    2,794
    Likes:
    119
    Location:
    Buenos Aires - Argentina
    I was aware of its existence related to the 18F4431, IIRC, but never used it. So full of capabilities as that micro is, I always used it in unusual applications only.
     
  14. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,077
    Likes:
    899
    Location:
    Rochdale UK
    ONLINE
    Gray wheel encoders output Gray code!!

    Quadrature encoders output A and B signals at 90 degrees shift....
     
  15. JimB

    JimB Super Moderator Most Helpful Member

    Joined:
    Sep 11, 2004
    Messages:
    6,287
    Likes:
    579
    Location:
    Peterhead, Scotland
    I suggest that "quadrature" is a subset of Gray Code.

    Two bits, modulo 4

    Please see my attachment.

    JimB

    Gray Quad.JPG
     
    • Agree Agree x 1
  16. MikeMl

    MikeMl Well-Known Member Most Helpful Member

    Joined:
    Mar 17, 2009
    Messages:
    11,004
    Likes:
    538
    Location:
    AZ 86334
    Incremental encoder = 2 bit quadrature = 2 bit output = 2bit Gray code

    I have some 12bit parallel (4096 counts per rev) absolute Gray-code encoders, too.

    The older style "blind altimeter encoder" used to encode aircraft altitude had an aneroid bellows rotating a glass wheel coded with a 10bit Gray code shadow mask, where each 100ft altitude change causes one bit of the Gray code to change. This is another example of an absolute, parallel output, Gray Code encoder.
     
    Last edited: May 5, 2015
  17. Tony Stewart

    Tony Stewart Well-Known Member Most Helpful Member

    Joined:
    Aug 31, 2012
    Messages:
    3,151
    Likes:
    281
    Location:
    Richmond Hill , ON Canada near Toronto
    I agree with Jim
     
  18. Mosaic

    Mosaic Well-Known Member

    Joined:
    Jun 3, 2010
    Messages:
    2,568
    Likes:
    128
    Location:
    Caribbean
    I guess that implies that debounced code would accommodate such encoders?
     
  19. JimB

    JimB Super Moderator Most Helpful Member

    Joined:
    Sep 11, 2004
    Messages:
    6,287
    Likes:
    579
    Location:
    Peterhead, Scotland
    I do not know, maybe.

    It would be worth a try if I have time to devote to it sometime.

    JimB
     
  20. Mosaic

    Mosaic Well-Known Member

    Joined:
    Jun 3, 2010
    Messages:
    2,568
    Likes:
    128
    Location:
    Caribbean
    Ok, well here is the proteus file with the asm.

    It does a few other things, but is fairly well commented. It is a test circuit for a PIC breakout board I designed.
     

    Attached Files:

  21. Tony Stewart

    Tony Stewart Well-Known Member Most Helpful Member

    Joined:
    Aug 31, 2012
    Messages:
    3,151
    Likes:
    281
    Location:
    Richmond Hill , ON Canada near Toronto
    Any scratchy encoders can be debounced with a small cap across open contacts such that the Load R and cap is ~10ms (more or less) depending on size and rotational speed. Small encoders might be 1 ms glitches that disappear with the cap. adn Schmitt Input.
     

Share This Page