read current servo position?

drew45

New Member
Hi, is it possible to read the current servo position? Why I ask is from a known position I can step the servo gracefully to a reference/ origin position. I'm using picaxe08M thanks
 

alband

Senior Member
Definitely.:) It just depend on your requirements.
As you may know, servos have a POT (potentiometer) built into them. I am not 100% sure, but I would have though it wouldn't upset the servo too much to sample that.
You could also add your own external POT to measure it.

Why do you want to do this though? :confused: The idea of a servo is to eliminate the requirement of the user creating a feedback loop - the servo already has one, you just need to tell it where you want it to be in the form of a pulsewidth.
 

drew45

New Member
thanks, I see what you mean. I have some stuff that the servo rotates 'direct drive' that I would like to move gracefully, in case any fingers are in the way. once the position is known I can step it +- with a servo pause to reduce speed
 

alband

Senior Member
So a smooth start/stop?

In that case some kind of code could be used to make a smooth start or stop.
Something along the lines of:
Work out the start and stop positions.
Work out the difference and thus the number of steps.
Divide by ten.
Then take the fist tenth and last tenth and smooth the pause between them.
 

goom

Senior Member
Would this code help? Goes between the receiver and servo to slow down the rate at which it rotates.
Code:
'Radio control servo slowdown using PICAXE-08M
'Kevin Goom, 17 October 2005
'
'PICAXE-08M connections are:
' Leg 1                   +5V
' Leg 2 (Serial in)       Tie to Ground through 10K resistor
' Leg 3 (In4/Out4)        Wiper of 10K potentiometer connected to +5V and ground
' Leg 4 (In3)             Pulse input from radio receiver
' Leg 5 (In2/Out2)        Pulse output to servo
' Leg 6 (In1/Out1)        Mode indicator output
      '1/2 second flash = no valid signal
      'Steady on = pass-through (no servo slowdown)
      'Flicker = servo slowdown mode
' Leg 7 (Out0/Serial Out) NC
' Leg 8                   Ground
symbol Delay=b8                                'Name the delay factor
symbol PWin=w0                                 'Name the input pulse length
symbol PWout=b2                                'Name the output pulse length
symbol PWinPrev=b3                             'Name the length of the prior input pulse length
symbol PWinErr=b6                              'Name the difference between input and output pulse lengths
symbol skip=b4                                 'Name the counter for skipping "Delay" times
restart:
   Skip=0
   high 1
   servo 2,135                                'Center the servo initially and on input pulse loss
   Pause 500                                  'Wait 1/2 second initially
   toggle 1
   readadc 4,Delay                            'Read the voltage from the delay potentiometer
   pulsin 3,1,PWin                            'Measure the input pulse width initially
   if PWin<75 or PWin>225 then restart        'Go back if no valid input detected
   high 1
   low 2                                      'Stop the sevo command if valid input detected
   PWinPrev=PWin                              'Initially set the prior pulse width to current pulse width
   if Delay<5 then StraightThru    'If delay pot set near zero skip slowdown routines
   Delay=Delay/21                             'Set delay to 0 (1.5s stop-to-stop) to 12 (20s stop-to-stop)
   PWout=PWin                                 'Set output pulse to input pulse initially
loop_:
   toggle 1
   PWinPrev=PWin                              'Reset the prior pulse width
   pulsin 3,1,PWin                            'Measure the input pulse
   if PWin<75 or PWin>225 then restart        'Go back if no valid input detected
   PwinErr=PWin-PWOut
   if PWinErr<2 or PWinErr>254 then StayPut   'Add 2 units of hysteresis
   if PWout<PWin then MoveUp
   if PWout>PWin then MoveDown
MoveDown:                                     'Routine to decrease the output pulse width
   if skip>=Delay then Skip1                  'Loop to delay change to Delay x 20ms input periods
      Skip=Skip+1
      goto Skip2
  Skip1:
     Skip=0
     PWout=PWout-1
  Skip2:
     pulsout 2,PWout                          'Send the output pulse to the servo
     goto loop_                               'Return to re-measure the input pulse
MoveUp:                                       'Routine to increase the output pulse width
   if skip>=Delay then Skip3                  'Loop to delay change to Delay x 20ms input periods
      Skip=Skip+1
      goto Skip4
  Skip3:
     Skip=0
     PWout=PWout+1
  Skip4:
     pulsout 2,PWout                          'Send the output pulse to the servo
     goto loop_                               'Return to re-measure the input pulse
StayPut:                                      'Routine to send the same output pulse
   pulsout 2,PWout
   goto loop_                                 'Return to re-measure the input pulse
StraightThru:
   pulsin 3,1,PWin
   if PWin<75 or PWin>225 then restart        'Go back if no valid input detected
   PwinErr=PWin-PWinPrev
   if PWinErr<2 or PWinErr>254 then Stay      'Add 2 units of hysteresis
   pulsout 2,PWin
   PWinPrev=PWin
   goto StraightThru                          'Return to re-measure the input pulse
   Stay:
   pulsout 2,PWinPrev          'Set output pulse to input pulse
   goto StraightThru                          'Return to re-measure the input pulse
 

Wrenow

Senior Member
Hmmm. In framing the question, it seems you may be missing some gits about how a servo works. I am assuming you are working with the ubiquitous radio control hobby servos.

When you give a servo a position command, the brain in the servo then moves the servo to a given position, and stops when it gets there based on a reading of an internal pot attached to the drivetrain. Since the servo always goes to the signaled position the position is always "known" (unless the servo is broken or something is overpowering it).

Illustration: Assuming a given servo has a range of 100-200, middle being 150.
If you give a pulse stream of 150 every 20ms, the servo will go to the middle if it is not already there, or will hold that middle position if it is there. So you know it is in the middle. If you want to move it to the maximum throw, 200, just change the pulse to 200 and the servo will go in that direction untill it reaches position 200 and then will hold that position as long as it is getting the pulse stream.

If you want to slow thee servo down on its move from 150 to 200, all you have to do is send the pulses in gradually increasing lngths until you reach the pulse length you want. If you have reached a pulse length of, say, 175, you know that the servo has moved to the 3/4 wide open position (assuming 200 is open, 100 is closed), again, assuming a properly functioning servo that has not been overpowered. If the servo is blocked from reaching that position, and the blockage is removed, it will then move there. As long as the signal is being applied, it will troy to reach/hold that position.

If you need a confirmation of its position (to see if it has functioned properly, you should be able to tap into the wiper of the internal pot with a READADC, or add another pot or limit switches or other sensors to double-check.

This is not to be confused with a stepper motor, which moves a certain number of degrees when you step it, but has no position feedback.

Although you can "step through" the pulse signal widths, I guess, I would not confuse that with how a stepper motor works.

Servos do not work with steps at all, and are just plain old DC motors attached to a gearbox and a position sensor and brain to tell it when to move or not.

I hope this clarifies things a bit.

Cheers,

Wreno
 

Andrew Cowan

Senior Member
To add feedback to the PIC, you would have to add an additional wire between the middle leg of the pot in the servo (open it up), and an ADC pin of the PIC.

A
 

Wrenow

Senior Member
Well one of the "hardware aspect" solutions, anyway.:)

Again the point is, the servo circuitry already has and uses its own internal position feedback (it is built in).

Unless you really need ot double-check to make sure it is not broken or being overpowered, there is no reason to "look over the servo's shoulder," as it were. Trust it to do its job the way it was designed to.

If the worry is something getting in the way (as a finger getting pinched) there are other ways to deal with that problem using switches, sensors, etc. Though most hobby servos are not all that strong.

One situation where reading the wiper from the pot might be useful is where you need something else to happen when the servo reaches its commanded position. Borrowing from RC Model Warship Combat, you might want your fire control system to only allow the guns to fire (enabled) once the guns have rotated to the commanded position (on target) and disabled until they are on target.

In practice, however, this is not really necessary (in this application). First, servos are pretty quick (unless you intentionally slow them down). Second, in this example, you need to be able to visually confirm your target anyway, so you can see if your guns are aimed properly. This also adds an additional failure/error point that is usually overkill.

Cheers,

Wreno
 
Top