Servo Jumpy with DT Interrupt


Closed Thread
Results 1 to 10 of 10

Hybrid View

  1. #1
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default

    That is interesting Mike. I had not seen that before. (ccp1x, ccp1y, and the register for ccpr1l are different on the 16f690, so some tinkering required).

    You could also use Darrel's 18F servo code: http://www.picbasic.co.uk/forum/cont...e-Servo-Driver

    If you are not tied to hardware, you could do it (almost) exclusively in hardware with a 18f2431 or a 18f4431 chip. These allow PWM down to 19 hertz on their power control pwm port pins. They have a "single shot mode" which gives the servo a single shot pulse. An interrupt would run at 20 ms to tell the single shot pulse widths when to fire. See the bottom of this wiki for more info: http://www.picbasic.co.uk/forum/cont...-encode-decode
    Last edited by ScaleRobotics; - 1st December 2010 at 16:16.
    http://www.scalerobotics.com

  2. #2


    Did you find this post helpful? Yes | No

    Default

    Guys,

    Thanks for the suggestions. I'll follow your tips and see where they lead. It the meantime, here is a sample of the code that causes the servo to twitch.

    I've observed that the jumps occur about 2 times per second, and are in a direction that a longer pulse width would cause. This supports Jerson's idea that the interrupt service is periodically adding to the pulse width. Maybe it would help if the ISR were written is assembly and therefore be faster?

    Code:
    '****************************************************************
    '*  Name    : servo_demo.pbp                                     *
    '*  Author  : Dick Ivers                                         *
    '*  Date    : Nov 30, 2010                                       *
    '*  Notes   : This is a simplistic demo of servo w/Elapsed Timer *
    '****************************************************************
    '435 program words
    'device is PIC 16F690
     '****************************************************************
    'set device configuration
    @ __config _HS_OSC & _WDT_ON & _MCLRE_ON & _CP_OFF
    
    'set registers
            CM1CON0.7 = 0        'comparator1 off
            CM2CON0.7 = 0        'comparator2 off
            ANSEL = 0            'porta pins all digital 
            ANSELH = 0           'all porta pins digital
    
            DEFINE OSC 16          '16 Mhz oscillator
     
    'declare variables
            led       var portc.5      'led output on portc.5
            servopos  var word
            runtime   var word         'motor runtime in tenths of seconds
    
    start: 
            low led      'flash red LED for 0.5 sec to show circuit is functioning
            pause 500
            high led     'turn off led
    
    
    INCLUDE "DT_INTS-14.bas"      'Base interrupt system
    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   TMR1_INT,  _ClockCount,   PBP,  yes
        endm
        INT_CREATE            ; Creates the interrupt processor
    ENDASM
    
    @    INT_ENABLE  TMR1_INT         ; Enable Timer 1 Interrupts  
    
            runtime = 100             ' run servo for 10.0 seconds
            servopos = 600            ' hold at mid servo range (4*150)
            gosub ResetTime           ' Reset Time to  0d-00:00:00.00
            gosub StartTimer          ' Start the Elapsed Timer
            low Led                   'turn on led
            low portc.4               'turn on servo 
    main:  
            pulsout portc.0,servopos
            pause 18
             if time => runtime then     'stop servo when target time is reached
             high led                    'turn off led
             goto hold
            endif
            goto main                   'loop until endtime is reached
            
    hold:   
    @    INT_DISABLE  TMR1_INT          ; Disable Timer 1 Interrupts  
            high portc.4                'turn off servo
            end
    Attached Files Attached Files

  3. #3
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by scalerobotics View Post
    That is interesting Mike. I had not seen that before. (ccp1x, ccp1y, and the register for ccpr1l are different on the 16f690, so some tinkering required).
    Yes, you would need to change bit labels to match the device you're using. Sorry!

    You could also use Darrel's 18F servo code: http://www.picbasic.co.uk/forum/cont...e-Servo-Driver
    I didn't care for that method (it's not entirely interrupt tolerant) but it probably would work fine for the OP. The odd interrupt interval timing (26.2144-msecs) would make it difficult to use for for general purpose interval timers.

    If you are not tied to hardware, you could do it (almost) exclusively in hardware with a 18f2431 or a 18f4431 chip. These allow PWM down to 19 hertz on their power control pwm port pins. They have a "single shot mode" which gives the servo a single shot pulse. An interrupt would run at 20 ms to tell the single shot pulse widths when to fire. See the bottom of this wiki for more info: http://www.picbasic.co.uk/forum/cont...-encode-decode
    That's an excellent example. Thank you.

    If anyone is interested, here's the link to another example of the PWM "frame" method for 8 or 16 "zero jitter" Servos with 250-nsec pulse width resolution (4000 steps between 1.0-2.0 msecs); 8 or 16 Servos using the PWM module

    Happy Holidays everyone!

    Cheerful regards, Mike
    Last edited by Mike, K8LH; - 2nd December 2010 at 13:57.

  4. #4


    Did you find this post helpful? Yes | No

    Default

    This message is just to close out this discussion in case someone is searching in the future.

    I was not able to implement any of the proposed ideas using the CCP module. The project hardware is stuck with the 16F690. The CCP1 and CCP2 pins are already committed to other functions. The proposed ideas sound good, so I'll try them in the future upon redesign.

    I measured the interrupt service routine of the present elapsed timer using the stopwatch function in MPASM. With a 16 mhz osc the ISR is only 2.5 usec. I don't think this is enough to account for the servo jitter, so the jitter must be coming from somewhere else.

    I've ditched the elapsed timer and gone to servo frame cycle counting to keep track of time. That's working okay.

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