Simple Servo Position Control Program - Is this right?


Closed Thread
Results 1 to 11 of 11

Hybrid View

  1. #1
    Join Date
    Oct 2010
    Location
    Northern Colorado
    Posts
    19


    Did you find this post helpful? Yes | No

    Default Sweet!

    This will only send a single a pulse to servo because the Pulsout is outside of the for next-loop. On top of that you are pausing 1000ms (1 second) each time thru the loop. I'd try something like:
    Code:

    For I = 0 to 100
    Pulsout PortA.1, 100
    Pause 19 'Pause 19ms for a total of 20ms which is 50Hz
    NEXT
    Thanks for the help. That makes sense now that I think about it. The timing of it was probably the biggest problem I was having.

    With moving the servo back to its "zeroed" position- I was thinking that if I send it one pulse to lift it up at the end of the one second test, so that it doesn't sit there until it decides to return to its "zeroed" position on its own. So, with the one pulse I send it at the end, I am helping the servo return to its natural "zeroed" position. Does that make sense?

    I am going to do the programing and wiring here in a bit and play with the actual position of the servo in relation to the pulse width. Hopefully all goes smoothly.

    -Marcus

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default

    Does that make sense?
    Yeah, kind of. But it won't work if the mechanical load on the servo doesn't happen to be exactly as much as is needed to "coast" back to "zero" with the help of a single pulse.....

    I'm pretty sure the servo won't decide to move anywhere on its own. It might move due to external load on it if you don't "refresh" it continously though.

    So, when you're moving it back to "zero", do something similar to when you're moving into position, ie. pulse it at least enough times to make sure it reaches position.

    Good luck!

  3. #3
    Join Date
    Oct 2010
    Location
    Northern Colorado
    Posts
    19


    Did you find this post helpful? Yes | No

    Default Makes sense...

    Ok. I wasn't thinking about the load on the servo. What I think I'll do then is put the pulse that controls the "zero" position in the loop that is waiting for the button to be pressed (so that it is "zeroed" when button is NO), then have the movement pulse in the second loop.


    Code:
    'Continuous loop until triggered by ignition button
    buttonloop:
    	
    Pulsout PORTA.1, 150			'pulse to servo for a length of 1.5 ms to move to "zeroed" position
    
    If (BUTTON=0) Then goto buttonloop
    	Pause 10
    
    If (BUTTON=1) Then goto positionloop
    
    goto button loop
    
    'Servo position control loop
    
    positionloop:
    
    		
    FOR I=1 TO 100
    	Pulsout PORTA.1, 100		'pulse to servo for a length of 1 ms to rotate servo CCW certain number of degrees		
    	Pause 19			'pulse to servo every 10 ms for a total of 1 second
    NEXT
    
    goto buttonloop
    
    End 					'end of program never reached

    Thanks!

  4. #4
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,653


    Did you find this post helpful? Yes | No

    Default

    Hi, Marcus

    this one should work as desired ...

    Code:
    '****************************************************************
    '*  Name    : GrassBurner.BAS                                   *
    '*  Author  : Acetronics                                        *
    '*  Notice  : Copyright (c) 2010                              *
    '*          : All Rights Reserved                               *
    '*  Date    : 23/12/2010                                        *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*          :                                                   *
    '****************************************************************
    '
    @ __config _CONFIG1, _INTRC_IO & _WDT_ON & _LVP_OFF & _CP_OFF
    ' DEFINES
    Define OSC 8
    Define BUTTON_PAUSE 0
    ' Internal Osc 8Mhz
    OSCCON = %01110010
    ' Turn off A/D conversion - Digital Inputs
    ADCON0 = 0
    ANSEL = 0
    ' Comparators Off
    CMCON  = 7
     
    'Define variables and pins
    I         VAR BYTE
    Position var WORD
    Delay  var Byte
    OldButton  var bit
    PORTA  = 0
    TRISA   = %11111101
    BUTTON_  VAR PORTA.0
    SERVO  VAR PORTA.1
     
    buttonloop:     ' Button check loop
     OldButton = 0
     LOW Servo
     Pulsout SERVO, 300  ' pulse to place servo to neutral
     Pause 19
     
    BUTTON BUTTON_,1,255,0,Delay,0,Buttonloop
     OldButton = 1       ' Launched ... We've pressed it !!!
    '******************************************************************************
    positionloop:  'Servo position control loop
     
    I = 0       ' Reset time counter
    While ( OldButton  AND ( I < 75 ))   '  if button has been pushed and time < 1.5s
     
     IF I >= 50 THEN     ' 1 second is ... 50 x 20 ms !    
      position = 300
     ELSE 
      POSITION = 200
     ENDIF 
     
     LOW Servo
     Pulsout SERVO, Position  ' pulse to servo 
     
     PAUSEUs 19813 - ( Position * 5 )        ' time between pulses
     
     I = I+1                         'Increase Time counter
    Wend                                ' go for seeking a new button push ...
     
    goto buttonloop
    End         'end of program supposed never reached
    may be you'll have to modify a bit the " @ __config ......" line if you use PM as an assembler.

    Also correct " IF I >= 50 ..." to i.e. " IF I >= 55 " to take servo positionning time into account ... knowing 1 unit is 20 ms.

    Alain
    Last edited by Acetronics2; - 23rd December 2010 at 13:17.
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  5. #5
    Join Date
    Oct 2010
    Location
    Northern Colorado
    Posts
    19


    Did you find this post helpful? Yes | No

    Default Thanks!

    Alain,

    Thanks for that code. I had some of my own code that was partially working (servo would only go one direction) that I was in the lab troubleshooting right now. But, I think I might break your code down a little bit to where I'll have two buttons controlling the CW and CCW movement. That way I can make sure I fully understand the overall process of the code.

    Thanks again.

    -Marcus

  6. #6
    Join Date
    May 2010
    Location
    Chile
    Posts
    25


    Did you find this post helpful? Yes | No

    Default Re: Simple Servo Position Control Program - Is this right?

    I've made some code that might help you.
    It was for a high voltage SPDT servo switch for my research.

    It sends a 1 second burst signal to the servo and then release it.
    Usually thats more than enough time for the servo to react

    Code:
    '//ON INITIAL CONFIG
    A      VAR BYTE  'counter
    SerPos var word  'servo position variable
    
    sers var PORTB.0 'servo signal pin out
    
    '//ON MAIN PROGRAM ROUTINE
    '-Set servo position
    serpos = 1300 'uS   pulse width: 0º -> 1000uS / 180º -> 2000uS
    gosub servout 'send pulse for 1 second
    
    '//ON SUBROUTINES
    servOUT: 'sends servo a PWM position signal for 1 sec.
    for a = 0 to 59  '60hz
        Sers = 1
        pauseus serpos
        Sers = 0
        PAUSEUS 2000-serpos '2ms TOTAL
        pauseus 14667 '2+14.667ms = 16.667ms -> 60hz  -> 1seg total refresh time
    next a
    
    return
    "If at first doesn't work, kicking it wont help either"

  7. #7
    Join Date
    Oct 2010
    Location
    Northern Colorado
    Posts
    19


    Did you find this post helpful? Yes | No

    Default Re: Simple Servo Position Control Program - Is this right?

    Not to bring up a dead subject, and I am not sure if anybody is going to have any interest in helping out. But if I am using a code similar to Alain's that he posted above ^^^, how can I slow down the movement of the servo? Basically, the servo goes straight from one point to another. I want to add something that will make it so that rather then jumping from position one to position two and back again that it takes, say 10 seconds, to gradually move from position one to position two. I have an idea in mind to basically have it move from say position 200 to 300 by 1 every .1 seconds so that after 10 seconds it has reached the second position. I would think a counting function or something would work so that it would go
    Code:
    IF I >= 50 THEN
    position=200
    pause 100
    position=201
    pause 100
    position=202
    pause 100
    ...
     ELSE 
      POSITION = 200
     ENDIF
    And if that is what it takes that I need to type out the whole process count down then so be it. But I would think there would be an easier option..

    Application: My problem right now is that there is a 4 inch piece of copper rod on the servo with a ceramic insulator attached to the end of that copper arm. So whenever it moves from position one to position two, the momentum of the mass of the ceramic insulator is causing the servo to overshoot its programmed position. Maybe its a servo issue, but I thought I would start with this.

    Any thoughts or help?
    Last edited by marcusvm; - 28th March 2011 at 04:51.

Members who have read this thread : 0

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

Tags for this Thread

Posting Permissions

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