Kronos Robotics and Electronics
 
 
Home Zeus Projects App Notes Downloads Dios Athena Forums
 

DAN133

Interface to a Quadrature State Device

  By Michael Simpson

 

There are several times that you may want to interface to a device that uses quadrature encoding.  Here are a few

  • Positional Feed Back in a CNC operation

  • Rotary pulse device

  • Robot movement feedback

This application note is not on how to build one of these devices but more on how to program the Dios to read one.  I have a CNC system that I wanted to create a closed system so that when I had overdriven the stepper motors I could still determine the position of the axis in question.  The same thing could be done to determine if a robot wheel is turning.

These deices use two phase states created by optical or mechanical means.  they can be as simple as a rotary wheel with holes and two leds and photo transistors. 

The two phase output allows you to detect not only movement but direction as well.  Lets look at the typical output of a 2 phase device.

Direction 1

00 01 11 10 ......(repeats)

Direction 2

00 10 11 01 ......(repeats)

As you can see a very simple pattern is created depending on the direction the device is moved.  So what our program has to do is two fold.

  • Detect a change

  • Detect direction

First we detect change.  If there has been no change we exit the routine.  No sense checking any thing else if the device has not moved.   To detect change we just store the values of the last two phases (bits) and compare them with the current ones.   The simples way to do this is Xor them together.  If the result is 0 then no change has occurred and we exit with a value of 0 (no change)

Once we no there is a change we need to detect the direction of travel.  To do this we create a pattern of what the device would look like if it was rotated in direction 1.  We know the last state so its simple bit fiddling to create the proper pattern.

Again we xor the current pos with the proposed pos.  If the result is 0 we are moving in direction 1 if its not we are moving in direction 2.  We then return the appropriate code to determine direction.

You will notice that I done refer to directions specifically but rather by general terms.   There is a reason for this.  All that need be done to reverse the true direction is to reverse the leads of the two phase outputs.

The following program demonstrates the procedures I just described.   The main function calls the getquad function to determine direction.  It passes the IO ports the phase outputs are connected to.

Program 1

'Demonstrates the interface to a Quaditure encoded device.
func main()
dim count
dim quaddir

count = 0

loop:
   quaddir=getquad(0,1) 'Pass IO ports phase outputs are connected to.

branch quaddir,loop,incit,decit
   goto loop

incit:
   count = count + 1
   print count
   goto loop

decit:
   count = count -1
   print count
   goto loop

endfunc
 


'-----------------------------------------------------------
'Returns the direction of a quaditure State Device
'Return 0=no change
'Return 1=Direction 1
'Return 2=Direction 2
'
'Pass the 2 port number for the phase A and phase B signals
'-----------------------------------------------------------
func getquad(port1,port2)
'Some variables that are needed

dim curport,tbit
'This on stores the last reading
global oldport

clear curport


'Get the encoder bits and store in variable
curport.bit(0)=ioport(port1)
curport.bit(1)=ioport(port2)

'Test to see if change
if curport ^ oldport = 0 then
   exit 0
endif


'----------------
'We had a change
'----------------
'Lets build what we expect for dir 1
tbit=oldport.bit(0) 'We will need this bit later
oldport = oldport /2 'Shift bits
oldport.bit(1)= tbit ^ 1 'Add saved bit back in but invert

'Now test for what we expect
if oldport ^ curport =0 then
   oldport = curport
   exit 1
else
   'Did not get what we expeced so its the other dir
   oldport = curport
   exit 2
endif


endfunc

 

The last program is not the fastest in the world nor the most efficient.  If the encoder changes faster than this program can handle count will slip or reverse direction.

With this next program we will use some inline assembly and speed things up a bit. 

Note You need Dios Editor 2.3 or later to run this code.

Program 2

'Demonstrates the interface to a Quaditure encoded device.
func main()
dim count
dim quaddir

count = 0

loop:
   quaddir=getquad()

branch quaddir,loop,incit,decit
   goto loop

incit:
  count = count + 1
  print count
  goto loop

decit:
  count = count -1
  print count
  goto loop

endfunc



func getquad()

startasm

 retport equ ASMDAT0
TPORTS equ ASMDAT1
OLDPORTS equ ASMDAT2

   clrf retport
   clrf TPORTS
   btfsc ioport 0
   bsf TPORTS,0
   btfsc ioport 1
   bsf TPORTS,1

   movf OLDPORTS,w
   xorwf TPORTS,w
   btfsc STATUS,Z
   goto nochange

'--------------
'We had change
   rrcf OLDPORTS,w
   bcf WREG,1
   btfss STATUS,C
   bsf WREG,1

   xorwf TPORTS,w

   btfss STATUS,Z
   bsf retport,0
   btfsc STATUS,Z
   bsf retport,1


   movff TPORTS,OLDPORTS
   goto alldone

nochange:
alldone:

endasm

   exit ASMDAT0

endfunc

 

While this program is a bit faster it still could miss something.  There are only two way to catch all the steps of a very high speed encoder.

  • Interrupt driven reader

  • Coproc

I will be doing both these a little bit later.   For now this should get you going with the interface you your own encoders.   As a closing note old computer mice make an excellent source for encoders.

 

 

Parts list

DiosPro 40 Pin Chip

Dios Workboard Deluxe

 

Easy RS232 Driver  

DiosPro 28 Pin Chip

Dios 32 Pin Carrier (Carrier #1)

 

9 Pin Cable

Breadboard Regulator

 

DigiKey Encoder Part# CT3002-ND www.digikey.com

 

Copyright © 2001 - 2004 Kronos Robotics