Rotary Optical Encoder C object
beebs
Posts: 20
Hi Everyone,
I've written an ICC7 routine for interfacing a rotary encoder to the Propeller.
This is my first real project working with the Propeller.
Specifically this works with Grayhill's 62LP22-L4 optical encoder with push button.
(http://www.grayhill.com/web1/images/ProductImages/Opt_Encoder_62P.pdf)
The function runs in one cog and is monitored from a main loop.
I'm working on an attic fan controller module and this will serve as the method for controlling menu navigation.
I think I'm going to use one of displays Timothy has on Brilldea for displaying
status info, on screen configuration, etc. Overkill probably, but I'm hoping to
incorporate some type of power save feature so the display can be "awakened" when
I want to check the status and in a "sleep" mode otherwise.
I've attached the code, a picture and link to a quick video demo of the prototype I created.
Below is a list of the connections which hopefully if someone is interested could use to recreate.
The small pcb the encoder is mounted to was just something simple to make it easy to use when breadboarding.
If anyone is interested I could post the eagle files for that also.
I'd like to see what others think and if this would be worthy of putting in the OBEX.
Any suggestions would be great.
Thanks for looking.
PPDB connections (as used in the demo):
P0 -> 16seg - A1
P1 -> 16seg - A2
P2 -> 16seg - B
P3 -> 16seg - C
P4 -> 16seg - D1
P5 -> 16seg - D2
P6 -> 16seg - E
P7 -> 16seg - F
P8 -> 16seg - G1
P9 -> 16seg - G2
P10 -> LED 0
P11 -> Encoder Push button
P15 -> Encoder output "A"
P16 -> Encoder output "B"
Note on Encoder connections:
The signal pins require a 10K pullup to +5v per datasheet.
The datasheet also recommends a 150 ohm resistor the +5v source.
demo video:
www.youtube.com/watch?v=XZKcLmYYg2M
I've written an ICC7 routine for interfacing a rotary encoder to the Propeller.
This is my first real project working with the Propeller.
Specifically this works with Grayhill's 62LP22-L4 optical encoder with push button.
(http://www.grayhill.com/web1/images/ProductImages/Opt_Encoder_62P.pdf)
The function runs in one cog and is monitored from a main loop.
I'm working on an attic fan controller module and this will serve as the method for controlling menu navigation.
I think I'm going to use one of displays Timothy has on Brilldea for displaying
status info, on screen configuration, etc. Overkill probably, but I'm hoping to
incorporate some type of power save feature so the display can be "awakened" when
I want to check the status and in a "sleep" mode otherwise.
I've attached the code, a picture and link to a quick video demo of the prototype I created.
Below is a list of the connections which hopefully if someone is interested could use to recreate.
The small pcb the encoder is mounted to was just something simple to make it easy to use when breadboarding.
If anyone is interested I could post the eagle files for that also.
I'd like to see what others think and if this would be worthy of putting in the OBEX.
Any suggestions would be great.
Thanks for looking.
PPDB connections (as used in the demo):
P0 -> 16seg - A1
P1 -> 16seg - A2
P2 -> 16seg - B
P3 -> 16seg - C
P4 -> 16seg - D1
P5 -> 16seg - D2
P6 -> 16seg - E
P7 -> 16seg - F
P8 -> 16seg - G1
P9 -> 16seg - G2
P10 -> LED 0
P11 -> Encoder Push button
P15 -> Encoder output "A"
P16 -> Encoder output "B"
Note on Encoder connections:
The signal pins require a 10K pullup to +5v per datasheet.
The datasheet also recommends a 150 ohm resistor the +5v source.
demo video:
www.youtube.com/watch?v=XZKcLmYYg2M
Comments
Your code looks fine to me ... some comments about the EncoderStart function parameters above the function definition might make it easier to understand. I like your 16 segment led driver array [noparse]:)[/noparse]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propalyzer: Propeller PC Logic Analyzer
http://forums.parallax.com/showthread.php?p=788230
You're right, good point, I need to add some explanation there.
Thanks for the compliment [noparse]:)[/noparse]
Appreciate you taking a look.
- dave
dir = ~prevEncoderBits ^ ~ucEncoderBits
} else {
dir = prevEncoderBits ^ ucEncoderBits
}
directly gives you the direction without a lookup-table. 01=one direction, 10=other direction, 00 = nothing changed, 11 = missed one step.
And you don't need to waste 16 bytes ;o)
Very cool.
Will definitely incorporate that.
Thanks!
- dave
Now that I'm at home I checked it with the truth table and figured out that it does not work for all cases.
But I guess there will be a solution without lookup-table.
I·expected a golden rule for calculating the result from the input-bits. And as you can see in the truth-table there is a rule for all cases except the previous value is 01.
Each red column in the result can easily be derived from the corresponding red column of the current value. For example for prev=10 the resulting red column is simply the inverse of the red column of cur. The green column in the result is equal to the green column of cur. This is why xor with 01 gives the correct result. Xor can be seen as a programmable inverter. Having a 0 in the first operand keeps the bit in the second operand, having a 1 in the first operand inverts the bit in the second operand.
So, for the 3 cases where prev is 00, 11 or 10 there is a simple boolean expression to get the result. Only for 01 it looks completely different. Here bit 0 of cur seems to correspond with bit 1 of result, bit 1 of cur corresponds with bit 0 of result. So, a bitwise boolean expression would be needed, but that's not what we really wanna do ;o)
What to do now very much depends on the fact if you need the additional information that you missed a state and·if you can turn the encoder fast enough to miss something at all. So, if results 00 and 11 simply result in 'do nothing' then you simply invert prev if it's not 00 and you get a result you can live with.