Shop OBEX P1 Docs P2 Docs Learn Events
Help with Quadrature encoder input and direction — Parallax Forums

Help with Quadrature encoder input and direction

kf4ixmkf4ixm Posts: 529
edited 2011-01-13 08:37 in Propeller 1
hello all. i have a quadrature encoder that i want to use as a input device, its a oaks-grigsby optical encoder, (like a pot) with two outputs, (a and b). for the life of me i cant figure out how to read this thing with spin. im looking for a simple spin program that will take a and b on two pins and show a count number, incrementing in one direction, decrementing in the other, showing the result in PST. like if a then b = fwd cnt=cnt_1, if b then a = rev cnt=cnt-1 not looking for high speed or anything, just something simple where i (and others) may learn from. i seen the objects in the obex, but i think they are way more than what im needing. thanks in advance.:thumb:

Comments

  • TappermanTapperman Posts: 319
    edited 2011-01-12 14:32
    kf4ixm wrote: »
    hello all. i have a quadrature encoder that i want to use as a input device, its a oaks-grigsby optical encoder, (like a pot) with two outputs, (a and b). for the life of me i cant figure out how to read this thing with spin.

    Well ... you'll need to modify it slightly .. but this one reads my US Digital E4P encoder:

    http://www.usdigital.com/products/encoders/incremental/rotary/kit/e4p/

    ... Tim
  • kf4ixmkf4ixm Posts: 529
    edited 2011-01-12 14:49
    Thanks, but i couldnt get this to do anything, i tried to comment out some of the pc_io stuff and still nothing, i take it the pin 20 when it reads that it reads pins 20-24? anyway, thanks for the response.
    Tapperman wrote: »
    Well ... you'll need to modify it slightly .. but this one reads my US Digital E4P encoder:

    http://www.usdigital.com/products/encoders/incremental/rotary/kit/e4p/

    ... Tim
  • John AbshierJohn Abshier Posts: 1,116
    edited 2011-01-12 14:54
    In the Propeller Tool Library is a QuadratureEncoder.spin file. I have used it with no problems.

    John Abshier
  • kf4ixmkf4ixm Posts: 529
    edited 2011-01-12 15:06
    In the Propeller Tool Library is a QuadratureEncoder.spin file. I have used it with no problems.

    John Abshier

    i seen that one, but im confused on how to use it for some reason. im thinking i need to call this object from another object, but im confused on the parameters, how and what do i pass the pin numbers then read the data from that object. this is my first time in spin trying to use an encoder and was hoping for something a little more 'idiot proof'. for me, calling on other objects other than pst or fds and i get lost quick.

    Dang it, i didnt read down past the assembly code, i feel really dumb right now. sorry. i will try this and see what happens. thank you all for the help.
  • kf4ixmkf4ixm Posts: 529
    edited 2011-01-12 15:33
    ok, i tried that and im not gonna lie, im lost. here is the program that im trying to read the 'Quadrature Encoder' object with...
    OBJ
      Encoder : "Quadrature Encoder"
      pst     : "Parallax Serial Terminal"
    VAR
      long Pos[3]                            'Create buffer for two encoders (plus room for delta position support of 1st encoder)
      
    PUB Init
      Encoder.Start(0, 1, 0, @Pos)           'Start continuous two-encoder reader (encoders connected to pins 8 - 11)
      pst.Start(115200)
    PUB Main 
      repeat
        Pos[0] :=0         'Read each encoder's absolute position
        'd :=Encoder.ReadDelta(0)    'Read 1st encoder's delta position (value since last read)
        pst.Str(String(pst#cs, pst#NL, pst#HM, "Counts "))
        pst.Dec(Pos)
        'pst.Dec(Delta)
    

    there is nothing showing up in pst. i am only using one encoder on pins 0 and 1.
  • John AbshierJohn Abshier Posts: 1,116
    edited 2011-01-12 15:46
    Suggested changes
    change Pos[3] to Pos[4]
    Encoder.Start(8, 2, 2, @Pos) pins start at pin 8. First encoder is 8&9, second is 10&11. 2 encoders, 2 deltas
    I don't think that you are allowed to reset the data so remove the Pos[0] := 0 line
    To get absolute position pst.Dec(Pos[0 or 1]
    To get relative position pst.Dec(Encoder.ReadDelta(0 or 1))
    If it reads in the wrong direction, going up when you want it to go down, physically reverse the wires.

    John Abshier

    PS. I am not familar with that specific encoder. It may require pull-ups or pull-downs on the a and b lines.
  • kf4ixmkf4ixm Posts: 529
    edited 2011-01-12 16:06
    Suggested changes
    change Pos[3] to Pos[4]
    Encoder.Start(8, 2, 2, @Pos) pins start at pin 8. First encoder is 8&9, second is 10&11. 2 encoders, 2 deltas
    I don't think that you are allowed to reset the data so remove the Pos[0] := 0 line
    To get absolute position pst.Dec(Pos[0 or 1]
    To get relative position pst.Dec(Encoder.ReadDelta(0 or 1))
    If it reads in the wrong direction, going up when you want it to go down, physically reverse the wires.

    John Abshier

    PS. I am not familar with that specific encoder. It may require pull-ups or pull-downs on the a and b lines.

    ok, im still not getting anything in pst, not even the "counts" string. i put 2.2k pull downs on the a and b outputs to pins 0 and 1, using a prop demo board.
    CON
    
    _clkmode = xtal1 + pll16x                               'Crystal and PLL settings.
    _xinfreq = 5_000_000
    
    OBJ
      Encoder : "Quadrature Encoder"
    pst : "Parallax Serial Terminal"
    VAR
      long Pos[4]                            'Create buffer for two encoders (plus room for delta position support of 1st encoder)
      
    PUB Init
      Encoder.Start(0, 1, 2, @Pos)           'Start continuous two-encoder reader (encoders connected to pins 8 - 11)
      pst.Start(115200)
    PUB Main | Go
    
      repeat
        pst.Str(String(pst#cs, pst#NL, pst#HM, "Counts "))
        Pos := Pos[0]         'Read each encoder's absolute position
        'Delta :=Encoder.ReadDelta(0)    'Read 1st encoder's delta position (value since last read)
        
        pst.Dec(Pos[0])
        'pst.Dec(Delta)
    
  • kf4ixmkf4ixm Posts: 529
    edited 2011-01-12 16:24
    OK, for whatever reason, it didnt like the...
    PUB Init
    
    section of the code. i took that out, put everything under the PUB Main and it works like a charm. Thank you very much for your help, and here is the updated code for anyone else that is interested...
    CON
    
    _clkmode = xtal1 + pll16x                               'Crystal and PLL settings.
    _xinfreq = 5_000_000
    
    OBJ
      Encoder : "Quadrature Encoder"
    pst : "Parallax Serial Terminal"
    VAR
      long Pos[4]                            'Create buffer for two encoders (plus room for delta position support of 1st encoder)
    
    PUB Main
    
    Encoder.Start(0, 1, 2, @Pos)           'Start continuous two-encoder reader (encoders connected to pins 8 - 11)
    pst.Start(115200)
    
      repeat
        waitcnt(clkfreq/10 + cnt)
        pst.Str(String(pst#cs, pst#NL, pst#HM, "Counts "))
        Pos := Pos[0]         'Read each encoder's absolute position
        'Delta :=Encoder.ReadDelta(0)    'Read 1st encoder's delta position (value since last read)
        
        pst.Dec(Pos[0])
        'pst.Dec(Delta)
    

    im still working on the delta part and will update when i get it resolved.
  • lardomlardom Posts: 1,659
    edited 2011-01-12 17:17
    I think This one is as easy as you'll find. It has a spin interface and it uses the PST.
  • kf4ixmkf4ixm Posts: 529
    edited 2011-01-12 17:20
    I've got the delta working now...
    CON
    
    _clkmode = xtal1 + pll16x                               'Crystal and PLL settings.
    _xinfreq = 5_000_000
    
    OBJ
      Encoder : "Quadrature Encoder"
    pst : "Parallax Serial Terminal"
    VAR
      long Pos[4]
      long ReadDelta[4]                            'Create buffer for two encoders (plus room for delta position support of 1st encoder)
    
    PUB Main
    dira[16..17]~~
    Encoder.Start(0, 1, 1, @Pos)           'Start continuous two-encoder reader (encoders connected to pins 8 - 11)
    pst.Start(115200)
    
      repeat
        waitcnt(clkfreq/10 + cnt)        '10Hz screen refresh
        pst.Str(String(pst#cs, pst#NL, pst#HM, "Counts "))
        Pos := Pos[0]         'Read each encoder's absolute position
        pst.Dec(Pos[0])
        pst.Str(String(pst#NL, "Delta "))
        pst.Dec(Encoder.ReadDelta(0))
        if (Encoder.ReadDelta(0)) > 1
          outa[16]~~
        if (Encoder.ReadDelta(0)) < -1
          outa[17]~~
        if (Encoder.ReadDelta(0)) ==0
          outa[16..17]~
    

    one thing im trying now, if you look at the bottom of the code, im trying to have the leds 16 and 17 come on on the demo board, 16 come on when the delta is >1, led 17 come on when delta is <-1, both off when delta is 0 but i cant get that to work, i think im trying to read the varible wrong into the if statement. i've tried assigning a varible to (encoder.ReadDelta(0)) using this...
    delta := (Encoder.ReadDelta(0))
    
    but i get an error when i hit f11, expected an instruction or varible with the word delta highlighted. Any thoughts on why this doesn't work or what im doing wrong?
  • John AbshierJohn Abshier Posts: 1,116
    edited 2011-01-13 07:37
    Did you declare delta as a variable in the VAR section?

    John Abshier
  • kf4ixmkf4ixm Posts: 529
    edited 2011-01-13 08:37
    NOPE!, (VAR Feel like := Stupid!)
    i did but did it wrong, thanks for pointing me in the right direction, i really appreciate your help!
    Did you declare delta as a variable in the VAR section?

    John Abshier

    Here is the updated code for anyone interested...
    CON
    
    _clkmode = xtal1 + pll16x                               'Crystal and PLL settings.
    _xinfreq = 5_000_000
    
    OBJ
      Encoder : "Quadrature Encoder"
    pst : "Parallax Serial Terminal"
    VAR
      long Pos[4]
      long Delta[4]                            'Create buffer for two encoders (plus room for delta position support of 1st encoder)
    
    PUB Main
    dira[16..17]~~
    Encoder.Start(0, 1, 1, @Pos)           'Start continuous two-encoder reader (encoders connected to pins 8 - 11)
    pst.Start(115200)
    
      repeat
        waitcnt(clkfreq/10 + cnt)        '10Hz screen refresh
        pst.Str(String(pst#cs, pst#NL, pst#HM, "Counts "))
        Pos := Pos[0]         'Read each encoder's absolute position
        pst.Dec(Pos[0])
        pst.Str(String(pst#NL, "Delta "))
        pst.Dec(Encoder.ReadDelta(0))
        Delta := (Encoder.ReadDelta(0))
        if Delta => 1
          outa[16]~~
        if Delta =< -1
          outa[17]~~
        if Delta ==0
          outa[16..17]~
    
Sign In or Register to comment.