In this article, we will learn about the working principle of servo motors and how to control them using the Arduino development board and the PWM driver PCA9685. There are many types of servo motors, and their main feature is the ability to precisely control the position of the shaft. A servo motor is a closed-loop system that uses position feedback to control its movement and final position.
In industrial servo motors, the position feedback sensor is usually a high-precision encoder, while in smaller RC or hobby servo motors, the position sensor is typically a simple potentiometer. The actual position captured by these devices is fed back to an error detector, where it is compared with the target position. Then, based on the error, the controller corrects the actual position of the motor to match the target position.
In this article, we will focus on hobby servo motors. We will explain how these servo motors work and how to control them using the Arduino development board.
Hobby servo motors are small actuators used to control RC toy cars, boats, airplanes, etc. They are also used by engineering students for robotics prototyping, robotic arms, bio-robots, humanoid robots, and more.
How do RC / Hobby Servo Motors Work?
In hobby servo motors, there are four main components: 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 about 60 RPM while increasing the torque.
The potentiometer is mounted on the end of the gear or output shaft, so as the motor rotates, the potentiometer also rotates, generating a voltage related to the absolute angle of the output shaft. In the control circuit, the voltage from the potentiometer is compared with the voltage from the signal line. If necessary, the controller activates the integrated H-bridge, allowing the motor to rotate in either direction until the two signals reach zero difference.
Servo motors are controlled by sending a series of pulses through the signal line. The frequency of the control signal should be 50Hz, or a pulse occurs every 20ms. The width of the pulse determines the angle position of the servo motor, which typically can rotate 180 degrees (they physically have stroke limits set).
Typically, a pulse duration of 1ms corresponds to a 0-degree position, 1.5ms corresponds to 90 degrees, and 2ms corresponds to 180 degrees. However, the minimum and maximum pulse durations can sometimes vary with different brands, where 0 degrees can be 0.5ms and 180 degrees can be 2.5ms.
Arduino Control of Servo Motors
Let’s test what we’ve discussed and create a practical example of using Arduino to control a hobby servo motor. I will use the MG996R servo motor, which is a high-torque servo with metal gears, with a stall torque of 10 kg-cm. High torque comes at a cost, and the stall current of the servo is 2.5A. The operating current ranges from 500mA to 900mA, and the working voltage is 4.8 to 7.2V.
The current rating indicates that we cannot connect this servo directly to the Arduino development board; we must use a separate power supply. Below is the circuit schematic for this example.
We just need to connect the control pin of the servo to any digital pin of the Arduino development board, connect the ground and positive wires to an external 5V power supply, and connect the Arduino ground to the servo motor ground.
Arduino Code to Control Servo Motors
Now let’s take a look at the Arduino code used to control the servo motor. The code is very simple. We just need to define the pin connected to the servo, set that pin as an output, and generate pulses with specific durations and frequencies in the loop function as mentioned above.
-
/*
-
Servo Motor Control – 50Hz Pulse Train Generator
-
by Dejan, https://howtomechatronics.com
-
*/
-
#define servoPin 9
-
void setup() {
-
pinMode(servoPin, OUTPUT);
-
}
-
void loop() {
-
// A pulse each 20ms
-
digitalWrite(servoPin, HIGH);
-
delayMicroseconds(1450); // Duration of the pulse in microseconds
-
digitalWrite(servoPin, LOW);
-
delayMicroseconds(18550); // 20ms – duration of the pulse
-
// Pulses duration: 600 – 0deg; 1450 – 90deg; 2300 – 180deg
-
}
Copy Code
After some testing, I found the following pulse durations to use with the servo system. A pulse duration of 0.6ms corresponds to a 0-degree position, 1.45ms corresponds to 90 degrees, and 2.3ms corresponds to 180 degrees.
I connected a multimeter in series with the servo system to check the current consumption. I noticed that the maximum current consumption reached 0.63A during stall. This was because this was not the original TowerPro MG996R servo, but rather a cheaper copy that clearly performed worse.
However, let’s look at a more convenient way to control the servo using Arduino. That is to use the Arduino Servo Library.
-
/*
-
Servo Motor Control using the Arduino Servo Library
-
by Dejan, https://howtomechatronics.com
-
*/
-
#include <Servo.h>
-
Servo myservo; // create servo object to control a servo
-
void setup() {
-
myservo.attach(9,600,2300); // (pin, min, max)
-
}
-
void loop() {
-
myservo.write(0); // tell servo to go to a particular angle
-
delay(1000);
-
myservo.write(90);
-
delay(500);
-
myservo.write(135);
-
delay(500);
-
myservo.write(180);
-
delay(1500);
-
}
Copy Code
Here we only need to include the library, define the servo object, and use the attach() function to define the pin the servo is connected to, as well as the minimum and maximum pulse durations. Then, using the write() function, we simply set the servo position from 0 to 180 degrees. With this library, we can drive up to 12 servo motors simultaneously or drive 48 servo motors using the Arduino Mega development board.
Leave a Comment
Your email address will not be published. Required fields are marked *