> For the complete documentation index, see [llms.txt](https://monasheng.gitbook.io/zerotohero/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://monasheng.gitbook.io/zerotohero/arduino-zero-to-hero/advanced-skills/servos.md).

# Servos

## Fundamentals

Servo motors are like miniaturised DC motors with built-in motor controllers. Unlike DC motors however, Servo motors are designed for *position control*, rather than speed control. Consequently, servos are typically used for precision positioning, rather than locomotion - e.g. for controlling robotic arms, joints, etc.

<figure><img src="/files/jfSwacXIqRqWjwyvCJCI" alt=""><figcaption><p>A typically hobby-grade servo motor. From wikimedia commons: <a href="https://commons.wikimedia.org/wiki/File:Servo_Motor.jpg">https://commons.wikimedia.org/wiki/File:Servo_Motor.jpg</a></p></figcaption></figure>

Servo motors are normally packaged on with a flange for mounting and with splined shaft for interfacing with accessories. They take a fixed input voltage (usually $$5;\text{V}$$) and come rated to a maximum torque (often in given in kg-cm).&#x20;

Many cheaper servo motors have plastic gears, though metal-gear variants (which are more expensive) can usually bear larger torques at the expense of drawing more current in operation.

## Servo Motor Control

Most servo motors take only 3 inputs:

1. A fixed supply voltage, (usually $$5;\text{V}$$, though many are tolerant to higher voltages),
2. A `GND` reference, and,
3. A PWM\* input, ordinarily provided by an MCU.

{% hint style="danger" %}
:zap: **Warning:** Like DC motors, servos can draw high currents in operation. They should not be powered directly from an MCU, but rather some external source (e.g. a battery, or power supply). Consult the datasheet for the loaded-current rating of a servo before integrating it!

**The only connection between a servo motor and your MCU should be the PWM position signal.**
{% endhint %}

<figure><img src="/files/f9vbg6No9MkO8Pt80BNl" alt=""><figcaption><p>Servo Motor functional block diagram.</p></figcaption></figure>

## Complete Sample Code

Servo motors can be controlled one of two ways:

1. By directly writing a PWM signal to their input line, or,
2. By using the `<Servo.h>` library.

### Direct PWM Servo Control

Driving a servo directly with PWM can be challenging. You need to map and understand how the PWM output range (`0-255`) maps to an equivalent output voltage, and how this maps to an angle on the servo. For rudimentary or simple applications, however, this may be feasible.

```arduino
void setup() {
  // Set PIN 3 as an output.
  pinMode(3, OUTPUT);
  // Setup the Serial Monitor for later
  Serial.begin(9600);
}

void loop() {
  // Increment the PWM of Pin 3
  for(int i=0; i<=255; i=i+25) {
  analogWrite(3,i);
  Serial.print("Current PWM = "); Serial.println(i);
  // Wait for 0.5 seconds
  delay(500);
  }
}
```

<figure><img src="/files/bWnUE3cz4CPaP2fLbDcY" alt=""><figcaption><p>Driving a servo using <code>analogWrite()</code>. Note that an external supply is being used to provide power to the servo, and only the PWM signal is suppled by the Arduino. Importantly, a <a data-mention href="/pages/bo0pJxx7asGilJAZeEav#common-gnd">/pages/bo0pJxx7asGilJAZeEav#common-gnd</a>is tied between the Arduino and supply.</p></figcaption></figure>

### `<Servo.h>` Library Control

Arduino has a built-in servo control library to make precise position of servo motors easily achievable.

{% embed url="<https://www.arduino.cc/reference/en/libraries/servo/>" %}

{% embed url="<https://docs.arduino.cc/learn/electronics/servo-motors/>" %}

In short, to use this library, you must:

1. `#include` the library at the beginning of your script, as with any other [Arduino C](/zerotohero/arduino-zero-to-hero/arduino-programming/arduino-c.md#library-inclusions),
2. declare a variable to represent your servo using the built-in `Servo` type provided by the library,
3. tell the library which pin the servo variable is to apply to, via the `attach` method provided by the library ( analogous to setting a `pinMode()`),
4. write a target angle to the servo object, which tells the library to do any math necessary and output an appropriate PWM signal to the attached pin.

```arduino
// Include the Servo Library
#include <Servo.h>

// Define a global servo variable
Servo myServoVariable;

void setup() {
  // Attach the servo variable to PIN 3
  myServoVariable.attach(3);
  // Setup the Serial Monitor for later
  Serial.begin(9600);
}

void loop() {
  // Increment the servo angle of Pin 3
  for(int i=0; i<=180; i=i+10) {
  myServoVariable.write(i);
  Serial.print("Current Angle = "); Serial.println(i);
  // Wait for 0.5 seconds
  delay(500);
  }
}
```

<figure><img src="/files/jK71lNgdroYx0cR8UoB6" alt=""><figcaption><p>Driving a servo using the <code>&#x3C;Servo.h></code> library. Note that an external supply is being used to provide power to the servo, and only the PWM signal is suppled by the Arduino. Importantly, a <a data-mention href="/pages/bo0pJxx7asGilJAZeEav#common-gnd">/pages/bo0pJxx7asGilJAZeEav#common-gnd</a>is tied between the Arduino and supply. Also note that the servo library maps directly to an angle, rather than PWM value.</p></figcaption></figure>
