Servo

This documents the Servo library for controlling RC servomotors. It is implemented as a thin layer over the built-in timer peripherals.

You can use this library in the IDE by choosing the Servo item under the Sketch > Import Library... menu.

If you are using the Unix toolchain, the library is located in the /libraries/Servo/ libmaple directory.

Servo Class Reference

You can construct a Servo object by including the declaration

Servo servo;

in your sketch. This will create a Servo object called servo. You can then use any of its methods; for instance, to control a servomotor attached to pin 9, you could write

servo.attach(9);
class Servo

Class for interfacing with RC servomotors.

Public Functions
Servo()

Construct a new Servo instance.

The new instance will not be attached to any pin.

bool attach(uint8 pin, uint16 minPulseWidth = SERVO_DEFAULT_MIN_PW, uint16 maxPulseWidth = SERVO_DEFAULT_MAX_PW, int16 minAngle = SERVO_DEFAULT_MIN_ANGLE, int16 maxAngle = SERVO_DEFAULT_MAX_ANGLE)

Associate this instance with a servomotor whose input is connected to pin.

If this instance is already attached to a pin, it will be detached before being attached to the new pin. This function doesn’t detach any interrupt attached with the pin’s timer channel.

Parameters:
  • pin -

    Pin connected to the servo pulse wave input. This pin must be capable of PWM output.

  • minPulseWidth -

    Minimum pulse width to write to pin, in microseconds. This will be associated with a minAngle degree angle. Defaults to SERVO_DEFAULT_MIN_PW = 544.

  • maxPulseWidth -

    Maximum pulse width to write to pin, in microseconds. This will be associated with a maxAngle degree angle. Defaults to SERVO_DEFAULT_MAX_PW = 2400.

  • minAngle -

    Target angle (in degrees) associated with minPulseWidth. Defaults to SERVO_DEFAULT_MIN_ANGLE = 0.

  • maxAngle -

    Target angle (in degrees) associated with maxPulseWidth. Defaults to SERVO_DEFAULT_MAX_ANGLE = 180.

Side Effects::

May set pinMode(pin, PWM).

Return:

true if successful, false when pin doesn’t support PWM.

bool attached()

Check if this instance is attached to a servo.

Return:true if this instance is attached to a servo, false otherwise.
See:Servo::attachedPin()

int attachedPin()

Get the pin this instance is attached to.

Return:Pin number if currently attached to a pin, NOT_ATTACHED otherwise.
See:Servo::attach()

bool detach()

Stop driving the servo pulse train.

If not currently attached to a motor, this function has no effect.

Return:true if this call did anything, false otherwise.

void write(int angle)

Set the servomotor target angle.

Parameters:
  • angle -

    Target angle, in degrees. If the target angle is outside the range specified at attach() time, it will be clamped to lie in that range.

See:

Servo::attach()

int read()

Get the servomotor’s target angle, in degrees.

This will lie inside the range specified at attach() time.

See:Servo::attach()

void writeMicroseconds(uint16 pulseWidth)

Set the pulse width, in microseconds.

Parameters:
  • pulseWidth -

    Pulse width to send to the servomotor, in microseconds. If outside of the range specified at attach() time, it is clamped to lie in that range.

See:

Servo::attach()

uint16 readMicroseconds()

Get the current pulse width, in microseconds.

This will lie within the range specified at attach() time.

See:Servo::attach()

Arduino Compatibility

The Servo class provides a public interface identical to the Arduino version’s documented functionality (as of Arduino 0021), so in most cases, this library will be a drop-in replacement.

However, there are some differences, essentially at the level of implementation details.

The major difference is that while the Arduino implementation drives servos with “bit-banged” PWM (in the sense that timer interrupt handlers are used to manually toggle pins), the Maple implementation uses timers to drive the PWM directly.

Consequently, the Maple implementation only allows Servo instances to attach to pins that support PWM.

To determine if a pin supports PWM, you can either check if “PWM” appears next to its number on your board’s silkscreen, or look for it in the list of boardPWMPins in your board’s hardware documentation.

RC Servos expect a pulse approximately every 20ms. In the Maple implementation, periods are set for entire timers, rather than individual channels. Thus, attach()ing a Servo to a pin can interfere with other pins associated with the same timer[1].

Because of this, we recommend connecting multiple servomotors to pins which share a timer, in order to keep as many timers free for other purposes as possible. Consult your board’s Timer Pin Map to match up pins and timer channels.

And here’s some fine print:

  • Although it is not publicly documented to do so, the Arduino implementation of attach() returns the timer channel associated with the newly-attached pin, or 0 on failure (as of Arduino 0021). The Maple implementation returns true on success, and false on failure (and this is its documented behavior).
  • In another bit of undocumented behavior, the Arduino implementation of write() also treats its argument as an angle or a pulse width depending on its value. This is a bad idea, and we don’t do it.

Footnotes

[1]The Arduino implementation also captures timer channels in groups as more Servo objects are attached, but the details of which channels have their periods reset when are slightly different.