recent
Hot News

How To Control A Servo Motor With an Arduino Board

Home






In this tutorial, we will learn together how to use model building servomotors with an Arduino / Genuino board. We will study the function of a servo motor and we will do some tests with a classic servo motor model. As a bonus, we will see how to take advantage of all the features offered by the Arduino "Servo" library.

Hello everyone !

In this tutorial, we will focus on servomotors and the use of servomotors with an Arduino / Genuino board.

Servomotors are somewhat specific motors, which can rotate with a freedom of about 180 ° and keep relatively precisely the angle of rotation that one wishes to obtain.

Servomotors are commonly used in model making to control mechanical systems (airplane rudder, heat engine accelerator, etc.). Servomotors are also commonly used in robotics to make mini-robots, actuators or rotary indicators.

Principle of operation and control of a servomotor

Chinese servomotor "9 grams"

A model building servomotor comes in the form of a small rectangle with two tabs on the sides for fixing and an off-center axis with an (interchangeable) arm for the mechanical connection.

Servo motor Futuba S3003

There are various types of servo motors, different in size, weight and torque (force). The above photograph shows a very classic model-making servomotor: the Futuba S3003. A little further down in the article, we will use another servomotor, commonly called a "9 gram servomotor", for the sake of electricity consumption.

Exploded view of a servomotor

The internal function of a servo motor are quite basic.

A small electronic circuit makes it possible to control a direct current motor according to the position of a potentiometer integrated in the servomotor.

The output of the DC motor is mechanically connected to a series of gears which increase the force (torque) of the servomotor by reducing the speed of rotation of the latter.

When the motor is running, the gears come to life, the arm moves and drives the potentiometer with it. The electronic circuit continuously adjusts the speed of the motor so that the potentiometer (and by extension the arm) always remains in the same place.

It suffices to give a setpoint to the servomotor ("stay at 45 °" for example) and the servomotor will do its utmost to stay as close as possible to this setpoint.

Illustration of the control signal

This instruction is transmitted by means of a digital signal, a pulse to be precise.

In order for the servomotor to remain in a given position, it is necessary to transmit every 20 milliseconds (ie at a frequency of 50Hz) a pulse with a length of between 1 and 2 milliseconds.

  • A pulse of 1 millisecond corresponds to an angle of 0 °.
  • A pulse of 2 milliseconds corresponds to an angle of 180 °.
  • By sending a pulse of an intermediate length, we obtain different angles, 90 ° with a pulse of 1.5 milliseconds for example.

N.B. Most servomotors operate at 5 volts, but some operate at 3.3 volts. Be sure to read the servomotor documentation carefully before using it.

Using a servo motor with an Arduino board

In this chapter, we are going to implement a small "9 grams" servo motor with an Arduino board.

Assembly

Necessary material

To carry out this assembly, we will need:

  • An Arduino UNO board (and its USB cable),
  • A "9 grams" servomotor or similar,
  • Wires to wire our servomotor.


Schematic view of the assembly


Prototyping view of the assembly

The wiring is relatively simple: red wire from the servo motor to pin 5V on the Arduino board, black wire on the GND pin and white wire (or yellow depending on the manufacturers) on pin D9 on the Arduino board.

The finished assembly

In the case of my servomotor, the (Chinese) manufacturer was pleased with the colors. So I have a brown wire instead of black and an orange wire instead of red. If in doubt, always consult the manufacturer's documentation 😄

PS With a standard servo motor, the power is always on the middle wire.

   Pay attention to the electrical consumption of the servo motor

A recurring problem with the above assembly is the loss of USB communication and / or the inadvertent restart of the Arduino board.

This is due to the power consumption of the servomotor. A servo motor consumes a lot of current, sometimes too much for a simple Arduino board. This overconsumption triggers the electronic fuse of the Arduino boards and has the effect of restarting them.

There is only one solution to this problem: wire the power supply for the servomotors to a dedicated 5 volt power supply.



Prototyping view of the assembly (with an external + 5V DC power supply)

Schematic view of the assembly (with an external + 5V DC power supply)


Wiring one or more servomotors to an external power supply is relatively straightforward.

The "+" of each servomotor must be connected to the "+" of the external power supply. The same goes for the "-" of each servomotor which must be connected to the "-" of the power supply. The GND pin of the Arduino board must also be connected to the "-" of the power supply.

N.B. The ground of the power supply and the servomotors must always be connected to the ground of the Arduino board. If the ground of the Arduino board and the servo motors is not common, nothing will work.

In addition, with large servomotors like the Futuba S3003, it is often necessary to wire a 10 ~ 100µF capacitor in parallel with the servomotor power supply, to avoid unwanted oscillations of the arm.

Be careful when wiring the capacitor, chemical capacitors (those in the shape of a cylinder) are polarized components. The "-" of a chemical capacitor is marked by a white band on the side of the capacitor.

N.B. Avoid inverting the "+" and the "-", capacitors do not like that at all and explode when it happens. The smoke that escapes is not very good for your health, but above all, the smell is abominable.

The code

To make our servomotor move, we will have to use a code library, named "Servo". This comes standard with the Arduino development environment.

The Servo library allows you to control up to 12 servomotors simultaneously with an Arduino UNO board and 48 with an Arduino Mega board.


With an Arduino UNO board, using the Servo library makes pins D9 and D10 unusable in PWM with analogWrite ().

With an Arduino Mega board, 11 servomotors can be used simultaneously without causing any particular problems. From 12 servomotors, pins D11 and D12 can no longer be used in PWM with analogWrite ().

Implementation of the Servo library

The Servo library comes standard with the Arduino development environment. There is therefore no installation to be planned.

All you have to do is import the library by adding this line at the start of the program to use it:

1 #include <Servo.h>

The Servo library is an object oriented library, this means that it works by assigning a variable (an object) to each servo motor you want to use.

To create a Servo object, all you have to do is declare a (global) variable of type "Servo", example:

1 Servo myservomotor;
If you want to use several servomotors simultaneously, you must create several variables, one per servomotor.
PS A complete code example is available at the end of the chapter

Initializing the Servo Library

The Servo library is initialized using the attach () function of each Servo type object. Example :

1 void setup() { 
2 myservomotor.attach(9);
3 }
1 Servo.attach(int broche);
The attach () function takes as argument a single mandatory parameter corresponding to the pin number to which the servomotor is wired

1 Servo.attach(int broche, unsigned long min, unsigned long max);
The attach () function can also take two optional parameters, "min" and "max", corresponding respectively to the minimum and maximum duration in microseconds of the control pulse seen at the beginning of the article.

The default times are 544µs for 0 ° ~ 240µs for 180 °. These default values are designed to work with the vast majority of commercial servomotors.


         Compatibility with Arduino 0016 and lower versions

If you are using an old version of the Arduino software, version 0016 or lower, the Servo library in this case only allows the use of 2 servomotors, on pins D9 and D10 only.

This limitation (quite restrictive) only exists in these versions. You just need to use a more recent version to no longer have a problem.
If later in your code you want to verify that a Servo object is attached to a pin, you can use the attached () function.

1 bool Servo.attached();

The attached () function returns a Boolean, True (true = 1) if the Servo object is attached to a pin, False (false = 0) otherwise.
And if you want to detach a Servo object from a pin, just call the detach () function.

1 Servo.detach();

The detach () function takes no parameters and returns no value. Just call it to detach the Servo object from its pin.

N.B. If you detach all Servo objects from their respective pins, the Servo library automatically frees pins D9 and D10 (or D11 and D12 on Mega) which become usable again with analogWrite ().

Changing the angle of the servomotor
To change the angle of the servomotor arm, there are two solutions: write () and writeMicroseconds ().

1 Servo.write(int angle);

The write () function is used to modify the angle of the servomotor arm by giving the angle in question as a parameter, in the form of an integer between 0 ° and 180 °.

1 int Servo.read();
If subsequently, you want to retrieve the last angle value assigned with the write () function, all you have to do is call the read () function which returns the last known value.

N.B. The range of rotation available depends on the servomotor model. Some servo motors can do 0 ° ~ 180 ° without problem, while others can barely turn 60 °. Remember to read the technical specifications

1 Servo.writeMicroseconds(unsigned long us);

The writeMicroseconds () function is used to modify the angle of the servomotor arm by setting the duration of the pulse to be transmitted to the servomotor as a parameter.

With a standard servomotor, a value of 1000µs will give an angle of 0 ° and a value of 2000µs will give an angle of 180 °. However, with some servomotors, these values can go up to a range of the order of 700 ~ 2300µs for 0 ~ 180 °.

This function makes it possible to precisely choose the angle of the arm according to the servomotor used. However, it is necessary to do tests beforehand to determine the limits of the arm.

                                   What is that noise?
When you ask a servomotor to go beyond its functional limits (by asking it to do a 360 ° for example), you usually hear a high-pitched noise.

If the servomotor makes a high-pitched / unusual noise, you are asking it for the impossible;)

Locking the arm of a booster in a "hard" position is not very good and will eventually kill it. This also induces a very high current consumption.

Example: Sweep

To illustrate the use of the functions described above, here is a small sample code named "Sweep".
Its purpose is simple: to rotate the servomotor arm in one direction then in the other, indefinitely.
Sweep example using Servo.write () with comments:

/**
* Example code for a servomotor, it moves the head of the servomotor back and forth. */

 /* Includes lib Servo to manipulate the servo motor */
#include <Servo.h>

/* Create a Servo object to control the servo motor */
Servo monServomoteur;

void setup() {
    
  // Attach the servo motor to pin D9
  monServomoteur.attach(9);
}

void loop() {

  // Moves the arm from 0 ° to 180 °
  for (int position = 0; position <= 180; position++) {
    monServomoteur.write(position);
    delay(15);
  }
  
  // Moves the arm 180 ° to 10 °
  for (int position = 180; position >= 0; position--) {
    monServomoteur.write(position);
    delay(15);
  }
}
Sweep example using Servo.writeMicroseconds () with comments:

/**
 * Example code for a servomotor, it moves the head of the servomotor back and forth.
  * /

 /* Includes lib Servo to manipulate the servo motor * / */
#include <Servo.h>

/* Create a Servo object to control the servo motor */
Servo monServomoteur;

void setup() {
    
  // Attach the servo motor to pin D9
  monServomoteur.attach(9);
}

void loop() {

  // Moves the arm from 0 ° to 180 °
  for (unsigned long position = 1000; position <= 2000; position += 5) {
    monServomoteur.writeMicroseconds(position);
    delay(15);
  }
  
  // Moves the arm 180 ° to 10 °
  for (unsigned long position = 2000; position >= 1000; position -= 5) {
    monServomoteur.writeMicroseconds(position);
    delay(15);
  }
}

Conclusion

This tutorial is now complete.
If you enjoyed this tutorial, feel free to comment on it on the forum, post it on social media, and support the site if you like it.



google-playkhamsatmostaqltradent