Hi all, I'm hoping for a little input on where i might be going wrong with my latest project using some home made optical encoders.
My pic is a 16f628a and i have 2 sensors generating interrupts on portB. i.e they are not quad or grey output - just a single opto sensor each with no direction. Each increment a counter which is displayed on a LCD.
The code appears fine, the sensors work but not quite as they should. It could be a problem with my encoder wheels but here's what happens:
Without the chopper disks, if i break the beam on the sensor with something opaque, i get an increment of 1 on the counter and same when the beam returns to unbroken. This works as expected. If the sensors are left alone, i do not get any increment. With the encoder disks in place i can rotate them at pace and get believable increments. My encoders are ~50 pulse/rev and i can get about 50 pulses if i manually rotate it about 360 degrees.
My problem is when i rotate them slowly - i.e just a small movement might increment the counter by 10 or 20. My assumption is that the sensor is on the edge of the opaque bit on the encoder and 'flaps' a bit. But, i do not get this when i manually break the beam which seems odd.
The encoders are printed with a laser printer on transparency film and are only 23mm diameter. The marks are very opaque and the on/off time is uniform. The Sensors are RS 306-061 (now discontinued but i had a heap of them).
So, from what i can see i have a few options:
I can reduce the 'on' time by using a sensor that has much less clear than opaque, reducing the edges somewhat
I could introduce some sort of 'debouncing' in my code to prevent flapping on the edges (could mean missed pulses but the application is slow speed)
Some other code change?
Try printing the disks on a different/better printer
Move the encoder disk closer to the transistor side of the sensor?
Is there a change to the circuit i could make that will help?
I'm after general comments from people that might have had some experience with this sort of thing in the past.
My interrupt routine (modded version of someone elses on this forum)...
Code:
Rot_Encoder:
New_Bits = PORTB & (%00110000)
' which encoder changed
IF (New_Bits & %00100000) = (Old_Bits & %00100000) then No_Change_Rot1
RotEnc1_val = RotEnc1_val + 1
No_Change_Rot1:
IF (New_Bits & %00010000) = (Old_Bits & %00010000) then DoneRotEnc
RotEnc2_val = RotEnc2_val + 1
DoneRotEnc:
Old_Bits = New_Bits
@ INT_RETURN
Pic of sensor schematic and example encoder disks attached...
P.S If anyone wants the .ps file i use for creating the encoder disks, let me know...
Bookmarks