Stuttering Servo


Results 1 to 9 of 9

Threaded View

  1. #1

    Default Stuttering Servo

    I am testing a DT Instant interrupt routine which is supposed to set the length of time that two servos are on or off. Everything works OK except the servos runs very rough. The average position of the servos is correct, but the twitching movement is excessive, making it unuseable. The timing is based on the Elapsed Timer1 Program, from routines found on this Forum. For comparison purposes I have another routine that does not use interrupts, but relies on cycle counting. With this program the servos are smooth and quiet. The cycle counting demo follows here:

    Code:
    'device is PIC 16F684
    
    'set registers
            OPTION_REG.7 = 0     'enable porta pullups    
            CMCON0 = 7           'comparators off
            ANSEL = 0            'porta pins all digital 
            TRISA = %111111      'set porta pins as input
            TRISC = %001101      'set portc pins 0,2,3 as input, all others output
            OSCCON = %1110000    'set internal osc. at 8 mhz, wait for stable freq.
            OSCTUNE = 0          'internal osc. running at factory calibration
    
            DEFINE OSC 8         '8 Mhz oscillator
    
            while OSCCON.2 = 0   'wait for osc.to be stable
            wend
    
    'declare variables
            i       var word         'couting variable
            led     var portc.3      'led output on portc.3
            dummy   var byte         'variable needed to end porta mismatch
            throttlepos var word     'servo1 pulse width in .01 seconds
            servopos    var word     'servo2 pulse width
            pulsecnt    var byte   
    start: 
            low led      'flash red LED for 0.5 sec to show circuit is functioning
            pause 500
            high led  
    
            pause 2000   'delay timer start 2 seconds
            
            portc.1 = 0               'turn off servo
            portc.4 = 0               'initialize servo pulse low
            portc.5 = 0               'initialize throttle pulse low 
            throttlepos = 400         '2*(200)  pulse width adjusted for 8 mhz osc
            servopos = 400            '2*(200)  pulse width adjusted for 8 mhz osc
    
            low Led                    'turn on led
            portc.1 = 1                'turn on servos
            for i = 1 to 500           'run servo for 10 seconds (500 cycles)
            pulsout portc.5,throttlepos                
            pulsout portc.4,servopos
            pause 16
            next 
    
            high Led                  'turn off led
            throttlepos = 200         '2*(100)  pulse width adjusted for 8 mhz osc
            servopos = 400            '2*(200)  pulse width adjusted for 8 mhz osc
    
            for i = 1 to 75           'run servos for 1.5 seconds (75 cycles}
            pulsout portc.5,throttlepos                
            pulsout portc.4,servopos
            pause 16
            next
    
            low Led                   ' turn on led
    
            for i = 1 to 750          'run servos for 15 seconds 750 cycles)
            pulsout portc.5,throttlepos                
            pulsout portc.4,servopos
            pauseus 16100
            next
    
            high led              'turn off led
    
    DT:     high portc.3          'turn off led
            servopos = 200        'DT release position 2*(100)
            pulsecnt = 75         'hold for 1.5 second
            gosub pulse           'this section uses a subroutine to run the servo
            servopos = 400        'home  position
            pulsecnt = 50         'hold for 1 second
            gosub pulse           'return to home position
            goto halt
    
    'subroutine pulse runs the servo  
    pulse:  portc.4 = 0                'initialize servo pulse low     
            for i = 1 to pulsecnt
              pulsout portc.4,servopos
              pause 18
            next
            return
    halt: 
            portc.1 = 0               'turn off servo
            end

    The demo interrupt program is follows here. Two interrupts are used in this case, but it makes no difference; the servos runs rough even when the interrupt on change is taken out. The twitching is still there even if only one servo is used. Any ideas on why the rough running?

    Code:
    'device is PIC 16F684
    
    'set registers
            OPTION_REG.7 = 0     'enable porta pullups    
            CMCON0 = 7           'comparators off
            ANSEL = 0            'porta pins all digital 
            TRISA = %111111      'set porta pins as input
            TRISC = %001101      'set portc pins 0,2,3 as input, all others output
            OSCCON = %1110000    'set internal osc. at 8 mhz, wait for stable freq.
            OSCTUNE = 0          'internal osc. running at factory calibration
    
            DEFINE OSC 8         '8 Mhz oscillator
    
            while OSCCON.2 = 0   'wait for osc.to be stable
            wend
    
    'declare variables
            i       var byte
            led     var portc.3      'led output on portc.3
            MTtime  var word         'target motor runtime in tenths of seconds
            BKtime  var word         'target brake time in tenths of seconds
            DTtime  var word         'target DT time in tenths of seconds
            dummy   var byte         'variable needed to end porta mismatch
            throttlepos var word
            servopos    var word
            pulsecnt    var byte   
    start: 
            low led      'flash red LED for 0.5 sec to show circuit is functioning
            pause 500
            high led  
    
            pause 2000   'delay timer start 2 seconds
            
    INCLUDE "DT_INTS-14 for F684.bas" 'Base interrupt with wsave selected for 16F684
    INCLUDE "ReEnterPBP.bas"          'Using PBP interrupts
    INCLUDE "Elapsed_INT_RI2.bas" 'Elasped timer counting seconds and tenths seconds
    
    ASM
    INT_LIST  macro     ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   RAC_INT,   _RDT,          PBP,  yes
            INT_Handler   TMR1_INT,  _ClockCount,   PBP,  yes
        endm
        INT_CREATE            ; Creates the interrupt processor
    ENDASM
    
    goto overint
    
    '-------Interrupt Handler for RDT------------
    RDT:
       high led                      'turn led off
       dummy = porta                 'needed to end mismatch for porta
       IOCA.4 = 0                    'disable porta.4 interrupt
    @ INT_RETURN
    '--------------------------------------------
    
    overint:
    
        portc.1 = 0               'turn off servo
        portc.4 = 0               'initialize servo pulse low
        portc.5 = 0               'initialize throttle pulse low 
        throttlepos = 400         '2*(200)
        servopos = 400            '2*(200)
        dummy = porta             ' initialize dummy variable
        IOCA.4 = 1                ' enable porta pin 4 for interrupt on change
        MTtime = 100              ' 10.0 second motor run time
        BKtime = 15               ' 1.5 second brake time
        DTtime = 150              ' 15 second glide time
        gosub ResetTime           ' Reset Time to  0d-00:00:00.00
        gosub StartTimer          ' Start the Elapsed Timer
    
    @    INT_ENABLE  RAC_INT       ; Enable PortA Change Interrupt
    @    INT_ENABLE  TMR1_INT      ; Enable Timer 1 Interrupts  
    
            low Led                    'turn on led
            portc.1 = 1                'turn on servo
    main:  
                pulsout portc.5,throttlepos                
                pulsout portc.4,servopos
                pause 17
            if IOCA.4 = 0 then
            goto newtime1              'jump to end-time on interrupt
            endif
            if sum => MTtime then      'stop when target end time is reached
            high led                   'turn off led
            goto newtime1
            endif
    goto main                      'loop until endtime is reached
        
    newtime1:
            gosub StopTimer           ' Stop Timer1
            gosub ResetTime           ' Reset Time to  0d-00:00:00.00
            gosub StartTimer          ' Start the Elapsed Timer
            throttlepos = 200         ' 2*(100) 
            high Led                  'turn off led
            portc.5 = 0               'initialize throttle pulse low 
        
    brake:  
                pulsout portc.5,throttlepos                
                pulsout portc.4,servopos
                pause 17
            if IOCA.4 = 0 then
            goto newtime2              'jump to end-time on interrupt
            endif
            if sum => BKtime then      'stop if elapsed time = target end-time
            low led                    'turn on led
            goto newtime2
            endif
    goto brake
        
    newtime2:
            gosub StopTimer    
            gosub ResetTime           ' Reset Time to  0d-00:00:00.00
            gosub StartTimer          ' Start the Elapsed Timer
            IOCA.4 = 1                ' re-enable porta pin 4 for interrupt on change
            low Led                   ' turn on led
            portc.5 = 0               ' initialize throttle pulse low 
            portc.4 = 0               ' initialize servo pulse low   
        
    glide:
                pulsout portc.5,throttlepos                
                pulsout portc.4,servopos
                pause 17
            if IOCA.4 = 0 then
            goto DT                   'jump to end-time on interrupt
            endif
            if sum => DTtime then     'stop if elapsed time = target end-time
            high led                  'turn off led
            goto DT
            endif
    goto glide
    
    @    INT_DISABLE  RAC_INT       ; Disable PortA Change Interrupt
    @    INT_DISABLE  TMR1_INT      ; Disable Timer 1 Interrupts  
    
    DT:     high portc.3          'turn off led
            servopos = 200        'DT release position
            pulsecnt = 75         'hold for 1.5 second
            gosub pulse
            servopos = 400        'home  position
            pulsecnt = 50         'hold for 1 second
            gosub pulse           'return to home position
            goto halt
    
    'subroutine pulse runs the servo  
    pulse:  portc.4 = 0                'initialize servo pulse low     
            for i = 1 to pulsecnt
              pulsout portc.4,servopos
              pause 18
            next
            return
    
    halt: 
         portc.1 = 0               'turn off servo
         end
    Attached Files Attached Files

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