Shop OBEX P1 Docs P2 Docs Learn Events
Rotary Optical Encoder C object — Parallax Forums

Rotary Optical Encoder C object

beebsbeebs Posts: 20
edited 2009-05-13 07:39 in Propeller 1
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
1507 x 868 - 248K

Comments

  • jazzedjazzed Posts: 11,803
    edited 2009-05-11 05:34
    beebs.
    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
  • beebsbeebs Posts: 20
    edited 2009-05-12 11:17
    Steve,
    You're right, good point, I need to add some explanation there.
    Thanks for the compliment [noparse]:)[/noparse]
    Appreciate you taking a look.


    - dave
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-05-12 12:53
    if( prevEncoderBits<1 ) {
    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)
  • beebsbeebs Posts: 20
    edited 2009-05-12 16:19
    MagIO2,
    Very cool.
    Will definitely incorporate that.

    Thanks!

    - dave
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-05-12 18:34
    This was just a quick shot I did at work ... without testing and just picking the test-cases where it really worked.
    Now that I'm at home I checked it with the truth table and figured out that it does not work for all cases.

    prev cur result
    00    00     00            no step ok
          01     01            right   ok
          11     11            missed  ok
          10     10            left    ok
                              
    01    00     01            right   wrong
          01     00            no step ok          
          11     10            left    wrong
          10     11            missed  ok
                     inverted         
    11    00     11  00 11  11 missed  ok
          01     10     10  10 left    ok
          11     00     00  00 no step ok
          10     01     01  01 right   ok
                 
    10    00     10  01 11  10 left    wrong
          01     11     10  11 missed  ok   
          11     01     00  01 right   wrong
          10     00     01  00 no step ok
    
    

    But I guess there will be a solution without lookup-table.
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-05-13 07:39
    Strange thing, this grey code!

    prev cur           prev xor cur
    00    [color=green]0[/color][color=red]0[/color]           [color=green]0[/color][color=red]0[/color]   no step ok
          [color=green]0[/color][color=red]1[/color]           [color=green]0[/color][color=red]1[/color]   right   ok
          [color=green]1[/color][color=red]1[/color]           [color=green]1[/color][color=red]1[/color]   missed  ok
          [color=green]1[/color][color=red]0[/color]           [color=green]1[/color][color=red]0[/color]   left    ok
                                     [color=orange]prev xor cur[/color]
    [color=orange]01    00           10   left     01            -> needs to be remapped
          01           00   no step  00
          11           01   right    10            -> needs to be remapped
          10           11   missed   11
    [/color]          ____ ___ ____     ___
              prev cur prev xor cur
    11    [color=green]0[/color][color=red]0[/color]  00   11  [color=green]1[/color][color=red]1[/color]   missed  ok
          [color=green]0[/color][color=red]1[/color]       10  [color=green]1[/color][color=red]0[/color]   left    ok
          [color=green]1[/color][color=red]1[/color]       00  [color=green]0[/color][color=red]0[/color]   no step ok
          [color=green]1[/color][color=red]0[/color]       01  [color=green]0[/color][color=red]1[/color]   right   ok
              ____     ____
              prev     prev xor cur
    10    [color=green]0[/color][color=red]0[/color]  01       [color=green]0[/color][color=red]1[/color]   right   ok
          [color=green]0[/color][color=red]1[/color]           [color=green]0[/color][color=red]0[/color]   missed  ok   
          [color=green]1[/color][color=red]1[/color]           [color=green]1[/color][color=red]0[/color]   left    ok   
          [color=green]1[/color][color=red]0[/color]           [color=green]1[/color][color=red]1[/color]   no step ok
    
    

    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.
Sign In or Register to comment.