Instant Int and encoder (Elect. Gearing)


Closed Thread
Results 1 to 14 of 14

Hybrid View

  1. #1
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default Progress, but not right yet...

    Hi All,
    Been banging my head for a while now and I am getting closer. Thank you for the time you have taken to add life to this forum.

    The Travel encoder section works pretty well, but the Manual encoder is erratic and sometimes take over the travel section and not let it work. A bump on Manual, and the Travel works again.

    As a reminder. The Travel generates Pulse and Direction in one direction only. The Manual is for bi-directional fine adjustment after the Travel section's movement is complete (automatic). Target: 12F675 @ 4mHz INT_OSC

    Anybody see what I'm missing?
    Thanks
    Bo
    Code:
    A_trav  VAR GPIO.0          'Travel encoder A  input
    B_trav  VAR GPIO.1          'Travel encoder B  input
    A_man   var GPIO.2          'Manual Encoder A input
    B_man   var GPIO.3          'Manual Encoder B input
    P_out   var GPIO.4          'Pulse output to motor
    D_out   var GPIO.5          'level output for direction                               
    Dir         VAR bit            'Direction
    Scratch     var byte            'dummy byte
    Old_Bits    VAR BYTE
    New_Bits    VAR BYTE
    TravEncOld  var byte            'TRAVel Measurement ENCoder
    TravEncNew  Var byte            '
    ManEncOld   var byte            'MANual input ENCoder
    ManEncNew   var byte            '
                 
    P_out = 1                   'servo I/P = LO pulse, start HI 
     
    INTCON = %10001000          'GLOBAL ON, GPIO Int ON
    CMCON =  7                   'Comparator off, Digital I/O
    OPTION_REG = %00000000      'GPIO Pull-up Enabled
    TRISIO = %001111 
    WPU = %000111               'pull-ups 0-2 (3 added on board) 
    IOC = %001111               'Int On Change GPIO 1-3
    ANSEL = 0
    
    INCLUDE "DT_INTS-14-0.bas"     '..-14-0 = ALL Banks REM'd 
    
    ASM
    INT_LIST  macro    ; IntSource,    label,  Type, ResetFlag?
            INT_Handler    RBC_INT,  _EncChg,   ASM,  yes
        endm
        INT_CREATE                   ; Creates the interrupt processor
        INT_ENABLE   RBC_INT         ;RB Port Change Interrupt
    ENDASM                                           
    
    Old_Bits = GPIO & (%001111)                 'Get initial inputs
    
    Main:
             
    GOTO Main
    
    '---[RBC - interrupt handler]---------------------------------------------------
    EncChg:
        New_Bits = GPIO & (%001111)                'Get inputs
        TravEncNew = New_Bits & (%000011)          'strip New Travel encoder
        TravEncOld = Old_Bits & (%000011)          'Strip Old Travel Encoder
        if TravEncNew = TravEncOld then ManEnc   ' If no chg -> Manual Encoder
        Dir = TravEncNew.1 ^ TravEncOld.0            'Check direction
        D_out = Dir                                  'Direction LEVEL out
        if Dir = 1 then                              'Only travel 1 direction
        pulsout P_out,20                             'drive servo controller 
        Endif                                'Controller is STEP/DIRECTION I/P
        goto DoneRotEnc                      'skip Manual Encoder
             
    ManEnc:            
        ManEncNew = New_Bits & (%001100)           'strip Manual Encoder
        ManEncOld = Old_Bits & (%001100)
        Dir = ManEncNew.3 ^ ManEncOld.2           'Direction of Manual input
        D_out = Dir
        pulsout P_out,20                        'Pulse for either direction
    
    DoneRotEnc:
         Old_Bits = New_Bits                    'reset reference 
         Scratch = GPIO                         'read GPIO to clear mis-match
    @ INT_RETURN
    Last edited by boroko; - 21st March 2008 at 07:14. Reason: Add Processor Info

  2. #2
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    The interrupt type should be PBP.
    Code:
    ASM
    INT_LIST  macro    ; IntSource,    label,  Type, ResetFlag?
            INT_Handler    RBC_INT,  _EncChg,   PBP,  yes
        endm
    And you'll need to INCLUDE "ReEnterPBP.bas", for it to work.
    DT

  3. #3
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default

    Thanks,
    I need to point out that this in on a 12F675.

    I commented out the bank lines in DT_INTS-14 (hence the "DT_INTS-14-0.bas" on the include)
    and removed ReEnterPBP

    I tried to use things in the way that was discussed in http://www.picbasic.co.uk/forum/show...9510#post49510

    Does that help this make sense a bit more?

    Thanks
    Bo

  4. #4
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by boroko View Post
    Does that help this make sense a bit more?
    Yes it does.

    Since you don't have anything in the Main loop, you can probably get away with it.
    But the PULSOUT statement uses PBP system vars. So if you add anything to the the Main loop, something will need to be changed.

    I'm wondering how you got past the GPIF/GPIE problem. Should have been something like this ...
    Code:
    ASM
    RBIF = GPIF
    RBIE = GPIE
    INT_LIST  macro    ; IntSource,    label,  Type, ResetFlag?
            INT_Handler    RBC_INT,  _EncChg,   ASM,  yes
        endm
    As for the main problem, the only thing I can see that might cause it is the Scratch = GPIO at the end of the handler.

    The mismatch is cleared in the first line New_Bits = GPIO & (%001111)

    Reading it again at the end of the handler, may be causing it to miss changes on the port. Try commenting it out.

    Still looking.
    <br>
    DT

  5. #5
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default servo feed revisited

    Back to this project.
    Imagine a sewing machine. When the needle goes down, the thread is held steady and travels with the needle. When the needle goes up, the thread is fed out at the same rate that it travels up, feeding slack. There is a servo motor with an encoder feeding the thread and a matching encoder reading the travel distance and speed. There is also an aux encoder (ManDrive) that can be used to retract or feed the thread to trim or allow for excess so you can cut the thread. The manual feed/trim works as expected, but after a manual encoder change, sometimes the travel feed operates on both directions of input from the travel encoder instead of just retract. The feed is the correct direction, but when bad, the "down" feeds at twice the input rate while the "up" feeds normally. A change on the Man encoder allows it to work correctly again.
    Code:
    ' 1) Quadrature encoder reading direction and speed of mechanical slide.
    ' 2) Motor (servo) driven in ONE direction of slide movement, 
    '    not driven for other direction. Pulse & Direction drive LOW.
    ' 3) Manual Encoder to drive servo either direction manually.
    '    ADD pull-up to GPIO.3 on 12F675
    ' DEBUG splash on power-up on GPIO.5
    '                  12F675
    '                    -----------u----------
    '                  -|Vdd(+)              (-)Vss |-         
    '   D_out       -|GP5                GP0/PGD|-  A_trav       
    '   P_out       -|GP4                GP1/PGC|-  B_trav        
    '   B_man      -|GP3/MCLR/Vpp  GP2/INT|-  A_man     
    '                   ----------------------  
    DEFINE DEBUG_REG GPIO 
    DEFINE DEBUG_BIT 5
    DEFINE DEBUG_BAUD 2400     '
    DEFINE DEBUG_MODE 0 
    DEFINE OSC 4	
    clear
    A_trav  VAR GPIO.0          ' Travel encoder A  input
    B_trav  VAR GPIO.1          ' Travel encoder B  input
    A_man   var GPIO.2          ' Manual Encoder A input
    B_man   var GPIO.3          ' Manual Encoder B input
    P_out   var GPIO.4          ' PULSE output to motor, Active LOW
    D_out   var GPIO.5          ' LEVEL output for direction                     
    AutoCnt     var word            'preprogrammed feed @ end of cycle
    Dir         VAR byte             'Direction
    EncOld      var byte
    EncNew      var byte
    ManCnt      var byte            'Counter for recent Man Pulses
    TrvCnt      var byte        ' Travel Encoder before change 
    INTCON = %10001000          ' GLOBAL ON, GPIO Int ON
    CMCON =  7                  ' Comparator off, Digital I/O
    OPTION_REG = %00000000      ' GPIO Pull-up Enabled
    TRISIO = %001111 
    WPU = %11111111             ' weak p/u on 0-2,4,5, GPPU must be enabled for p/u
    IOC = %00001111             ' Interrupt on Change for GPIO: 0-3
    ANSEL = 0                   ' Analog off
    ManCnt = 0
    TrvCnt = 0 
    P_out = 1                   ' start out HI. Moves on LOW pulse 
    INCLUDE "DT_INTS-14-0.bas"    'Base Inturrupt program:0 banks
    'include "ReEnterPBP-0.pbp"    'allow PBP int
    
    ASM
    RBIF = GPIF
    RBIE = GPIE
    INT_LIST  macro    ;IntSource,   Label,  Type,   ResetFlag?
        INT_Handler     RBC_INT, _EncChg, ASM, yes
        endm
        INT_CREATE          ;creates the INT processor
        INT_ENABLE  RBC_INT         ;enable RB change int 
    ENDASM 
    debug "LW-FiberDrive-7"
    
    Main:
    ManualDrive:                               ' MANUAL first: set direction bit 
          if ManCnt > 0 then
           Dir = EncNew.3 ^ EncOld.2    ' XOR new L bit > Old Rt bit=Direction
           D_out = Dir                             'set direction pin
           pauseus 2
           P_out = 0                               'send drive pulse either dir
           pauseus 2
           P_out = 1                               'reset drive pulse 
           ManCnt = ManCnt - 1                     ' empty out pulse counter
          endif
          D_out = 1                             'set direction pin
    TravelDrive:
          D_out = 1                             'set direction pin
          if TrvCnt > 0 then     
           Dir = EncNew.1 ^ EncOld.0    ' XOR new L bit > Old Rt bit=Direction
            If DIR = 0 then TravDown                'end if travel DOWN
           
           pauseus 2
           P_out = 0                               'send drive pulse retract only
           pauseus 2
           P_out = 1                               'reset drive pulse 
    TravDown:
           TrvCnt = TrvCnt - 1
          endif 
    goto main
           
    '++++++++ Motor Drive Pulse Out interrupt handler ++++++++++++++++++
    EncChg:            'got here if GPIO 0-3 changed
         EncOld = EncNew
         EncNew = GPIO
         if (EncNew & (%00001100)) = (EncOld & (%00001100))then ' man enc same?
            TrvCnt = TrvCnt + 1     ' trav moved: count travel interrupts        
         endif
         ManCnt = ManCnt + 1     ' else: Man moved:count man interrupts 
    @ INT_RETURN 
    end
    Anyone care to take another look?

  6. #6
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default

    HI all,
    I'm in the process of moving this over to a larger PIC so that I can have a chance to get some debugging info out of it. I have some 16F627's that will run at 20MHz instead of the 12F675 @ 4MHz. That will allow some HSEROUT data to give me a better look at what's happening and some headroom in the speed area. Thought I could just whip this one out, but alas, too big for my pants again...
    Bo

  7. #7
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default

    HI all,
    I moved this to a 16F627 and made the code as straight as I could.

    The problem is much like it has been for a while: The direction signal is erratic and can be tricked by interaction with the other encoder.

    Any thoughts would be appreciated.
    Code:
    '****************************************************************
    '*  Notes   :  16F627@20mhz, HS_OSC                             *
    '*          : PBP 2.50c, MPASM: 5.11,                           
    ' 1) Quadrature encoder reading direction and speed of mechanical slide.
    ' 2) Motor (servo) driven in ONE direction of slide movement, 
    '    not driven for other direction. Pulse & Direction drive LOW.
    ' 3) Manual Encoder to drive servo either direction manually.
    '                        16F627
    '          ----------------u-----------------
    '        -1|RA2/AN2/Vref            RA1/AN1 |18-   direction LEVEL output        
    '        -2|RA3/AN3/CMP1            RA0/AN0 |17-   Step PULSE o/p, Active LOW      
    '        -3|RA4/TOCKI/CMP2   RA7/OSC1/CLKIN |16-        
    '        -4|RA5/MCLR/vpp    RA6/OSC2/CLKOUT |15-              
    '        -5|-- VSS                    VDD++ |14-            
    '        -6|RB0/INT           RB7/T1OSI/PGD |13-   Manual Encoder B input       
    '        -7|RB1/RX/DT  RB6/T1OSCO/T1CKI/PGC |12-   Manual Encoder A input       
    '        -8|RB2/TX/CK                   RB5 |11-   Travel encoder B  input      
    '        -9|RB3/CCP1                RB4/PGM |10-   Travel encoder A  input        
    '          ----------------------------------       
    
    DEFINE OSC 20	
    INCLUDE "AllDigital.pbp"
    clear
    P_out   var PORTA.0          ' Step PULSE output to motor, Active LOW
    D_out   var PORTA.1          ' LEVEL output for direction  
    syncM   var PORTA.2          ' output for testing timing 
    syncI   var PORTA.3                            
    Dir         VAR byte         ' Direction
    EncOld      var byte
    EncNew      var byte 
    OPTION_REG = %00000000       ' Pull-up Enabled
    TRISA = %00000000 
    TRISB = %11110000
    TravEnc  con %00110000
    ManEnc   con %11000000 
    P_out = 1                    ' start out HI. Moves on LOW pulse 
    goto Main      
    '********** Subs *************************** 
    ManDrive:
           Dir = EncNew.7 ^ EncOld.6    ' XOR new L bit > Old Rt bit=Direction
           D_out = Dir                  ' set direction pin
           pauseus 2                    ' minimum 3.5uS for Gecko drive
           P_out = 0                    ' send drive pulse either dir
           pauseus 2
           P_out = 1                    ' reset drive pulse 
    return     
    TravDrive:
           D_out = 1                     ' set direction pin
           Dir = EncNew.5 ^ EncOld.4    ' XOR new L bit > Old Rt bit=Direction
           If DIR = 0 then                  ' end if travel DOWN
            P_out = 0                    ' send drive pulse retract only
            pauseus 2
            P_out = 1                    ' reset drive pulse
           endif  
    return 
    '******* MAIN *********************************************** 
    Main:
          'TOGGLE syncM                  ' pulse to time Main loop
        EncNew = PORTB           ' get the new state of both encoders 
        if (EncNew & ManEnc) != (EncOld & ManEnc) then ' man not same? Drive Man  
          gosub ManDrive
          endif
        if (EncNew & travEnc) != (EncOld & TravEnc) then ' Trav not same? Drive Trav 
         GOSUB TravDrive
         endif     
        EncOld = EncNew          ' save the previous state of both encoders 
    goto main        
    end
    Thanks
    Mark

Similar Threads

  1. Using PICBASIC PRO in MPLAB IDE
    By jblackann in forum General
    Replies: 8
    Last Post: - 4th May 2008, 09:20

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts