Controlling servos with arduino


Allows Arduino boards to control a variety of servo motors.
This library can control a great number of servos. It makes careful use of timers: the library can control 12 servos using only 1 timer. On the Arduino Due you can control up to 60 servos.


This library is compatible with the avr, megaavr, sam, samd, nrf52, stm32f4, mbed, mbed_nano, mbed_portenta, mbed_rp2040 architectures so you should be able to use it on the following Arduino boards:

Compatibility Note

Note: while the library is supposed to compile correctly on these architectures, it might require specific hardware features that may be available only on some boards.


To use this library, open the Library Manager in the Arduino IDE and install it from there.


This library allows an Arduino board to control RC (hobby) servo motors. Servos have integrated gears and a shaft that can be precisely controlled. Standard servos allow the shaft to be positioned at various angles, usually between 0 and 180 degrees. Continuous rotation servos allow the rotation of the shaft to be set to various speeds.

The Servo library supports up to 12 motors on most Arduino boards and 48 on the Arduino Mega. On boards other than the Mega, use of the library disables analogWrite() (PWM) functionality on pins 9 and 10, whether or not there is a Servo on those pins. On the Mega, up to 12 servos can be used without interfering with PWM functionality; use of 12 to 23 motors will disable PWM on pins 11 and 12.


Arduino — Servo Motor

In this tutorial, we are going to learn:

Hardware Required

About Servo Motor

Servo motor is a component that can rotate its handle (usually between 0° and 180°). It used to control the angular position of the object.


The servo motor used in this example includes three pins:

How It Works

After connecting VCC pin and GND pin to 5V and 0V, respectively, we can control the servo motor by generating proper PWM signal to signal pin.

The angle is determined by the width of PWM signal.

Datasheet of the servo motor provides us the following parameters:

These parameters are fixed in Arduino Servo library. We do NOT need to know the value of parameters.

The angle is determined as follows:

Arduino — Servo Motor

Some of Arduino pins can be programmed to generate PWM signal. We can control the servo motor by connecting the servo motor’s signal pin to an Arduino’s pin, and programming to generate PWM on the Arduino’s pin.

Thanks to Arduino Servo library, controlling servo motor is a piece of cake. We even do NOT need to know how servo motor works. We also do NOT need to know how to generate PWM signal. We JUST need to learn how to use the library.

Wiring Diagram

Image is developed using Fritzing. Click to enlarge image

For the sake of simplicity, the above wiring diagram is used for the testing or learning purposes, and for small-torque servo motor. In practice, we highly recommend using the external power supply for the servo motor. The below wiring diagram shows how to connect servo motor to an external power source.

Image is developed using Fritzing. Click to enlarge image


Servo Motor Basics with Arduino

LAST REVISION: 10/05/2022, 01:00 PM

The Servo Library is a great library for controlling servo motors. In this article, you will find two easy examples that can be used by any Arduino board.

The first example controls the position of a RC (hobby) servo motor with your Arduino and a potentiometer. The second example sweeps the shaft of a RC servo motor back and forth across 180 degrees.

You can also visit the Servo GitHub repository to learn more about this library.

Hardware Required

  • Arduino Board
  • Servo Motor
  • 10k ohm potentiometer
  • hook-up wires


Servo motors have three wires: power, ground, and signal. The power wire is typically red, and should be connected to the 5V pin on the Arduino board. The ground wire is typically black or brown and should be connected to a ground pin on the board. The signal pin is typically yellow or orange and should be connected to PWM pin on the board. In these examples, it is pin number 9.

Knob Circuit

For the Knob example, wire the potentiometer so that its two outer pins are connected to power (+5V) and ground, and its middle pin is connected to on the board. Then, connect the servo motor to +5V, GND and pin 9.

The Knob Circuit.

Sweep Circuit

For the Sweep example, connect the servo motor to +5V, GND and pin 9.

The Sweep Circuit.


Controlling a servo position using a potentiometer (variable resistor).


Sweeps the shaft of a RC servo motor back and forth across 180 degrees.


How to Control Servo Motors with Arduino – Complete Guide

In this tutorial we will learn how servo motors work and how to control servo motors with Arduino. Servo motors are very popular and widely used in many Arduino projects because they are easy to use and provide great position control.

Servos are great choice for robotics projects, automation, RC models and so on. I have already used them in many of my Arduino projects and you can check out some of them here:

You can watch the following video or read the written tutorial below. It includes several examples how to use a servo motor with Arduino, wiring diagram and codes. In additional, it has a guide how to control multiple servo motors with Arduino using the PCA9685 PWM driver.

What is Servo Motor?

A servo motor is a closed-loop system that uses position feedback to control its motion and final position. There are many types of servo motors and their main feature is the ability to precisely control the position of their shaft.

In industrial type servo motors the position feedback sensor is usually a high precision encoder, while in the smaller RC or hobby servos the position sensor is usually a simple potentiometer. The actual position captured by these devices is fed back to the error detector where it is compared to the target position. Then according to the error the controller corrects the actual position of the motor to match with the target position.

In this tutorial we will take a detailed look at the hobby servo motors. We will explain how these servos work and how to control them using Arduino.

Hobby servos are small in size actuators used for controlling RC toys cars, boats, airplanes etc. They are also used by engineering students for prototyping in robotics, creating robotic arms, biologically inspired robots, humanoid robots and so on.

How Servo Motors Work?

There are four main components inside of a hobby servo, a DC motor, a gearbox, a potentiometer and a control circuit. The DC motor is high speed and low torque but the gearbox reduces the speed to around 60 RPM and at the same time increases the torque.

The potentiometer is attached on the final gear or the output shaft, so as the motor rotates the potentiometer rotates as well, thus producing a voltage that is related to the absolute angle of the output shaft. In the control circuit, this potentiometer voltage is compared to the voltage coming from the signal line. If needed, the controller activates an integrated H-Bridge which enables the motor to rotate in either direction until the two signals reach a difference of zero.

A servo motor is controlled by sending a series of pulses through the signal line. The frequency of the control signal should be 50Hz or a pulse should occur every 20ms. The width of pulse determines angular position of the servo and these type of servos can usually rotate 180 degrees (they have a physical limits of travel).

Generally pulses with 1ms duration correspond to 0 degrees position, 1.5ms duration to 90 degrees and 2ms to 180 degrees. Though the minimum and maximum duration of the pulses can sometimes vary with different brands and they can be 0.5ms for 0 degrees and 2.5ms for 180 degrees position.

There are many different models and manufacturers of RC or hobby. The main consideration when choosing a servo motor is its torque, operating voltage, current draw and size.

Here are the two most popular servo models among makers, the SG90 Micro Servo and the MG996R.

SG90 Micro Servo technical specifications:

Stall Torque 1.2kg·cm @4.8V, 1.6kg·cm @6V,
Operating Voltage 3.5 – 6V
No Load Current 100mA
Stall Current 650mA
Max Speed 60 degrees in 0.12s
Weight 9g

MG996R Servo technical specifications:

Stall Torque @4.8v, @6V
Operating Voltage 4.8 – 7.2V
No Load Current 220mA @4.8V, 250mA @6V
Stall Current 650mA
Max Speed 60 degrees in 0.20s
Weight 55g

Arduino Servo Motor Control

Let’s put the above said to test and make a practical example of controlling a hobby servo using Arduino. I will use the MG996R which is a high-torque servo featuring metal gearing with stall torque of 10 kg-cm. The high torque comes at a price and that’s the stall current of the servo which is 2.5A. The running current is from 500mA to 900mA and the operating voltage is from 4.8 to 7.2V.

The current ratings indicate that we cannot directly connect this servo to the Arduino, but we must use a separate power supply for it.

Circuit Diagram

Here’s the circuit diagram for this example.

We simply need to connect the control pin of the servo to any digital pin of the Arduino board, connect the Ground and the positive wires to the external 5V power supply, and also connect the Arduino ground to the servo ground.

In case we use a smaller hobby servo, the S90 Micro Servo, it’s possible to power it directly from the 5V Arduino pin.

The S90 Micro Servo has lower current consumption, around 100-200mA no-load running current, but around 500-700mA stall current. On the other hand, the Arduino 5V pin can output only around 500mA if powered via USB, or up to 1A in powered via the barrel connector.

Even though it’s possible to run these 9g servo motors directly to Arduino, for more stable work I would suggest to always use an external power supply for them.

You can get the components needed for this example from the links below:

Disclosure: These are affiliate links. As an Amazon Associate I earn from qualifying purchases.

Servo Motor Control Arduino Code

Now let’s take a look at the Arduino code for controlling the servo motor. The code is very simple. We just need to define the pin to which the servo is connect, define that pin as an output, and in the loop section generate pulses with the specific duration and frequency as we explained earlier.

After some testing I came up with the following values for the duration of the pulses that work with my servo. Pulses with 0.6ms duration corresponded to 0 degrees position, 1.45ms to 90 degrees and 2.3ms to 180 degrees.

I connected a multimeter in series with the servo to check the current draw. The maximum current draw that I noticed was up to 0.63A at stall. Well that’s because this isn’t the original TowerPro MG996R servo, but a cheaper replica, which obviously has worse performance.

Nevertheless, let’s take a look at a more convenient way of controlling servos using Arduino. That’s using the Arduino servo library.

Here we just need to include the library, define the servo object, and using the attach() function define the pin to which the servo is connected as well as define the minimum and maximum values of the pulses durations. Then using the write() function we simply set the position of the servo from 0 to 180 degrees.

Controlling Multiple Servo Motors with Arduino

The Arduino servo library supports controlling of up to 12 servos at the same time with most the Arduino boards, and 48 servos using the Arduino Mega board. On top of that, controlling multiple servo motors with Arduino is as easy as controlling just a single one.

Here’s an example code for controlling multiple servos:

So, we just have to create objects from the Servo class for each servo motor, and define to which Arduino pin is connected. Of course, we can set any servo to move to any position, at any time.

As an example you can also check my Arduino Ant Hexapod Robot project where I used an Arduino MEGA board to control 22 servo motors.

Arduino and PCA9685 PWM/ Servo Driver

There’s also another way of controlling servos with Arduino, and that’s using the PCA9685 servo driver. This is a 16-Channel 12-bit PWM and servo driver which communicates with Arduino using the I2C bus. It has a built in clock so it can drive 16 servos free running, or independently of Arduino.

What’s even cooler we can daisy-chain up to 62 of these drivers on a single I2C bus. So theoretically we can control up to 992 servos using only the two I2C pins from the Arduino board. The 6 address select pins are used for setting different I2C addressed for each additional driver. We just need to connect the solder pads according to this table.

Here’s the circuit schematic and we can once again notice that we need a separate power supply for the servos.

You can get the components needed for this example from the links below:

  • MG996R Servo Motor …………………………. Amazon / Banggood / AliExpress
  • PCA9685 PWM Servo Driver ………………. Amazon / Banggood / AliExpress
  • Arduino Board ……………………………………. Amazon / Banggood / AliExpress
  • 5V 6A DC Power Supply …………………..….. Amazon / Banggood / AliExpress

Disclosure: These are affiliate links. As an Amazon Associate I earn from qualifying purchases.

Now let’s take a look at the Arduino code. For controlling this servo driver we will use the PCA9685 library which can be downloaded from GitHub.

Arduino and PCA9685 Code

So first we need to include the libraries and define the PCA9685 object. Then using the Servo_Evaluator instance define the pulses duration or the PWM output of the driver. Note that the outputs are 12-bit, or that’s a resolution of 4096 steps. So the minimum pulse duration of 0.5ms or 0 degrees position would correspond to 102 steps, and the maximum pulse duration of 2.5ms or 180 degrees position to 512 steps. But as explained earlier these values should be adjusted according your servo motor. I had value from 102 to 470 which corresponded to 0 to 180 degrees position.

In the setup section we need to define the I2C clock rate, set the driver address and set the frequency to 50Hz.

In the loop section, using the setChannelPWM() and pwmForAngle() functions we simply set the servo to the desired angle.

I connected a second servo to the driver, and as I expected, it wasn’t positioning the same as the first one, and that’s because the servos that I’m using are cheap copies and they are not so reliable. However, this isn’t a big problem because using the Servo_Evaluator instance we can set different output settings for each servo. We can also adjust the 90 degrees position in case it’s not precisely in the middle. In that way all servos will work the same and position at the exact angle.

Controlling a lot of servos with Arduino and the PCA9685 drivers

We will take a look at one more example and that’s controlling a lot of servos with multiple chained PCA9685 drivers.

For that purpose we need to connect the drivers to each other and connect the appropriate address select solder pads. Here’s the circuit schematic:

Let’s take a look at the Arduino code now.

So we should create separate PCA9685 object for each driver, define the addresses for each driver as well as set the frequency to 50Hz. Now simply using the setChannelPWM() and pwmForAngle() functions we can set any servo at any driver to position any angle we want.


Servo motor jitters and resets my Arduino board

This is a common problem with these hobby servo motors, the SG90 Micro Servo and the MG996R. The reason for this is that, as mentioned earlier, they can draw quite significant amount of current when they are at load. This can cause the Arduino board to reset, especially if you are powering the servo directly from the Arduino 5V pin.

In order to solve this issue you can use a capacitor across the GND and the 5V pin. It will act as a decouple capacitor which will provide additional current to the system at start up when the DC motor starts.

Servo motor won’t move entire range from 0 to 180 degrees

This is another common problem with these hobby servos. As we explained earlier, a pulse width of 1ms (0.5ms) corresponds to 0 degrees position, and 2ms (2.5ms) to 180 degrees. However, these values can vary from servo to servo and between different manufacturers.

In order to solve this problem, we need to adjust the pulse width we are sending to the servo motor with the Arduino. Luckily, using the Arduino Servo library we can easily adjust the pulse widths values in the attach() function.

The attach() function can take two additional parameters, and that’s the minimum and maximum pulse width in microseconds. The default values are 544 microseconds (0.544milliseconds) for minimum (0 degrees) angle, and 2400 microseconds (2.4ms). So by adjusting these values we can fine tune the moment range of the servo.

Dimensions and 3D Model

I made 3D models of the two most popular servo motors, the SG90 Micro Servo and the MG996R servo motor. You can download load them from the links below.