Shop OBEX P1 Docs P2 Docs Learn Events
Quadrature Encoder Object: How do I set or reset the position — Parallax Forums

Quadrature Encoder Object: How do I set or reset the position

Chuck RiceChuck Rice Posts: 210
edited 2008-06-20 00:30 in Propeller 1
I am attempting to use the Quadrature Encoder Object. It works, but I need to be able to set/reset the position to zero (or perhaps another number). I tried:


VAR
    long position[noparse][[/noparse] 4 ]

PUB
  Encoder.Start(Encoder1APin, 1, 0, @position) 
  
  repeat
    position[noparse][[/noparse] 0 ] :=    0 #>   position[noparse][[/noparse] 0 ] <# 10           'limit encoder value
    sevenseg.SetValue(position[noparse][[/noparse] 0 ])





but no Joy.

Comments

  • scottascotta Posts: 168
    edited 2008-06-18 14:52
    The encoder object is overwriting position[noparse][[/noparse]0] everytime it
    sees a change in shaft position, making the following line
    useless: "position[noparse][[/noparse] 0 ] := 0 #> position[noparse][[/noparse] 0 ] <# 10 "

    Just store the initial position if you wish to rest the zero point,
    and add a current position variable for the 0-10 limiting:


    VAR
    long position[noparse][[/noparse] 4 ]
    long zero_position 'HERE
    long current_position 'HERE

    PUB
    Encoder.Start(Encoder1APin, 1, 0, @position)

    zero_position:=position[noparse][[/noparse] 0 ] 'store the current position (the shaft might have moved before the spin code reached this point)

    repeat
    current_position:= 0 #> zero_position-position[noparse][[/noparse] 0 ] <# 10 'limit encoder value
    sevenseg.SetValue(current_position)

    'zero the current position with this line
    'zero_position:=position[noparse][[/noparse] 0 ]
  • scottascotta Posts: 168
    edited 2008-06-18 15:05
    Chuck,

    I think I made a mistake [noparse]:)[/noparse]

    You might need to change

    current_position:= 0 #> zero_position-position[noparse][[/noparse] 0 ] <# 10
    to
    current_position:= 0 #> position[noparse][[/noparse] 0 ]-zero_position <# 10

    or you will be displaying negative numbers.

    Scott
  • Chuck RiceChuck Rice Posts: 210
    edited 2008-06-18 15:09
    I tried that too, but things get more complicated when using another level of variables.

    If the user turns the frob-knob way past 10 with a flick of the wrist and then tries to
    slowly turn back to 10, nothing happens till position gets back in range. This can be
    coded around too, but the solution tends to get messy and unreadable.

    I was hoping that Parallax (Jeff Martin) might provide a version 1.1 of the object with
    a set position function. Not the only solution, but seems like it would be the "best" solution.
  • Jeff MartinJeff Martin Posts: 756
    edited 2008-06-18 16:24
    Hi Chuck,

    The position registers that are at the start of the array that you pass as the PosAddr parameter are·"read-only" registers where the Quadrature Encoder cog stores the absolute position of the encoder(s) since the object was launched.· Those values are never read back into the cog, partly to save time, partly to prevent·mangling of the position values·by having another cog write over them when the Quadrature Encoder cog was·in a bad place for them to be changed. ;-)· Those values are simply there if users with to have an absolute-positition value for the related encoder.

    I had anticipated people would need a feature like what you are needing, and that's why I provided the Delta Value support.· What you do is provide enough room·starting at the PosAddr you·give it to store an Absolution-Position-Value, and a Value-When-Last-Read.· Then you simply call the ReadDelta method when you want to know how much the encoder has moved (a positive or negative value) since the last time you called ReadDelta.

    Side note: Your example's position array declaration defines 4 longs, but you are only using 1 of them (the first one) by specifying 1 for the NumEnc and 0 for the NumDelta parameters in the call to Start... I'll adjust this for sake of this example.

    So, your code becomes something like the following (changes are made in red):
    VAR
        long position[noparse][[/noparse] [color=red][b]2[/b][/color] ]                                   [color=red]'Encoder position workspace (1 absolute value, 1 last-read value)[/color]
        [color=red]long limitedposition                                 'Holds value-limited position of encoder (0 to 10)
    [/color]
    PUB
      Encoder.Start(Encoder1APin, 1, [color=red][b]1[/b][/color], @position)           'Start quadrature encoder object to read 1 encoder with delta support
      
      repeat
        [s][color=red]position[noparse][[/noparse] 0 ] :=    0 #>   position[noparse][[/noparse] 0 ] <# 10       'limit encoder value[/color][/s]
    [color=#ff0000]    limitedposition := limitedposition + Encoder.ReadDelta(0) #> 0 <# 10        'limit encoder value[/color]
        sevenseg.SetValue([color=red]limitedposition[/color] [color=red][s]position[noparse][[/noparse] 0 ][/s][/color])
    
    


    The value from ReadDelta(0) will be a positive or negative value that is equal to the number of positions the encoder has moved since the last call to ReadDelta.· The expression "limitedposition + Encoder.ReadDelta(0) #> 0 <# 10" will add that relative value to the last value in limitedposition and then will limit the overall result to between 0 and 10, inclusive.· So, even if someone cranks on the knob to make it move very fast, you'll always have a limited value in the range you want, and the moment they turn the know in the opposite direction (even just one tick) it will reflect that within your limited range.· And, of course, you can reset limitedposition to any value you desire, at any time.

    Note: I made the limitedposition variable a long, but it should work just fine as a byte since the·Spin interpreter's·intermediate signed math will be using a long-sized register before limiting the value to between 0 and 10, inclusive.· If you want to limit to a range that extends into negative number (like -5 to +5, for example) then limitedposition will have to be a long.

    I don't have time to test the above example... please let me know if it does or doesn't work for you.

    Your request made me aware of the fact that I didn't clearly explain in the object's documentation what the Delta value can be used for; I'll update it to include an example like this.· There's also a small "logical" error I made in the code that I'll fix... it doesn't cause a bug, but is hard to understand because it was a mistake.

    Take care,

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Jeff Martin

    · Sr. Software Engineer
    · Parallax, Inc.

    Post Edited (Jeff Martin (Parallax)) : 6/18/2008 7:28:04 PM GMT
  • Chuck RiceChuck Rice Posts: 210
    edited 2008-06-18 18:40
    Works like a Champ and it is a nice clean solution! Thanks!

    You might also want to emphasize that position is read only for the next user. [noparse]:)[/noparse]
  • Jeff MartinJeff Martin Posts: 756
    edited 2008-06-18 19:25
    Will do. Thanks Chuck.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Jeff Martin

    · Sr. Software Engineer
    · Parallax, Inc.
  • Richard S.Richard S. Posts: 70
    edited 2008-06-18 23:46
    Hello...

    I use the quadrature encoder routine·kindly supplied .· With some modifications to the routine, I have the program check main memory on startup (at the beginning of the program and whenever it is stopped and restarted) for current or edited position.··At initial startup I set main memory buffers to·zero, and later·if I want to reset a given axis to another value or zero it out, I just edit the memory buffer for that axis·and then stop and restart the encoder routine. · I have attached the modified object.· I use it in "quad dro" which is a 4 axis dro using quadrature encoded scales.· Just search on 'quad dro' for a copy of the program, screen shots,·and some discussion.

    The quad dro thread is:

    http://forums.parallax.com/showthread.php?p=720621






    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Richard in Michigan

    Post Edited (Richard S.) : 6/19/2008 11:01:10 AM GMT
  • Richard S.Richard S. Posts: 70
    edited 2008-06-20 00:30
    Oops...I misspoke.· Change Hub memory buffer after stopping encoder object but before restarting or starting the encoder object.· If there is a value in the Hub memory buffer ie 12345,·and you stop then restart the encoder object, no change to the current axis value will occur unless it has been edited between the stop/restart commands.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Richard in Michigan
Sign In or Register to comment.