Servo Motors
Servo motors are great devices that can turn to a specified position.Usually, they have a servo arm that can turn 180 degrees.
Last updated
Servo motors are great devices that can turn to a specified position.Usually, they have a servo arm that can turn 180 degrees.
Last updated
Small servos can be powered directly from the Arduino but it is best practice to power them externally to avoid overloading the board.
There are few big names in the servo motor world. Hitec and Futaba are the leading RC servo manufacturers.
There are many types of servo motors and their main feature is the ability to precisely control the position of their shaft. A servo motor is a closed-loop system that uses position feedback to control its motion and final position.
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.
Inside a servo 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 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.
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.
Connect you servo control wire to Pin 8 and we sure to couple the ground of the servo to the ground of the board.
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.
You will need to test to find the values for the duration of the pulses that work with your servo.
Generally pulses with 1ms duration correspond to 0 degrees position, 1.5ms duration to 90 degrees and 2ms to 180 degrees.
It is often more convenient to use a servo library. We set it up by providing the control pin, min pulse duration and max pulse duration.
With this library we can drive up to 12 servos at the same time or 48 servos using Arduino Mega board.
To find these values consult the data sheet for your servo. For the one I was using (an SG90)
Position "0" (1.5 ms pulse) is middle
"90" (~2ms pulse) is middle, is all the way to the right
"-90" (~1ms pulse) is all the way to the left
However, I found that I a min value of 900 (microseconds) and a max of 2100 (microseconds) to get the full range of motion
In this example we sweep the servo from 0 to 180 and back again
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.
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.
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. In my case values from 102 to 470 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.
We can control lots of servos with 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: