Counting pulses from an optical encoder disc

dandlion

New Member
I am using a PICAXE 08M2 to control each wheel of my robot. I want to count the pulses from my home-brew optical encoder. It is not a real high resolution device. There are only 18 bright/dark transitions and the disc is mounted on the final drive shaft so the revolutions are only in the realm of zero to a few revs per second. Lets say approximately 54 pulses per second - max. Sounds simple enough. I have set an interrupt to occur whenever an input pin goes high. I assume the pin will go high the moment my detector "sees" the leading edge of the bright/reflective strip on the encoder disc and will remain high as long as it takes for the bright strip to pass the detector. I only need to add 1 to a counter, re-set the interrupt and return to the main routine to do other things. Here's my question... How can I avoid popping back into the interrupt routine multiple times during the same pulse? Also, I don't want to just loop in the interrupt routine as long as the input is high - got too much other stuff to do. Any ideas or suggestions would be greatly appreciated.
 

nick12ab

Senior Member
Set your interrupt so that it next happens when the input goes LOW and put a little bit of extra code in that interrupt routine so that if the interrupt is triggered by a low-going pulse then whatever is in the interrupt isn't executed.

Pseudo-code
Code:
setint 1
'code
interrupt:
    if bit0 = 1 then
        bit0 = 0
        setint 1
        return
    end if
    'do stuff
    'do stuff
    bit0 = 1
    setint 0
    return
 

erco

Senior Member
54 pps isn't all that fast, you might not even need to bother with interrupts, depending on how much concurrent processing is going on. Are you using an 08M2 for each wheel? I made some simple encoders that worked well without using an interrupt. The 20M2's Schmitt trigger-like inputs reduced my over ampling requirements compared to the BASIC Stamps I had used previously.
http://www.youtube.com/watch?v=PfMnl4oGzs8
 

nick12ab

Senior Member
You can also do away with the interrupt by using some code I previously posted here. 16MHz or higher PICAXE speed should be fine for your application.

@erco - You haven't provided any code.
 

dandlion

New Member
Thanks! I'll give that a try. I was trying to make it too hard. If I understand correctly, all I have to do is count each time the encoder input pin goes from high to low. If I don't have too much code in my main program loop, it shouldn't miss any state changes. B.T.w. - At some point, I plan to add a more sophisticated encoder which can give me speed and direction instead of just distance. But wait! As I was writing that, it occurred to me that I can get speed by timing the duration between high pulses. That means i can implement a PID algorithm with these simple encoders!
 

dandlion

New Member
Thanks - I would really be interested in seeing the code if its not too much trouble. See my reply to nick12ab
 

nick12ab

Senior Member
Thanks - I would really be interested in seeing the code if its not too much trouble. See my reply to nick12ab
Sorry, I can't tell which reply is to me and which is to someone else. The normal 'Reply' button at the bottom of each post does not add indication of which post you're replying to - for this use the 'Reply with quote' or 'Multiquote' buttons next to the 'Reply' button.
 

erco

Senior Member
You can get speed by sampling the encoder state rapidly and counting how many consecutive high samples and low samples you get.
 

dandlion

New Member
Sorry, I can't tell which reply is to me and which is to someone else. The normal 'Reply' button at the bottom of each post does not add indication of which post you're replying to - for this use the 'Reply with quote' or 'Multiquote' buttons next to the 'Reply' button.
Sorry! As you can tell - I'm not only learning to use the PICAXE - I'm also learning to use the Forum. I learned early on not to use the "Blog" feature!
 

dandlion

New Member
You can get speed by sampling the encoder state rapidly and counting how many consecutive high samples and low samples you get.
Thanks. Would that be better than using the "Settimer" and using the internal timer function? That's what I was thinking I'd do but as you can tell, I'm still at the bottom of a learning curve.
 

erco

Senior Member
Many ways to skin a cat. Timer might work fine. My encoder program below just keeps looking at the encoder state (0 or 1) and notes when it changes. It would be easy to count the number of consecutive 0's or 1's to calculate a relative speed.

Code:
'72 segment encoder disk on wheel
'continuous rotation servo on b.7
'phototransistor sensor into pin b.6 
'LED displays encoder status on on pin c.6
'picaxe 20M2

start0:
b3=150		  'servo stop value
pause 10
t:b1=0		  'reset encoder stripe counter
b3=155		  'servo drive value 
r:if b1<72 then r   'wait here until encoder count =72
b3=150		  'stop
pause 1000
goto t

start1:b0=pinb.6	             'store initial encoder status 0 or 1 in b0
output c.0
w:pinc.0=pinb.6	              'display encoder status on led
q:if b0=pinb.6 then q        ' wait for encoder change
b0=pinb.6		'update encoder status
inc b1		               'increment encoder count
goto w

start2:pulsout 7,b3           ' servo drives smoother using pulsouts than servopos
pause 20		'drive servo with current value of b3 150 (stop) or 155 (go)
goto start2		'150 stop value applies dynamic braking for quick stop
 
Top