Forum Update - Announcement about May 10th, 2018 update and your password.

Encoder Idea

ElaineElaine Posts: 8
I finally got a replacement for my Bourns 64-pulse per revolution optical encoder and have been playing with it all day. I can read left and right rotations reasonably well using the attached look-up table.
upload_2015-11-12_16-39-7.png

The problem is that the zeros mean different things. The first 0 (offset =0) means no change in position. The other 0's are effectively errors, such as skipped reads. The characteristic of which is more than one bit changes in the binary value I am reading. In brief, the +1's and -1's are added to an accumulator to determine the actual number of "clicks."

Since "true" zero should be much more common than the other zeros, I am thinking of using another value for the other zeros, such as "2" that could be easily tested for (e.g., xorlw 0x02, skpnz). Any other ideas?

Thanks, Elaine

Comments

  • 16 Comments sorted by Date Added Votes
  • Where does that table come from ?
    It is a strange way to present optical encoder info.

    Usually, for any given counter value, there are 4 possible paths +0 (no change), then +1 or -1 and finally Err, which is both Quad channel changed, and that can go to another decision tree.
    Some systems treat that as a speed overrun, and use the previous delta, others flag it as an error.
  • jmg wrote: »
    Where does that table come from ?
    It is a strange way to present optical encoder info.

    Agreed.

    I'm guessing this is a quadrature encoder.

    Quadrature output has two pins which transition between high and low with only one channel changing at a time.

    The channels are often called A and B.

    In one direction you'll get output like this.
    0, 0
    0, 1
    1, 1
    1, 0
    and then back to 0, 0.

    In the other direction you'll get the following output.
    0, 0
    1, 0
    1, 1
    0, 1

    The program can tell which direction the encoder is rotating to keeping track of the previous output and checking it against the new output.

    If the previous output had been 1, 0 and the new output is 1, 1, then we know the encoder is rotating according to the first set of outputs listed above.

    I posted some quadrature encoder code here.

    If the code has been written correctly, you can't "fool" the encoder by rotating it back and forth a small amount. As mentioned in the thread linked above, there's an object in the OBEX which doesn't count transitions correctly.

    I'm pretty sure there's some quadrature encoder code in the Propeller Tool's library.

  • For my needs, I dedicated a cog to one encoder but didn't bother with the table method. I simply waited for either CHA or CHB to change from their existing state and incremented or decremented the counter variable based on, well, the table.

    This method doesn't require that the inputs be contiguous and allows for CHI (index) handling (typically in "A0B0:" below).

    It's in PropBASIC (therefore self documented) which translates directly to PASM.
    DEVICE P8X32A, XTAL1, PLL16X
    FREQ 80_000_000
    
    Chan_A PIN 6 INPUT
    Chan_B PIN 7 INPUT
    Chan_Z PIN 2 INPUT
    
    Counter VAR LONG = 0
    HubCTR HUB LONG
    LoopCTR VAR LONG = 0
    Idx_Monitor VAR LONG = 0
    Idx_Count VAR LONG = 0
    Count_Error VAR LONG = 0
    
    PROGRAM Start
    
    Start:
    Watch Counter   ' This is for ViewPort
    
    
    'Decide where to start
    If Chan_A = 1 And
        Chan_B = 1 Then
        Goto A1B1
    Endif
    
    If Chan_A = 0 And
        Chan_B = 0 Then
        Goto A0B0
    Endif
    
    If Chan_A = 1 And
        Chan_B = 0 Then
        Goto A1B0
    Endif
    
    If Chan_A = 0 And
        Chan_B = 1 Then
        Goto A0B1
    Endif
    
    'Keep hopping between these labels 
      
     A1B1:
     If Chan_A = 0 Then
       Dec Counter
       Wrlong HubCTR,Counter
       Goto A0B1
     Elseif Chan_B = 0 Then
       Inc Counter
       Wrlong HubCTR,Counter
       Goto A1B0
     Endif
     Goto A1B1
     
     A0B0:
     If Chan_A = 1 Then
       Dec Counter
       Wrlong HubCTR,Counter
       Goto A1B0
     Elseif Chan_B = 1 Then
       Inc Counter
       Wrlong HubCTR,Counter
       Goto A0B1
     Endif
     Goto A0B0
     
     A1B0:
     If Chan_A = 0 Then
       Inc Counter
       Wrlong HubCTR,Counter
       Goto A0B0
     Elseif Chan_B = 1 Then
       Dec Counter
       Wrlong HubCTR,Counter
       Goto A1B1
     Endif
     Goto A1B0
     
     A0B1:
     If Chan_A = 1 Then
       Inc Counter
       Wrlong HubCTR,Counter
       Goto A1B1
     Elseif Chan_B = 0 Then
       Dec Counter
       Wrlong HubCTR,Counter
       Goto A0B0
     Endif
     Goto A0B1
    End
    
    PropBASIC ROCKS!
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 21,968
    edited December 2015 Vote Up0Vote Down
    A table is a perfectly logical -- and simple-to-program -- way to encode the state transitions for a quadrature encoder. It's the way I would to it. In Elaine's table, the first two bits represent the previous states of the A and B channels; the second two bits, the current values. However, 0 (0000) is not the only legitimate non-change value: also 5 (0101), 10 (1010), and 15 (1111).

    The cool thing about such a table is that it can be completely represented in the Prop as one 32-bit long.

    -Phil
    “Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away. -Antoine de Saint-Exupery
  • Thanks all! I am looking for the CW or CCW change. I am thinking of an "enhancement." My thought was to use those returns that indicate more than a 1-bit change as flags to change the range.
  • Duane Degn, Mickster , I will try to use the meat of your codes. Thank you for sharing your algorithm.
  • FWIW, I have since decided to implement external quad decode ICs, with up/down count outputs, to feed the Prop's own high speed counters. It just felt wrong to waste a cog doing something that it's not particularly good for. Admittedly, I have no practical need for 16MHz capability but it's good for specmanship :-D
    PropBASIC ROCKS!
  • The term "waste a cog" has always bothered me. If it's a cog that can be spared, it's not "wasted," particularly if it's in the midst of a waitxxx instruction, since it requires virtually no power in the interim. The Propeller chip is as close as you will ever come to a microcoded peripheral processor without actually being one. Event processing and waiting for stuff to happen is what the cogs were invented for -- no "waste" involved.

    -Phil
    “Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away. -Antoine de Saint-Exupery
  • +1 @PhiPi

    and the P2 is supposed to have 16 of them.

    Enjoy!

    Mike
    I am just another Code Monkey.
    A determined coder can write COBOL programs in any language. -- Author unknown.
    Press any key to continue, any other key to quit

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this post are to be interpreted as described in RFC 2119.
  • I don't know any other way to appropriately word it. Quad decode is a mundane, simple task that requires no computation and very little code/data. Thanks to the hub-write bottleneck, a cog can only, at best, handle up to 2MHz quad decode and this is bare bones; not including any form of filtering that pretty much every dedicated quad decode IC has. Meanwhile, each cog features two counters, good for what, 40MHz? They only lack the ability to decode quad.
    PropBASIC ROCKS!
  • Mickster wrote: »
    I don't know any other way to appropriately word it. Quad decode is a mundane, simple task that requires no computation and very little code/data. Thanks to the hub-write bottleneck, a cog can only, at best, handle up to 2MHz quad decode and this is bare bones; not including any form of filtering that pretty much every dedicated quad decode IC has.
    SW will always be slower than HW, but you may be able to push this a little with less frequent transfers,
    Of course that has other complications...

    Mickster wrote: »
    Meanwhile, each cog features two counters, good for what, 40MHz? They only lack the ability to decode quad.
    Yes, that was a fairly large oversight.
    - but U/D counters are slightly slower than single direction counters.
    Mickster wrote: »
    FWIW, I have since decided to implement external quad decode ICs, with up/down count outputs, to feed the Prop's own high speed counters.
    What part did you choose ?

  • jmg wrote: »
    SW will always be slower than HW, but you may be able to push this a little with less frequent transfers,
    Of course that has other complications...
    Yeah no matter how infrequent the write, any time that it hangs around waiting for hub access (worst case, 22 clocks), it will lose counts. For velocity control, not a big deal but I need to keep track of absolute position.

    jmg wrote: »
    Yes, that was a fairly large oversight.
    No kidding.

    jmg wrote: »
    What part did you choose ?
    I'm glad you asked because I forgot to thank you for finding it for me, several years ago :-D
    I have sixteen of THESE on order.

    I might just grab a BiSS-C master device to play with. More and more demand for absolute encoders out there.



    PropBASIC ROCKS!
  • Duane DegnDuane Degn Posts: 10,002
    edited December 2015 Vote Up0Vote Down
    Mickster wrote: »
    Yeah no matter how infrequent the write, any time that it hangs around waiting for hub access (worst case, 22 clocks), it will lose counts. For velocity control, not a big deal but I need to keep track of absolute position.

    I've only dealt with relatively slow encoders.

    I don't suppose you have a source a motor encoder combo which would tax the Prop the way you describe?

    Thanks for the links to the encoder chips. I'll probably get a couple to try.
  • Hi Duane,

    Well the complete kit involves the servo drive also. This is the Emerson/Control Techniques Unidrive range that I am mainly working with. The nominally rated 6,000 RPM servo motor is momentarily pushed to a higher RPM and it is equipped with a 4096 line encoder (16,384 quad counts/rev).
    PropBASIC ROCKS!
  • Mickster wrote: »
    jmg wrote: »
    What part did you choose ?
    I'm glad you asked because I forgot to thank you for finding it for me, several years ago :-D
    I have sixteen of THESE on order.
    I think mentioned was LSI-LS7366R etc
    I see the LSI-LS7082N is a rather old looking 10V CMOS device spec's down to 4.5v, and at that 4.5v spec is ~ 4.75MHz Max

    The LSI-LS7366R specs 20MHz clk at 3v3

    The LSI-LS7082N function of Quad pins to CkUP and CkDN, you can fit into a SPLD,
    and I think doable is
    a Pair of Quad->UP/DN clocks in an ATF16V8BQL
    and 5 pairs in ATF750xx, and 7 or 8 pairs in ATF1502

    Not sure of the MHz, but 20MHz or 40MHz state clock should be possible.




  • jmg wrote: »
    I think mentioned was LSI-LS7366R etc
    I see the LSI-LS7082N is a rather old looking 10V CMOS device spec's down to 4.5v, and at that 4.5v spec is ~ 4.75MHz Max

    Oh 4.75MHz will have me well covered. For SPI type devices, I have ordered one of THESE to play with.
    jmg wrote: »
    The LSI-LS7082N function of Quad pins to CkUP and CkDN, you can fit into a SPLD,
    and I think doable is
    a Pair of Quad->UP/DN clocks in an ATF16V8BQL
    and 5 pairs in ATF750xx, and 7 or 8 pairs in ATF1502
    You're whetting my appetite again, dammit.

    PropBASIC ROCKS!
Sign In or Register to comment.