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.

Quadrature Encoder Debounce in ASM

Status
Not open for further replies.

Mosaic

Well-Known Member
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:
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:
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:
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...
 
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,...
 
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,...


Hola Mike

May I take for granted that any quadrature encoder will output Gray code?
 
Yes and quadrature is the precursor to modem schemes called Trellis encoding with minimal bit changes in parallel codes bigger than 2.
 
ATF wrote:
May I take for granted that any quadrature encoder will output Gray code?

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
 
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.
 
quadrature = (special case of) Gray

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.
 
I suggest that "quadrature" is a subset of Gray Code.

Two bits, modulo 4

Please see my attachment.

JimB

Gray Quad.JPG
 
Gray wheel encoders output Gray code!!

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

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:
I agree with Jim
 
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.


JimB

I guess that implies that debounced code would accommodate such encoders?
 
I guess that implies that debounced code would accommodate such encoders?
I do not know, maybe.

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

JimB
 
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.
 

Attachments

  • QUAD_proteus.zip
    207.5 KB · Views: 602
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.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top