Shop OBEX P1 Docs P2 Docs Learn Events
Quadrature encoder obex - mod — Parallax Forums

Quadrature encoder obex - mod

jeromelabjeromelab Posts: 31
edited 2010-10-28 04:44 in Propeller 1
Hello,

I am using the Jeff Martin's quadrature object which works fine with the avago HEDR-54xx encoders. Now I am hooking up 5 encoders to the same board and folloowing layout and cabling issues I would prefer having the 5 encoders not being assigned to successive pins (0-1 for fisrt encoder then 2-3 for the next ...) but every 5 pins(0-1 for first, 5-6 for second ...).

I have no experience with propeller assembly. So how would I modify the object so that I can have the 5 pins layout (or even better having a variable to parametrize this increment). I understand there is probably a simple increment somewhere but rather than trying to locate it by hit and miss, I thought I will ask first people who knows...

In attachment, Jeff Martin's object.


Thanks

Comments

  • LukeHLukeH Posts: 22
    edited 2010-10-04 08:37
    You can probably lie to the object, and tell it that there are 16 encoders, but only connect encoders to 0-1, 6-7, 12-13, etc. Just as long as you make sure there is an even number of pins between encoders. Then, just monitor the values in the array that actually have encoders connected to them, and ignore the rest - they will reflect "virtual" encoders that don't exist and won't do anything; even if you have other objects using those I/O pins it should not affect the overall operation of this quadrature decoder object. I haven't tried this object but I think the above approach will work and you shouldn't have to modify any code.
  • jeromelabjeromelab Posts: 31
    edited 2010-10-05 01:23
    Good idea! But I am concerned as I use the other pins for motor control, thus as outputs, and the process is running on another cog. I have also to write the code before having the hardware (motor and encoders) in hand, so I would prefer not to take any risk at it. Here is the assembly code. I understand there are several lines on which there is an increment, but I don't see where the "Pin" variable gets incremented.
    DAT
    'Read all encoders and update encoder positions in main memory.
    'See "Theory of Operation," below, for operational explanation.
    'Cycle Calculation Equation:
    '  Terms:     SU = :Sample to :Update.  UTI = :UpdatePos through :IPos.  MMW = Main Memory Write.
    '             AMMN = After MMW to :Next.  NU = :Next to :UpdatePos.  SH = Resync to Hub.  NS = :Next to :Sample.
    '  Equation:  SU + UTI + MMW + (AMMN + NU + UTI + SH + MMW) * (TotEnc-1) + AMMN + NS
    '             = 92 + 16  +  8  + ( 16  + 4  + 16  + 6  +  8 ) * (TotEnc-1) +  16  + 12
    '             = 144 + 50*(TotEnc-1)
    
                            org     0
                                                                                                    
    Update                  test    Pin, #$20               wc      'Test for upper or lower port
                            muxc    :PinSrc, #%1                    'Adjust :PinSrc instruction for proper port
                            mov     IPosAddr, #IntPos               'Clear all internal encoder position values
                            movd    :IClear, IPosAddr               '  set starting internal pointer
                            mov     Idx, TotEnc                     '  for all encoders...  
            :IClear         mov     0, #0                           '  clear internal memory
                            add     IPosAddr, #1                    '  increment pointer
                            movd    :IClear, IPosAddr               
                            djnz    Idx, #:IClear                   '  loop for each encoder
                                                                    
                            mov     St2, ina                        'Take first sample of encoder pins
                            shr     St2, Pin                
    :Sample                 mov     IPosAddr, #IntPos               'Reset encoder position buffer addresses
                            movd    :IPos+0, IPosAddr                               
                            movd    :IPos+1, IPosAddr
                            mov     MPosAddr, PAR                           
                            mov     St1, St2                        'Calc 2-bit signed offsets (St1 = B1:A1)
                            mov     T1,  St2                        '                           T1  = B1:A1 
                            shl     T1, #1                          '                           T1  = A1:x 
            :PinSrc         mov     St2, inb                        '  Sample encoders         (St2 = B2:A2 left shifted by first encoder offset)
                            shr     St2, Pin                        '  Adj for first encoder   (St2 = B2:A2)
                            xor     St1, St2                        '          St1  =              B1^B2:A1^A2
                            xor     T1, St2                         '          T1   =              A1^B2:x
                            and     T1, BMask                       '          T1   =              A1^B2:0
                            or      T1, AMask                       '          T1   =              A1^B2:1
                            mov     T2, St1                         '          T2   =              B1^B2:A1^A2
                            and     T2, AMask                       '          T2   =                  0:A1^A2
                            and     St1, BMask                      '          St1  =              B1^B2:0
                            shr     St1, #1                         '          St1  =                  0:B1^B2
                            xor     T2, St1                         '          T2   =                  0:A1^A2^B1^B2
                            mov     St1, T2                         '          St1  =                  0:A1^B2^B1^A2
                            shl     St1, #1                         '          St1  =        A1^B2^B1^A2:0
                            or      St1, T2                         '          St1  =        A1^B2^B1^A2:A1^B2^B1^A2
                            and     St1, T1                         '          St1  =  A1^B2^B1^A2&A1^B2:A1^B2^B1^A2
                            mov     Idx, TotEnc                     'For all encoders...
    :UpdatePos              ror     St1, #2                         'Rotate current bit pair into 31:30
                            mov     Diff, St1                       'Convert 2-bit signed to 32-bit signed Diff
                            sar     Diff, #30
            :IPos           add     0, Diff                         'Add to encoder position value
                            wrlong  0, MPosAddr                     'Write new position to main memory
                            add     IPosAddr, #1                    'Increment encoder position addresses
                            movd    :IPos+0, IPosAddr
                            movd    :IPos+1, IPosAddr
                            add     MPosAddr, #4                            
    :Next                   djnz    Idx, #:UpdatePos                'Loop for each encoder
                            jmp     #:Sample                        'Loop forever
    
    'Define Encoder Reading Cog's constants/variables
    
    AMask                   long    $55555555                       'A bit mask
    BMask                   long    $AAAAAAAA                       'B bit mask
    MSB                     long    $80000000                       'MSB mask for current bit pair
    
    Pin                     long    0                               'First pin connected to first encoder
    TotEnc                  long    0                               'Total number of encoders
    
    Idx                     res     1                               'Encoder index
    St1                     res     1                               'Previous state
    St2                     res     1                               'Current state
    T1                      res     1                               'Temp 1
    T2                      res     1                               'Temp 2
    Diff                    res     1                               'Difference, ie: -1, 0 or +1
    IPosAddr                res     1                               'Address of current encoder position counter (Internal Memory)
    MPosAddr                res     1                               'Address of current encoder position counter (Main Memory)
    IntPos                  res     16                              'Internal encoder position counter buffer
    
    
  • kwinnkwinn Posts: 8,697
    edited 2010-10-05 05:04
    Took a quick look at the code and it looks like "pin" does not get updated. The individual encoder data is updated in the ":UpdatePos" routine by the first 5 (ror...wrlong) instructions. You can accomplish what you want to do by adjusting the number of bits the "ror" shifts.
    I did not have time to thoroughly analyze the code so it may require other changes as well.
  • jeromelabjeromelab Posts: 31
    edited 2010-10-05 05:27
    Thanks! I will try that.
  • jeromelabjeromelab Posts: 31
    edited 2010-10-28 04:44
    Didn't work, encoder 1 is fine but encoder 3 is saved in position[1] where normally encoder 2 position should be, and i have nothing from following encoders...

    Seems it needs more work than modifying the "ror".

    Nevermind I found another (hardware) solution.
Sign In or Register to comment.