Motors guide series

Project 1: Control a servo motor with a potentiometer

Servo motors are used in applications where precision movement is required, such as in robotics. It is very easy to control one or more servo motors with the Arduino. Learn how with this article.

In other articles in the series (see here and here), you learned about the DC motor. The DC motor is a versatile, low-priced solution for providing motion to your projects. A “weakness” (or characteristic) of the plain vanilla DC motor is that when you apply voltage to its coil, it will spin as fast as its mechanics and load allows. Without additional electronics, we have no way of knowing or controlling the rotor position and speed.

This is not a problem for applications were continuous movement is needed, like for propelling a vehicle. However, it is a problem in application where precision is needed.

Example application of precision movement

Imagine a robot that can perform surgery on humans. Some of you may work on something like this in the not so distant future. In such application, precision and control feedback is of paramount importance. You don’t just want to tell the motor to rotate its rotor by 90 degrees; you also want confirmation that it did.

The servo motor

In a previous article in the series, I made a passing mention of the servo motor. The servo motor is an enhanced DC motor that includes circuitry for fine movement control and feedback.

In this and the next article, you will learn how to use a servo motor with your Arduino.

To make programming easy, you will use the servo motor library that comes standard with the Arduino IDE, as well as a third party library that adds a bunch of very useful capabilities.

Let’s go straight to the assembly and sketches.

A simple servo motor project

In this project, you will use the servo motor library that comes with the Arduino IDE to start playing with your mini servo motor. Start by assembling the circuit. Then you will work on the sketch.

Project parts list

You will need the following components for this circuit:

Servo motor circuit

This is what you are going to assemble:

There are a couple of things to notice here.

First, there is no motor break-out board like the one we used in the DC motor lecture. There, I wrote that because the Arduino cannot provide enough current for the motor, it is best to always use an external power source to power our motors. This is why you used the L298N motor controller module.

However, the mini servo motor that you are using in this circuit, is small enough to not stress the Arduino too much. Therefore, you can safely plug it straight into the Arduino in order to keep things simple.

Notice the big round tube at the lower part of the breadboard? That is a capacitor. Even though my servo motor is small, occasionally it may draw more power than what the Arduino can provide. This spike in power demands happens when the motor begins to move.

To assist the battery or other power supply to provide this additional power, you can use a small capacitor. Connect this capacitor between the GND and +5V pins of the motor. A capacitor works as store of energy, a bit like a battery that can charge and discharge very quickly.

When the servo motor starts, the capacitor will assist the main power supply by discharging, ensuring that the motor has all the power it needs.

A capacitor that is around 300μF or more is a good choice for a mini servo motor.

The motor itself has three wires coming out of it.

Two are for power (+5V and GND), and one for signal.

Usually, the red wire is for +5V, and black or brown for GND.

The yellow wire is for the signal.

Plug the signal wire to digital pin 9, the red to +5V and the black to GND.

Sketch

You could try to control the servo motor through the Arduino digitalWrite() functions but that would require us figuring out the right values to write, and the timing for writing those values.

That’s too much work.

We are lucky, though, because with the Arduino IDE we get the Servo library, which contains functions that allow us to easily work with servo motors. First, we'll write the sketch using the Servo library. 

Later, I’ll show you an alternative library that provides additional functionality.

Here’s the sketch:

#include <Servo.h>


Servo myservo;  // create servo object to control a servo

       // a maximum of eight servo objects can be created

int pos = 0;    // variable to store the servo position

 

void setup()

{

  // attaches the servo on pin 9 to the servo object

  myservo.attach(9);  

}

 

void loop()

{

 // goes from 0 degrees to 180 degrees

  for(pos = 0; pos < 180; pos += 1)  

  {                      // in steps of 1 degree

    // tell servo to go to position in variable 'pos'

    myservo.write(pos);  

   // waits 15ms for the servo to reach the position

    delay(15);                      

  }

  // goes from 180 degrees to 0 degrees

  for(pos = 180; pos>=1; pos-=1)  

   { 

    // tell servo to go to position in variable 'pos'    

    myservo.write(pos);    

    // waits 15ms for the servo to reach the position      

    delay(15);                      

  }
}

This is one of the demo sketches that also come with the Arduino IDE. You can find it by clicking on File —> Examples —> Servo —> Sweep.

You first include the Servo library (“#include <Servo.h>”), and create the variable myservo that you can use as a handle to the Servo object (“Servo myservo;”).

In the setup function, you tell the Arduino that the control wire from our servo motor is attached to digital pin 9 (“myservo.attach(9);”).

The work is done in the loop() function, where you use the "for loop" to count from 0 to 180, and another one to count backwards, from 180 to 0. This has the effect of the rotor of the servo motor traveling 180 degrees to one side, and 180 degrees to the other side, 1 degree at a time, constantly.

Inside each for block, you first write a value to the motor using myservo.write(d), where “d” is a number representing the degree to which the shaft should turn. If we want to turn it by 15 degrees, we write myservo.write(15).

Simple, right?

In Block 1, you get the rotor to turn from 0 to 180 degrees, and in Block 2 to travel all the way back to 0 degrees.

Finally, notice how you set a delay of 15 milliseconds inside each block, after a movement has been written? We need this because it takes a bit of time for the motor to move, and you want to make sure that any previous instruction has been completed before sending through the next move instruction.

That was easy but not satisfying enough. I want to be able to control the servo motor myself, instead of the Arduino being in charge.

How about you try to connect a potentiometer and use it as a controller for the motor?

Control the servo with a potentiometer

Let’s attach a rotary 10kΩ potentiometer, and adjust our sketch to enable us control of the motor by turning the knob.

Here’s the new circuit:

Connect the middle of the potentiometer pin to analog pin 0 (A0) on the Arduino. The other two pins connect to +5V and GND.

The new sketch looks is this:

#include <Servo.h>

// create servo object to control a servo 
Servo myservo;  

 

// analog pin used to connect the potentiometer

int potpin = 0; 

// variable to read the value from the analog pin

int val;    

 

void setup()

{

 // attaches the servo on pin 9 to the servo object

  myservo.attach(9); 

}

 

void loop()

{

 // reads the value of the potentiometer (0 to 1023)

  val = analogRead(potpin);        

 // scale it to use it with the servo (0 to 180)

  val = map(val, 0, 1023, 0, 179);

  // sets servo position according to the scaled value

  myservo.write(val);    

  // waits for the servo to get there         

  delay(15);                      

}

Just like in the first part of this project, you include the Servo library and set pin 9 as the servo pin.

In the loop() function, the Arduino constantly takes readings from analog pin 0 (A0) where the potentiometer is attached.

Because the range of values read in A0 is not the same as the values we can send to the servo, we use the map() function to scale appropriately.

Finally, we use the myservo.write(val); function to send the scaled value to the potentiometer.

Learn more

If you would like to learn how to use servo motors with your Arduino, consider enrolling to Arduino Step by Step Getting Serious.

We have a full section (Section 17) with 10 lectures dedicated to this topic.

New to the Arduino?

Arduino Step by Step Getting Started is our most popular course for beginners.

This course is packed with high-quality video, mini-projects, and everything you need to learn Arduino from the ground up. We'll help you get started and at every step with top-notch instruction and our super-helpful course discussion space.

Tech Explorations Arduino intermediate level

Done with the basics? Looking for more advanced topics?

Arduino Step by Step Getting Serious is our comprehensive Arduino course for people ready to go to the next level.

Learn about Wi-Fi, BLE and radio, motors (servo, DC and stepper motors with various controllers), LCD, OLED and TFT screens with buttons and touch interfaces, control large loads like relays and lights, and much much MUCH more.


We publish fresh content each week. Read how-to's on Arduino, ESP32, KiCad, Node-RED, drones and more. Listen to interviews. Learn about new tech with our comprehensive reviews. Get discount offers for our courses and books. Interact with our community. One email per week, no spam; unsubscribe at any time

Image
{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}