Servo command

waltsar

New Member
I've been using the "servo" command to drive an inexpensive R/C servo. I also generate a ramped reference using "for-next". My problem is that the servo "jerks" as it follows the increasing pulse width reference. When I scope the reference pulses, the ramp is smooth from .5 msec to 2.25 msec, no stuttering. I've also tried using the PWM command to ramp the reference from .5 to 2.25 msec with the same results. The for/next loop counts 175 times in 5 seconds to provide the ramp slope; the increments should be invisible to the naked eye, but the rotation can be seen incrementing at about 5 times per second. Any thoughts?

Thanks,
walt
 
Not my field, I'm afraid but it would almost certainly help others if you could post your code. If you haven't done it before, prefix the code with
[ CODE ] (omit the spaces) and postfix it with [/CODE]
 
Here's the code for the project using the servo command.

Note: If rampValue increments 175 times in 5 seconds, then there would be 35 increments per second. The "stutter" I see is about 5 increments per second.

;Picaxe 14M2
Code:
   symbol rampValue = b0                      ; symbol rampValue = b0 ; Variable to store ramp 
     
main:                        
    low b.2                                                ; turns off flasher lites    
    if pinc.1 = 1 then delay                       ; if input c.1 is high, go to "delay:"
    goto main                                           ; if input c.1 is low, repeat

delay:
    high b.2
    wait 3
    goto gateclose

gateclose:
    servo b.1, 50
      for rampValue = 50 to 225 step 1       ; Generate ramp values from 50 to 255
      servopos b.1, rampValue                     ; Send ramp value to servo 
      inc b0
      pause 30                                              ; Adjust pause as needed for the desired ramp speed (was 10)
      next rampValue 
     goto crossing
crossing:
    readadc c.0, b4                                       ; load voltage on input c.0 into register b4
    let w2 = b4 * 200                                   ; multiply value in b4 by 200 and load into register w2
    pause w2                                                ; wait for 0 to 30 seconds                          
    goto gateopen                                       ; raise gate     
gateopen:    
    for rampValue = 225 to 50 step -1  
      servopos b.1, rampValue                      ; Send ramp value to servo                                                                                                                                  dec b0
      pause 30                                               ; Adjust pause as needed for the desired ramp speed (was 10)
      next rampValue
      goto main
 
If rampValue increments 175 times in 5 seconds
b0 register is the same register that you declared as rampValue

Your instruction inc b0 means that you are stepping two counts at a time

Attached is my simplified attempt, which should be an improvement.

I will await your next reply after testing to see if more improvement is needed
 

Attachments

Last edited:
b0 register is the same register that you declared as rampValue

Your instruction inc b0 means that you are stepping two counts at a time

Attached is my simplified attempt, which should be an improvement.

I will await your next reply after testing to see if more improvement is needed
Thanks Hex, That's a rookie mistake for sure... thanks for pointing it out. I'll post again to let you know if that cured the problem.
 
I deleted the extra "inc/dec bo" lines and that improved the "stepping", but only very slightly. Further research uncovered some interesting info. Some makers of low-cost servos actually design in a small delay, 50 to 100msec to minimize hunting around zero position. If that's true of my servo, that might explain the "stutter" because it would only be responding to a position update of about 66 steps per 5 seconds instead of the expected 175.
 
Hi,

Normally, any "hunting" would be controlled by a small amount of "hysteresis" in the comparator, rather than by adding a delay. Low-cost servos might also suffer some physical "backlash" in either their internal drive gears or the linkage to their internal potentiometer. But when any type of d.c. motor is operated from the same power supply rail as a microcontroller, there is a risk of "interaction" (e.g. jitter), so it might be worth experimenting with a separate power supply source (remembering to link the earths) and/or improved supply rail decoupling (capacitors).

It appears that you might be driving "Level Crossing Gates", so perhaps your expectations are too high? Directly connected to gate hinges, the gates could move by around 2 degrees per step, which may be clearly visible to the (human) eye. Servos typically are used with an angular reduction linkage, for example a 180 degrees rotation being reduced to around +/- 30 degrees offset of a 'plane or boat rudder. Perhaps you can add a gear train (if you haven't already), or a geared stepper motor may be preferable to deliver a more realistic gate movement.

You indicated in #1 that you have a 'scope; does it have two channels so that you might compare the servo pulses with the (delay in the) gate/output position? Some servos can be dismantled quite easily to gain access to the (wiper) connection of the feedback potentiometer (to monitor its position and possibly add some hysteresis).

Cheers, Alan.
 
Hi,
I'm just a beginner.
Are you sure this line is correct?
let w2 = b4 * 200 ; multiply value in b4 by 200 and load into register w2
Good luck.............
 
Back
Top