How to Control Servo Motors with Arduino & Code

Welcome to our exciting exploration of controlling servo motors with Arduino and code! As we delve into this fascinating topic, we’ll unlock an essential skill set in the world of robotics, animatronics, and motorized props. Servo motors, with their ability to rotate with precision, form the backbone of various applications ranging from the nimble arms of robots to the expressive faces of animatronic creatures, and even the intricate movements of motorized props in movies or stage performances. By mastering the art of maneuvering these servos using an Arduino and some clever coding, you’ll have the power to breathe life into static objects, creating dynamic, interactive projects. Whether you’re a hobbyist looking to enhance your home creations, an aspiring roboticist, or a professional prop maker, understanding how to harness the versatility of servo motors is a game-changer. Let’s dive in and start making things move!

How to Connect a Servo to an Arduino Microcontroller

Connecting a servo motor to an Arduino is relatively straightforward even if you’ve never wired anything together before. There are only 3 servo wires to connect and you don’t have to do any soldering. This makes it easy to put together servo circuits and practice the code examples later in this tutorial. I encourage you to follow along with the components listed below.

Components you’ll need to build & code along:

Step-by-Step Servo to Arduino Connection Guide:

Servo motors have three wires: power (often red), ground (often brown or black), and signal (often orange or yellow). These servo wires typically terminate at a plastic connector where you can use Dupont-style jumper wires to connect to an Arduino, breadboard or external power supply.

The negative (ground), positive, and signal wires of a servo that can be connected to an Arduino and external power supply via its connector.
Circuit diagram for how to connect a servo to an Arduino microcontroller.

The circuit diagram shows you where to connect each wire. Be sure you don’t have your Arduino microcontroller plugged in while you make these connections.

  1. Connect the Power: Connect the power wire of the servo to the 5V pin on the Arduino board, and the servo’s ground wire to one of the GND pins on the Arduino.
  2. Connect the Signal: Connect the signal wire to one of the digital pins on the Arduino. You can choose any digital pin, but you’ll often see pin 9 used for servo motors.

How to Use an External Power Supply for Your Servo

Small servo motors like the SG90 operate on 4.8 – 6V DC and consume around 10 mA when idle and about 250 mA when rotating so it can be powered directly from the Arduino. Medium to larger servos that consume more than 300 mA will require their own power source. If a servo motor tries to draw too much current from the Arduino then you can end up damaging the microcontroller.

Even with the SG90, I recommend only powering one of these servos directly from the Arduino. If you need to control more, then you’ll need a separate power supply. On top of that, I usually only do this during the prototyping phase of a project. Once I have all the components figured out, I like to move the servo to its own power source. Don’t forget that you may have other components being controlled by the Arduino too like LEDs, sensors, etc that may run at the same time as the servo and all this draws current.

Servos can be powered separately either by batteries or a wall adapter. Just be sure that the power supply you choose matches the voltage requirements of the servo and provides enough current for it to operate with the load it will be moving in your animatronic, robot or motorized prop.

Here are examples of circuits using both a battery pack option and female DC jack adapter:

Circuit diagram showing the wire connections to connect a servo to an Arduino using an external battery power supply.
Circuit diagram showing the wire connections to connect a servo to an Arduino using an female DC jack adapter external power supply.

Common Ground

In electronics, “common ground” refers to a shared point of zero voltage. This serves as a common reference point for all components in a circuit.

When you’re connecting a servo to an Arduino and using an external power supply, it’s crucial to establish a common ground. This means that the ground of the Arduino (GND) and the ground of the external power supply should be connected together.

Why is this important?

  • Voltage Reference: For signals to be accurately interpreted between different parts of a circuit, they need to share a common voltage reference. This is especially important when you’re using an external power supply to power a servo and the Arduino to control it.
  • Signal Integrity: Servo motors receive control signals from the Arduino through the signal wire. This signal is relative to the ground of the Arduino. If the servo and the Arduino don’t share the same ground, the signal can become corrupted or not get through at all, causing erratic behavior or even damage to the components.
  • Preventing Circuits Faults: A common ground helps to prevent potential difference from building up between different parts of your circuit, which could lead to unpredictable behavior or even damage.

So when you’re connecting a servo motor to an Arduino AND using an external power supply, you must connect the ground of the power supply (usually the black or negative wire) to the ground pin on the Arduino (GND). This ensures that they share a common ground and that signals can pass between them correctly.

How to Control Your Servo with Arduino Code

Once the connections are made, you can start programming the Arduino to control the servo. If you’re new to coding, don’t worry! I’ll take you through each line of code step-by-step so you understand what each command does and can modify it to suit your project.

To write our code, let’s go to the Arduino IDE. If you haven’t installed this free software yet, head over to the official Arduino website and pick the version that matches your operating system. You’ll need to set up your board and port first before proceeding with the examples below. If you never worked with the Arduino IDE, I highly recommend checking out my in-depth tutorial on how to install and configure the Arduino IDE first. It will also take you through the different parts of a sketch so you can get familiar with the basic code sections.

Include the Servo Library

Upon launching the program, you’ll be presented with a blank sketch. The first thing we need to do is include the servo library. The Arduino servo library comes pre-installed and simplifies the complex details of controlling servo motors, allowing you to easily specify the desired position or rotation angle for the servo motor with just a few lines of code. The library translates these instructions into appropriate signals that the servo can understand.

To include the library, go to Sketch => Include Library => Servo. As soon as you do this, you’ll notice a line of code appear at the very top of your Arduino sketch:

 #include <Servo.h>

Now that the servo library is included, we can start tapping into all the functionality it provides. But first, there’s a few more setup items we have to cover.

Declare a Servo Object

Next, we need to declare a servo object. In the context of Arduino programming and the servo library, when you create a servo object, you’re creating an entity that represents a specific servo motor and has methods (functions) that allow you to control that servo motor. Basically, it just means that you need to give your servo a unique name. You can name your servo object anything you want but I recommend you keep it descriptive so you remember which servo it refers to months later. This is especially true if you’re controlling multiple servos. Each servo will need to be declared as a servo object with it’s own unique name.

Let’s say we’re building a robot arm, so I’ll call my servo object, armServo. Here’s how you would declare it:

 #include <Servo.h>

 Servo armServo;

Attach the Servo to an Arduino Pin (in the code)

You already have your servo motor connected to pin 9 of the Arduino but we have to specify this in the code. For your project, you’ll probably end up with other components connected to the Arduino too so it needs to know specifically which pin is being used for the servo motor. You typically specify this information in the setup() function of the sketch like this:

 #include <Servo.h>

 Servo armServo;

 void setup() {
  armServo.attach(9);
 }

If you break down this line of code, it starts with your servo’s name. In our case, it’s armServo. Then in the parenthesis, you put the Arduino pin the servo is connected to. If you named your servo legServo and connected it to pin 5 on the Arduino, then that line of code would look like: legServo.attach(5);

Set Servo Positions

Now that our servo has a name and we’ve specified which Arduino pin it’s connected to, let’s get it moving! The code for making your servo horn rotate to a specific position is:

servoname.write(degrees);

So if I want my servo to rotate to 180 degrees, I would write: armServo.write(180);

This would go in the loop() function like this:

 #include <Servo.h>

 Servo armServo;

 void setup() {
  armServo.attach(9);
 }

 void loop() {
  armServo.write(180);
 }

Try out different values from 0 to 180 in the parenthesis and watch your servo rotate as soon as you upload the code! This is a good exercise to go through whenever you hook up a new servo. With the less expensive ones, you’ll quickly notice that they usually don’t give you the full 0-to-180 range of motion. It will usually be more like 20 to 160.

Servo Arduino Code Examples

You now have total control over how you want to position your servo horn but holding it in one position doesn’t make for a very interesting project so let’s animate some different movements.

Timed Position Sequence

Let’s say you need your project to move in a repeated timed sequence of positions. With our robot arm example, let’s have the arm start in a neutral position at 90 degrees for 2 seconds. Then we’ll have it extend (0 degrees) and stay that way for 1 second before retracting (180 degrees) and hold that for 2 seconds. Then the program would repeat from the beginning at the neutral position.

Here’s how it would look like as Arduino code:

 #include <Servo.h>

 Servo armServo;

 void setup() {
  armServo.attach(9);
  armServo.write(0); //initial starting position
 }

 void loop() {
  armServo.write(90); //rotate servo to 90 deg
  delay(2000); //pause 2 secs

  armServo.write(0); //rotate servo to 0 deg
  delay(1000);  //pause 1 sec

  armServo.write(180); //rotate servo to 180 deg
  delay(2000); //pause 2 secs
 }

Setting a Servo Starting Position

This isn’t absolutely necessary but it’s good practice to give your servo motor a starting point at the beginning of your sketch before your animation begins. When you power off a servo, it will just stop at whatever angle it was at. When you turn it back on it will jerk back to the beginning of the animation. Adding a starting point before the animation allows your servo to “reset” before starting the animation again.

I did this in the setup() function with this line of code:

armServo.write(0);

This should look familiar to you because it’s the same line you used in the previous exercise. Because the setup() function runs first and only one time, your servo will always reset to 0 degrees before moving on to the loop() function where the animation happens.

Pausing the Rotation at a Specific Angle

There are many ways to add pauses to your servo movement so your robot, animatronic or motorized prop can hold a position for a specified amount of time. The example above shows a very beginner-friendly way to do it using the delay() function. After each movement, we hold the position by placing a delay() function right under the action we want to pause. The number in the parenthesis is the time you want to hold the action in milliseconds. So 1 second is 1000 milliseconds. After the delay is over, the program resumes execution from the point where it left off.

This function is particularly useful when you want to control the timing of operations. But delay() is a blocking function, which means it halts the execution of the program and prevents any other operations from happening during the delay period. This may not be suitable for more complex programs where multiple things need to happen at the same time or where you need to be continuously monitoring inputs while doing something else. In such cases, non-blocking methods using functions like millis() might be more appropriate. If you are more experienced with Arduino code, I encourage you to check out my tutorial on using millis() to get your Arduino to multi-task.

Continuous Sweep

Sometimes you need your robot, motorized prop or animatronic to perform a repeating continuous movement. In our example, let’s say we want our robot arm to wave continuously to people walking by. We can do this by having the servo motor sweep back and forth from 0 to 180 degrees and then back to 0 degrees before starting the sweep again.

To accomplish this, we’ll use for loops to control the back and forth movements. For loops are great for handling repetitive actions like incrementing or decreasing angles in a sequential manner. Let’s take a look at what the Arduino code to sweep a servo looks like and then we’ll go over each line of code in detail.

 #include <Servo.h>

 Servo armServo;

 int angle = 0; //set initial position to 0 degs

 void setup() {
  armServo.attach(9);
 }

 void loop() {
 
  for (angle = 0; angle <= 180; angle++) {
   armServo.write(angle);
   delay(15);
  }
 
  for (angle = 180; angle >= 0; angle--) {
   armServo.write(angle);
   delay(15);
  }
 }

As we scan down this code, much of it looks familiar. We start out by including the servo library and creating the servo object.

Setting a Servo Starting Position

We established a starting position for our servo in the previous example in the setup() function with this code:

armServo.write(0);

In this example, I changed it up by doing it in the 3rd line of code above the setup() function like this:

int angle = 0;

I set up an integer variable (int) and named it angle. I then set the angle equal to 0. In Arduino code, a variable is a placeholder for a value of a certain type that you can use and manipulate in your programs. The variable’s value can change during the execution of the program—hence the term “variable”. In our case, the variable will represent an angle that will change as the servo horn sweeps back and forth.

Both ways you’ve seen so far for establishing a starting position for your servo are correct but using a variable will allow us to manipulate the angle in the loop() function. Any code that appears outside the loop() function runs only once so when we power up our circuit the servo will reset to 0 degrees before starting the sweeping animation.

for Loops

In the loop() function of our sketch, we run into the first for loop which is a block of code that rotates our servo horn from 0 degrees to 180 degrees at an increment of 1 degree every 15 ms.

for (angle = 0; angle <= 180; angle++) {

armServo.write(angle);

delay(15);

}

All for loops have the same basic structure as what you see above which is:

for (initial state; condition; modifier) {

CODE TO BE EXECUTED HERE

}

The for loop needs 3 pieces of information to work properly which are specified in the parenthesis separated by semi-colons(;). The first is the “initial state”. In our case we set the value for the angle equal to 0:

angle = 0;

This code translates to “set the starting angle to 0”. The “initial state” portion of the for loop is only used one time, the very first time the for loop is run. It then gets ignored because we’ll be rotating the servo position past this.

Second, we need to set up a “condition”. The for loop code block will run over and over again, executing the code within its curly brackets {} so long as the condition we set up is true. If it becomes false then the program will jump out of the for loop code block and continue going down executing the rest of the code.

Since we want the servo to go from 0 degrees to 180 degrees our condition looks like this:

angle <= 180;

This translates to “so long as the angle is less than or equal to 180” keep running this for loop.

The third piece of information is the “modifier”. In other words, how do you want to modify the angle every time the for loop is run? In our case we want to increment the angle by 1 degree until we get to 180:

angle++

This code is short hand for angle + 1. So we want to add 1 to the current angle every time the for loop is run until the angle reaches 180 degrees.

After you specify the initial state, condition and modifier for the for loop in the parenthesis, you now have to tell it what code to execute as long as the condition is met. In our case we want to rotate the servo to the angle calculated by the modifier:

armServo.write(angle);

In the next line of code we hold that angle for 15 ms:

delay(15);

Then the program will loop back to the beginning of the for loop for another round. Let’s say our servo’s angle is at 27 degrees. For the next round, the for loop will check to see if 27 passes the condition. Since it is still less than 180 then it gets modified: 27 + 1 = 28. The servo will rotate to 28 degrees and hold it there for 15 ms before looping back to the beginning of the for loop again.

At some point the servo will reach 180 degrees and when it loops back to the beginning of the for loop, 181 will not meet the condition so the program will jump out of that entire for loop code block and move on to the next line.

The next code block down the sketch is another for loop that takes the servo from 180 degrees back down to 0 degrees:

for (angle = 180; angle >= 0; angle–) {

armServo.write(angle);

delay(15);

}

It uses the same structure as before, but now we’re counting down. Since the servo is at 180 from the previous for loop, we start this one with an “initial state” of 180:

angle = 180;

Next, the condition is that as long as the angle is greater than or equal to 0, modify it:

angle >= 0;

Finally, in our modifier we want to subtract 1 degree each time the for loop is run:

angle–

This code is shorthand for angle – 1.

So long as the condition we set in this second for loop is true, the code within the curly brackets {} will execute:

armServo.write(angle);

delay(15);

The servo will rotate from 180 degrees back down to 0 by 1 increment every 15 ms. Once the servo reaches 0 degrees and the for loop tries to run again, the angle will be -1 which doesn’t meet the condition anymore. The program will jump out of this code block and go back to the top of the main loop() function where it will encounter the first for loop again to repeat the sweep.

The servo will continue sweeping back and forth until you unplug it.

Changing the Timing of the Sweep

Both for loops in the example above have a delay of 15 ms. Try different values in each for loop to see what happens. Smaller values will cause the servo to rotate faster while larger values will slow it down. But there’s a limit to how fast a servo can sweep depending on the model and manufacturer. See how fast you can get yours to sweep!

Gaining proficiency in controlling servo motors with Arduino and code is a significant step in your journey as a maker, hobbyist, or professional. This skill opens up a realm of possibilities, allowing you to create intricate robots, life-like animatronics, and realistic motorized props. We’ve unpacked the essentials of connecting, coding, and controlling servos, highlighting how the popular Arduino microcontroller, some clever coding, and a little electrical know-how can lead to incredible outcomes. As you continue to explore and experiment, you’ll find that these fundamental skills form the bedrock of countless projects. The world of robotics and animatronics awaits, ready to be shaped by your creativity and technical prowess. Remember, each servo moved is a step closer to animating your dreams!

Some links in this post are to affiliate sites. If you purchase something through them, I may earn a small commission — which costs you nothing! I am very grateful for your support when you use my links to make a purchase.

Stop Scrolling. Start Creating.

Find out about new courses and live events!
Get my latest guides and reference materials.
Unsubscribe anytime!