Servo

A library for controlling a Radio Control (R/C) model Servo.

R/C Model Servo

Hello World!

Import program

00001 // Hello World to sweep a servo through its full range
00002 
00003 #include "mbed.h"
00004 #include "Servo.h"
00005 
00006 Servo myservo(p21);
00007 
00008 int main() {    
00009     for(float p=0; p<1.0; p += 0.1) {
00010         myservo = p;
00011         wait(0.2);
00012     }
00013 }

Library

Import library

Public Member Functions

  Servo (PinName pin)
  Create a servo object connected to the specified PwmOut pin.
void  write (float percent)
  Set the servo position, normalised to it's full range.
float  read ()
  Read the servo motors current position.
void  position (float degrees)
  Set the servo position.
void  calibrate (float range=0.0005, float degrees=45.0)
  Allows calibration of the range and angles for a particular servo.
Servo operator= (float percent)
  Shorthand for the write and read functions.

This library controls a standard R/C model servo using a PwmOut signal, and provides control of the servo between min and max by setting it to 0.0 - 1.0.

As all servos respond differently, you can also use the calibrate function the range, so 0.0 - 1.0 is the maximum range of the servo.

Details

The underlying PwmOut period is set to 20ms, and by varying the pulsewidth (up to a maximum of 0.5ms to 2.5ms) the position of the servo is changed, usually by around 180 degrees. The library lets you calibrate the exact range.

The servo must connect to a PwmOut, and be supplied with a separate power supply, usually in the range 4.5-6.0v.

Warning

A servo requires higher current than the USB port can safely provide, and so it is essential that you power the servo using an external supply, such as a 4xAA (6v) battery pack or an appropriate DC power adaptor.

/media/uploads/simon/servoschematic.png /media/uploads/simon/servophoto.jpg

Examples

Import program

00001 #include "mbed.h"
00002 #include "Servo.h"
00003 
00004 Servo myservo(p21);
00005 Serial pc(USBTX, USBRX);
00006 
00007 int main() {
00008     printf("Servo Calibration Controls:\n");
00009     printf("1,2,3 - Position Servo (full left, middle, full right)\n");
00010     printf("4,5 - Decrease or Increase range\n");
00011 
00012     float range = 0.0005;
00013     float position = 0.5;
00014     
00015     while(1) {                   
00016         switch(pc.getc()) {
00017             case '1': position = 0.0; break;
00018             case '2': position = 0.5; break;
00019             case '3': position = 1.0; break;
00020             case '4': range += 0.0001; break; 
00021             case '5': range -= 0.0001; break; 
00022         }
00023         printf("position = %.1f, range = +/-%0.4f\n", position, range);
00024         myservo.calibrate(range, 45.0); 
00025         myservo = position;
00026     }
00027 }



4 related questions:


14 comments:

27 Aug 2010

All of the RC servos have the three wire connectors, but the different brands move the three pins around and use different wire color codes. Each company does this to try to lock users into their RC equipment. The info on which pin is which can be hard to find. There is even a company that makes conversion cables! Here is a handy pinout table I found with some pictures:

http://www.horrorseek.com/home/halloween/wolfstone/Motors/svoint_RCServos.html#ServoConnectors

31 Aug 2010

Servos have a drive wheel that is controlled by a PWM coded signal. The servo shown below is a Futaba S3003 which is identical, internally, to the Tower TS53J servo. Radio control servomotors are mass-produced for the hobby market and are therefore relatively inexpensive and consistently available. They are ideally suited for robotics applications. Internally, the servo contains a DC drive motor seen on the left in the image below, built-in control circuitry, and a gear reduction system. They are small, produce a relatively large amount of torque for their size, and run at the appropriate speed for a small robotics drive motor.

/media/uploads/4180_1/servo.png /media/uploads/4180_1/servoinside.png

The control circuitry of the servo uses a potentiometer (variable resistor) that is used to sense the angular position of the output shaft. The potentiometer is the tall component on the right in the image. The output shaft of a servo normally travels 180-210 degrees. A single control bit is used to specify the angular position of the shaft. The timing of this bit specifies the angular position for the shaft. The potentiometer senses the angle, and if the shaft is not at the correct angle, the internal control circuit turns the motor in the correct direction until the desired angle is sensed. The control signal bit specifies the desired angle. The desired angle is encoded using pulse width modulation (PWM). The width of the active high pulse varies from 1-2 ms. A 1ms pulse is 0 degrees, 1.5ms is 90 degrees and a 2 ms pulse is approximately 180 degrees. New timing pulses are sent to the servo every 20 ms.

Normally, a servo has a mechanical stop that prevents it from traveling move than half a revolution. If this stop is removed along with other modifications to the potentiometer, a servo can be converted to a continuously rotating drive motor for robots. You can find web sites showing how to convert a servo for continuous rotation.

23 Sep 2010

If you have the .1" breakaway header pins with long pins on both sides or even wire wrap pins, you can break off a strip of three pins and plug them into the servo cable connector. The servo cable can then plug directly into the breadboard. This works a bit nicer than putting jumper wires directly into the servo cable connector.

/media/uploads/4180_1/_scaled_longsip.jpg

http://www.pololu.com/catalog/product/1065 is seen above. Also available from Sparkfun, http://www.sparkfun.com/products/10158. Many of the right angle header strips will also work.

24 Oct 2010

I am intrigued by the read() function. It would seem to allow us to check that the servo did rotate to the required position, without any hindrance or obstruction. However, I thought that feedback is only available in the very expensive servos. Does this function work for all servos?

24 Oct 2010

@David,

Yes, this does work on all analog servos that have a potentiometer in them.

04 Nov 2010

_How_ does that work?? The servo certainly does not _send_ anything back?

Christoph

04 Nov 2010

When you call read(), it is simply returning where you set it with a write() i.e. the target position. This is mainly so you can easily do things like relative position changes.

It doesn't actually know where the servo is, so can't tell you if the motor has been stalled etc. The closed loop aspect of this type of R/C servo is within the servo itself, so you don't get any feedback.

If you do want lots of control/feedback, something like the digital Dynamixel AX12 Servo might be interesting.

14 Nov 2010

Hi, just wondering what ppl are using to work the code above. Win7 doesn't have a terminal program anymore. So what can I use to interact with supplied code? Should the keys still work even though I can't see output?

15 Nov 2010

Ok so I did a search of the site for terminal and found a link to a program called terraterm. Installed it along with latest mbed serial driver and got the code working. Very nice, thanks to the author. For some reason mbed is now on com4? whereas before the new driver was installed it was com3. There are no negative consequences from this that I can see.

13 Jan 2011

...mmm just testing the newly adquired MPC with the "hello world" example and the compiler says it cannot find "Servo.h" ("Cannot open source input file "Servo.h": No such file or directory (E5)" in file "/main.cpp"). Tried to find it at the class doc page, but ain't luck... Someone to point a newbie what to do? I've tried importing from the project window, no way... I'll go on reading, just in case I missed something! Thanks so much!

13 Jan 2011

OOOps! Found! just for the record: http://mbed.org/users/simon/libraries/Servo/le3jpb/docs/Servo_8h_source.html Sorry to bore you all, just put it in case sb finds same difficulty... I guess I have now to include this file as I did with mines (I thought Servo.h was a system-integrated library). Thanks and sorry for so silly question!

01 Sep 2011

Hello. Is there a way using the Servo library to disable the servo line in the event that the user wants the line to just have flat 0V? A disconnect method or similar. I've tried various values with the available functions but do not see a way to do this.

Thanks, Kerwin

17 Oct 2011

Hi, I have a problem while testing the program provided above which is the one setting servo to move full left, middle and full right. From the results that I've obtained, the range between full left and full right was only 90 degree. Was it suppose to be 180degree? Hope that someone could help me out of this. Thanks

12 Oct 2012

This library it doesn't work with LPC11U24

/media/uploads/Romik/lpc-servo.jpg

#include "mbed.h"
#include "Servo.h"

Servo myservo(p26);

int main() {    
    for(float p=0; p<1.0; p += 0.1) {
        myservo = p;
        wait(0.2);
    }
}