Quadrature encoders

flyingnunrt

Senior Member
Anyone know where to get or how to make one?
Has anyone got some seed code for me to start with.
I need to count revolutions of the shaft (Not RPMs) but need to subtract from counter when shaft is reversed.
 

SD2100

New Member
I suppose you'll need two sensors, in one direction A picks up then B picks up, in the other it's B then A, then just a matter of
adding or subtracting in the program.

Here's a quicky version, I was going to use a block IF statement with ELSEIF's but there is problems with the beta version so I used 3 separate blocks.
<code><pre><font size=2 face='Courier'>
symbol Latch = b0
symbol Counter = b1
symbol SensorA = pin1
symbol SensorB =pin2

main:
if SensorA=1 and SensorB=0 and Latch=0 then
inc Counter
Latch=1
end if

if SensorA=0 and SensorB=1 and Latch=0 then
dec Counter
Latch=1
end if

if SensorA=0 and SensorB=0 then
Latch=0
end if
goto main
</font></pre></code>


Edited by - Phil75 on 17/10/2006 16:19:58
 

hippy

Technical Support
Staff member
This may be useful - http://www.rev-ed.co.uk/picaxe/forum/Topic.asp?topic_id=1547
 

flyingnunrt

Senior Member
Thanks phil thats good.
I didn't know about inc and dec.
Gee that simulator is great in the beta programmer. Just saved me so much time coming to grips with the above.
Yesterday I didn't even know what a quad thingy was, now I think I have some sort of handle on it.
 

evanh

Senior Member
Searching for &quot;quadrature encoder&quot; on this forum will provide much info.

To add to Hippy's link I also posted an enhanced FSM version of the decoder, <A href='http://www.rev-ed.co.uk/picaxe/forum/Topic.asp?topic_id=2049&amp;forum_id=14&amp;Topic_Title=rotary%2Bencoder&amp;forum_title=No+new+posts+please%21+8' Target=_Blank>External Web Link</a>.


Evan
 

evanh

Senior Member
Here's a tidied version from the above link. A few things of note:

- It would be difficult to integrate this code with other functions.

- If no other signals are to appear on the the input pins then the line &quot;snap = pins &amp; 3&quot; is no longer needed although BRANCH command may not like operating on PINS directly.

- Jitter removal is done by swallowing the first count in the opposite direction. This will not normally add noticable error to the measurement.

- A small optimisation was done by removing some of the &quot;pins = counter&quot; commands from the fast counting states.

<code><pre><font size=2 face='Courier'>
; *****************************************************************************
; * *
; * Quadrature Decoder Using Finite State Machine *
; * *
; * *
; * http://homepage.ntlworld.com/the.happy.hippy/picaxe/encoder.txt *
; * *
; * Modified by Evan Hillas (evanh@clear.net.nz): *
; * 01 Aug 2004 - Streamlined execution *
; * 23 Oct 2004 - Added tripple speed *
; * 26 Oct 2006 - Showing jitter removal variant *
; *****************************************************************************
;
; States are named as _&lt;from&gt;_&lt;to&gt;_&lt;inc/dec&gt;
;


SYMBOL snap = b0
SYMBOL counter = b1


low portc 7 ; Flash LED on my 28X board
sertxd (&quot;Yay&quot;,13,10)
dirsc=0

snap = pins &amp; 3
BRANCH snap,( _00_00_f , _01_01_f , _10_10_f , _11_11_f )


; *****************************************************************************
; * *
; * Moving forward state machine *
; * *
; *****************************************************************************

; *****************************************************************************
; * Moving forward zero speed *
; *****************************************************************************

_00_00_f:
pins = counter
snap = pins &amp; 3
BRANCH snap,( _00_00_f , _00_01_f1 , _10_10_b , _00_11_f2 )

_01_01_f:
pins = counter
snap = pins &amp; 3
BRANCH snap,( _00_00_b , _01_01_f , _01_10_f2 , _01_11_f1 )

_11_11_f:
pins = counter
snap = pins &amp; 3
BRANCH snap,( _11_00_f2 , _01_01_b , _11_10_f1 , _11_11_f )

_10_10_f:
pins = counter
snap = pins &amp; 3
BRANCH snap,( _10_00_f1 , _10_01_f2 , _10_10_f , _11_11_b )


; *****************************************************************************
; * Moving forward single speed *
; *****************************************************************************

_10_00_f1:
counter = counter + 1
pins = counter
snap = pins &amp; 3
BRANCH snap,( _00_00_f , _00_01_f1 , _00_10_f3 , _00_11_f2 )

_00_01_f1:
counter = counter + 1
pins = counter
snap = pins &amp; 3
BRANCH snap,( _01_00_f3 , _01_01_f , _01_10_f2 , _01_11_f1 )

_01_11_f1:
counter = counter + 1
pins = counter
snap = pins &amp; 3
BRANCH snap,( _11_00_f2 , _11_01_f3 , _11_10_f1 , _11_11_f )

_11_10_f1:
counter = counter + 1
pins = counter
snap = pins &amp; 3
BRANCH snap,( _10_00_f1 , _10_01_f2 , _10_10_f , _10_11_f3 )


; *****************************************************************************
; * Moving forward double speed *
; *****************************************************************************

_11_00_f2:
counter = counter + 2
snap = pins &amp; 3
BRANCH snap,( _00_00_f , _00_01_f1 , _00_10_f3 , _00_11_f2 )

_10_01_f2:
counter = counter + 2
snap = pins &amp; 3
BRANCH snap,( _01_00_f3 , _01_01_f , _01_10_f2 , _01_11_f1 )

_00_11_f2:
counter = counter + 2
snap = pins &amp; 3
BRANCH snap,( _11_00_f2i , _11_01_f3 , _11_10_f1 , _11_11_f )

_01_10_f2:
counter = counter + 2
snap = pins &amp; 3
BRANCH snap,( _10_00_f1 , _10_01_f2i , _10_10_f , _10_11_f3 )

_11_00_f2i:
counter = counter + 2
pins = counter
snap = pins &amp; 3
BRANCH snap,( _00_00_f , _00_01_f1 , _00_10_f3 , _00_11_f2 )

_10_01_f2i:
counter = counter + 2
pins = counter
snap = pins &amp; 3
BRANCH snap,( _01_00_f3 , _01_01_f , _01_10_f2 , _01_11_f1 )


; *****************************************************************************
; * Moving forward tripple speed *
; *****************************************************************************

_01_00_f3:
counter = counter + 3
snap = pins &amp; 3
BRANCH snap,( _00_00_f , _00_01_f1 , _00_10_f3 , _00_11_f2 )

_11_01_f3:
counter = counter + 3
snap = pins &amp; 3
BRANCH snap,( _01_00_f3i , _01_01_f , _01_10_f2 , _01_11_f1 )

_10_11_f3:
counter = counter + 3
snap = pins &amp; 3
BRANCH snap,( _11_00_f2 , _11_01_f3 , _11_10_f1 , _11_11_f )

_00_10_f3:
counter = counter + 3
snap = pins &amp; 3
BRANCH snap,( _10_00_f1 , _10_01_f2 , _10_10_f , _10_11_f3 )

_01_00_f3i:
counter = counter + 3
pins = counter
snap = pins &amp; 3
BRANCH snap,( _00_00_f , _00_01_f1 , _00_10_f3 , _00_11_f2 )


; *****************************************************************************
; * *
; * Moving backward state machine *
; * *
; *****************************************************************************

; *****************************************************************************
; * Moving backward zero speed *
; *****************************************************************************

_00_00_b:
pins = counter
snap = pins &amp; 3
BRANCH snap,( _00_00_b , _01_01_f , _00_10_b1 , _00_11_b2 )

_01_01_b:
pins = counter
snap = pins &amp; 3
BRANCH snap,( _01_00_b1 , _01_01_b , _01_10_b2 , _11_11_f )

_11_11_b:
pins = counter
snap = pins &amp; 3
BRANCH snap,( _11_00_b2 , _11_01_b1 , _10_10_f , _11_11_b )

_10_10_b:
pins = counter
snap = pins &amp; 3
BRANCH snap,( _00_00_f , _10_01_b2 , _10_10_b , _10_11_b1 )


; *****************************************************************************
; * Moving backward single speed *
; *****************************************************************************

_01_00_b1:
counter = counter - 1
pins = counter
snap = pins &amp; 3
BRANCH snap,( _00_00_b , _00_01_b3 , _00_10_b1 , _00_11_b2 )

_11_01_b1:
counter = counter - 1
pins = counter
snap = pins &amp; 3
BRANCH snap,( _01_00_b1 , _01_01_b , _01_10_b2 , _01_11_b3 )

_10_11_b1:
counter = counter - 1
pins = counter
snap = pins &amp; 3
BRANCH snap,( _11_00_b2 , _11_01_b1 , _11_10_b3 , _11_11_b )

_00_10_b1:
counter = counter - 1
pins = counter
snap = pins &amp; 3
BRANCH snap,( _10_00_b3 , _10_01_b2 , _10_10_b , _10_11_b1 )


; *****************************************************************************
; * Moving backward double speed *
; *****************************************************************************

_11_00_b2:
counter = counter - 2
snap = pins &amp; 3
BRANCH snap,( _00_00_b , _00_01_b3 , _00_10_b1 , _00_11_b2 )

_10_01_b2:
counter = counter - 2
snap = pins &amp; 3
BRANCH snap,( _01_00_b1 , _01_01_b , _01_10_b2 , _01_11_b3 )

_00_11_b2:
counter = counter - 2
snap = pins &amp; 3
BRANCH snap,( _11_00_b2i , _11_01_b1 , _11_10_b3 , _11_11_b )

_01_10_b2:
counter = counter - 2
snap = pins &amp; 3
BRANCH snap,( _10_00_b3 , _10_01_b2i , _10_10_b , _10_11_b1 )

_11_00_b2i:
counter = counter - 2
pins = counter
snap = pins &amp; 3
BRANCH snap,( _00_00_b , _00_01_b3 , _00_10_b1 , _00_11_b2 )

_10_01_b2i:
counter = counter - 2
pins = counter
snap = pins &amp; 3
BRANCH snap,( _01_00_b1 , _01_01_b , _01_10_b2 , _01_11_b3 )


; *****************************************************************************
; * Moving backward tripple speed *
; *****************************************************************************

_10_00_b3:
counter = counter - 3
snap = pins &amp; 3
BRANCH snap,( _00_00_b , _00_01_b3 , _00_10_b1 , _00_11_b2 )

_00_01_b3:
counter = counter - 3
snap = pins &amp; 3
BRANCH snap,( _01_00_b1 , _01_01_b , _01_10_b2 , _01_11_b3 )

_01_11_b3:
counter = counter - 3
snap = pins &amp; 3
BRANCH snap,( _11_00_b2 , _11_01_b1 , _11_10_b3 , _11_11_b )

_11_10_b3:
counter = counter - 3
snap = pins &amp; 3
BRANCH snap,( _10_00_b3i , _10_01_b2 , _10_10_b , _10_11_b1 )

_10_00_b3i:
counter = counter - 3
pins = counter
snap = pins &amp; 3
BRANCH snap,( _00_00_b , _00_01_b3 , _00_10_b1 , _00_11_b2 )

; *****************************************************************************

end
</font></pre></code>

Edited by - evanh on 25/10/2006 23:04:09
 

RickAlty

Senior Member
As to the question as the where to get one, here....

http://cgi.ebay.com/10-Switches-Rotary-Encoders-for-John-Deere-Tractor_W0QQitemZ140016493732QQihZ004QQcategoryZ67005QQcmdZViewItem

Is a link to some being sold on eBay. These are 24 step per rotation, positive detent (ie they 'click') quadrature encoders.

Richard
 

evanh

Senior Member
I just re-edited the above listing to streamline the new optimisation. If you have made a copy of it then you better make another copy.


Evan
 

flyingnunrt

Senior Member
Phil75's code is OK for what I need except that the counter clocks over if the shaft is rotated back and forth at the clocking position, which is a problem.
How shoul the disc and sensors be arranged?
90 degree cut out with sensors within the cut sector or outside?
 

SD2100

New Member
I see what you mean, It needs to check that the second sensor has changed before adding or subtracting the counter, I'll have a look at it. The holes in the disc should be arranged so in one direction A picks up then B picks up then A goes low followed by B, in the other direction it's opposite, B picks up then A, B goes drops off then A drops off. google quadrature encoders will show a lot of stuff.
 

evanh

Senior Member
Bit pattern is described here, <A href='http://www.rev-ed.co.uk/picaxe/forum/Topic.asp?topic_id=3153&amp;forum_id=18&amp;Topic_Title=Encoder%252C%2BModel%253A%2BEC%252D10%253F&amp;forum_title=No+new+posts+please%21+12' Target=_Blank>External Web Link</a>
Some electrical and mechanical issues covered here, <A href='http://www.rev-ed.co.uk/picaxe/forum/Topic.asp?topic_id=691&amp;forum_id=7&amp;Topic_Title=Working%2Bwith%2Bbits&amp;forum_title=No+new+posts+please%21+2' Target=_Blank>External Web Link</a>

I would use a ready made encoder to be confident in my methods before constructing an encoder of my own.


Evan

Edited by - evanh on 26/10/2006 08:29:08
 

SD2100

New Member
Here's a new one, Some description below but easier to understand in the simulator.

If A is high and B is low it drops into the forward loop, if A goes low while B is high
then the shaft is still turning forward so the counter is incremented, the program then
exits the forward loop, now with A low and B high the reverse loop is entered, if the shaft
is turned backwards A goes high then B goes low which subtracts one from the counter but if
the shaft continues to turn forward then A &amp; B will go low and it will exit to the main loop.
The program will swap back and forth between the forward and reverse loops depending on the
state on the inputs.
'
'
<code><pre><font size=2 face='Courier'>
#picaxe 08m

symbol Counter = b0
symbol Sensor_A = pin1
symbol Sensor_B = pin2

do
;Forward
if Sensor_A=1 and Sensor_B=0 then
do
if Sensor_A=0 and Sensor_B=1 then
inc Counter
exit
elseif Sensor_A=0 and Sensor_B=0 then
exit
end if
loop
end if

;Reverse
if Sensor_A=0 and Sensor_B=1 then
do
if Sensor_A=1 and Sensor_B=0 then
dec Counter
exit
elseif Sensor_A=0 and Sensor_B=0 then
exit
end if
loop
end if
loop </font></pre></code>

Edited by - Phil75 on 26/10/2006 10:26:38
 

SD2100

New Member
How have you set up the encoder ???

to inc 1 count the sensors do the following
when turning forward
A high
B high
A low
B low

to dec 1 count the sensors do the following
when turning in reverse
B high
A high
B low
A low

If your turning in say the forward direction and your getting inc 1 then dec 1 it appears your getting inputs like the following

A high
B low
B high
A low
A high
B low
B high
A low
A high
B low
etc

How have you made the disc and what are you using for the sensors ??


Edited by - Phil75 on 26/10/2006 13:02:42
 

flyingnunrt

Senior Member
How bizzar.
It works on my hardware setup but was not incrementing the counter in the simulator.
I didn't load it into an actual picaxe to test.
Thanks heaps phil, it is now running as sweet as.
 

SD2100

New Member
Thats funny I tested it in the sim but not in the chip and it counted ok, have you got the latest beta test version 5.0.4 the earlier versions had problems with the IF THEN statements so if your not using the latest one then that might be the problem ??
anyway good to see you have it working.
 

SD2100

New Member
If you want to save 19 bytes, this will cut it down from 69 bytes to 50 by using PINS in the IF statements instead of the SENSOR variables.
<code><pre><font size=2 face='Courier'>
#picaxe 08m
symbol Counter = b0

do
;Forward
if pins = 2 then
do
if pins = 4 then
inc Counter
exit
elseif pins = 0 then
exit
end if
loop
end if

;Reverse
if pins = 4 then
do
if pins = 2 then
dec Counter
exit
elseif pins = 0 then
exit
end if
loop
end if
loop
</font></pre></code>
 

flyingnunrt

Senior Member
5.0.3!!
Looks like I missed 5.0.4.
I'll get it now.
Previous code counted ok. so I assummed the sim was ok.
Your last posting looks good.
Again many thanks.

Just downloaded version 5.0.4 which counts perfectly.

Edited by - flyingnunrt on 26/10/2006 15:11:10
 
Top