Arduino - Servo Motor
Arduino - Controlling a Servo Motor
Section titled “Arduino - Controlling a Servo Motor”A hobby servo motor is a compact device containing a DC motor, gears, a position feedback potentiometer, and control electronics. It allows you to control the angular position of its output shaft with high precision. Servos are fundamental components in robotics, radio-controlled models, and animatronics.
There are two main types of servos: standard (positional) servos, which rotate over a limited range (typically 0-180 degrees), and continuous rotation servos, which are modified to spin continuously like a regular motor but with easy speed and direction control.
How Servos Work: Pulse Width Modulation (PWM)
Section titled “How Servos Work: Pulse Width Modulation (PWM)”A servo’s position is not set by a steady voltage, but by the duration (width) of a repeating electrical pulse sent down its signal wire. This control method is called Pulse Width Modulation (PWM). The servo expects a pulse every 20 milliseconds (a frequency of 50 Hz).
- A pulse of ~1 millisecond (1000 µs) typically corresponds to the 0-degree position.
- A pulse of ~1.5 milliseconds (1500 µs) corresponds to the 90-degree (neutral) position.
- A pulse of ~2 milliseconds (2000 µs) corresponds to the 180-degree position.
The Arduino’s Servo.h library handles the generation of these precise pulses for you, making control very simple.
Components Required
Section titled “Components Required”- 1 × Arduino board (e.g., UNO, Nano, MKR)
- 1 × Standard hobby servo (e.g., SG90, MG996R)
- 1 × 10kΩ Potentiometer
- Jumper Wires
- (Recommended) An external 5V-6V power supply (e.g., a 4xAA battery pack or a 5V/2A wall adapter)
Circuit and Connections
Section titled “Circuit and Connections”⚠️ Important Note on Power: A servo can draw significant current, especially under load. Powering it directly from the Arduino’s 5V pin can cause the Arduino to reset or become unstable. While it might work for a single, small servo like an SG90 with no load, the best practice is to power the servo from a separate, external power supply.
Recommended Wiring (with External Power Supply)
Section titled “Recommended Wiring (with External Power Supply)”- Servo Power: Connect the servo’s red wire (+V) to the positive (+) terminal of your external 5V/6V supply.
- Servo Ground: Connect the servo’s brown/black wire (GND) to the negative (-) terminal of your external supply.
- Common Ground: Connect the negative (-) terminal of the external supply also to a GND pin on the Arduino. This is crucial for the signal to be interpreted correctly.
- Servo Signal: Connect the servo’s orange/yellow wire (Signal) to a PWM-capable pin on the Arduino (e.g., pin 9, marked with a
~). - Potentiometer: Connect its middle pin to Arduino A0. Connect the two outer pins to the Arduino’s 5V and GND pins.
Using the Servo.h Library
Section titled “Using the Servo.h Library”The Servo library simplifies control down to a few key functions:
#include <Servo.h>: Includes the library in your sketch.Servo myServo;: Creates a servo object.myServo.attach(pin): Associates the servo object with a physical pin on the Arduino. This must be a PWM pin.myServo.write(angle): Commands the servo to move to a specific angle, from 0 to 180.myServo.writeMicroseconds(us): Provides finer control by specifying the pulse width directly in microseconds (e.g., 1000 to 2000).myServo.detach(): Stops sending pulses to the servo, allowing it to be moved freely and saving power.
Code: Potentiometer Control of a Servo
Section titled “Code: Potentiometer Control of a Servo”/* Servo Control with a Potentiometer - Modernized
This sketch reads an analog value from a potentiometer and uses it to control the position of a servo motor.
- Potentiometer connected to pin A0 - Servo signal wire connected to pin 9 - Servo powered by an external 5V supply with a common ground to Arduino*/
#include <Servo.h>
// Create a servo object to control a servoServo myServo;
// Define constants for pins for better readabilityconst int potPin = A0;const int servoPin = 9;
void setup() { // Attach the servo on pin 9 to the servo object myServo.attach(servoPin);
Serial.begin(9600); Serial.println("Servo control initialized. Turn the potentiometer.");}
void loop() { // Read the raw value from the potentiometer (0 to 1023) int potValue = analogRead(potPin);
// Scale the potentiometer's range (0-1023) to the servo's angle range (0-180) int servoAngle = map(potValue, 0, 1023, 0, 180);
// Set the servo position according to the scaled value myServo.write(servoAngle);
// Print the angle to the serial monitor for debugging Serial.print("Potentiometer Value: "); Serial.print(potValue); Serial.print(", Servo Angle: "); Serial.println(servoAngle);
// A small delay to allow the servo to reach its position delay(15);}Common Problems & Debugging
Section titled “Common Problems & Debugging”- Servo is twitching, jittering, or resetting the Arduino: This is almost always a power supply issue. The servo is drawing too much current from the Arduino’s regulator. Use a suitable external power supply.
- Servo doesn’t move the full 180 degrees: The default pulse width range in the
Servolibrary (typically 544µs to 2400µs) might not match your specific servo’s physical limits. You can calibrate it by usingmyServo.writeMicroseconds()to find the exact pulse widths that correspond to 0 and 180 degrees for your servo. analogWrite()stops working on certain pins: On some Arduino boards (like the UNO), attaching a servo disables PWM (analogWrite()) on pins 9 and 10. This is due to internal timer conflicts. Be aware of this when designing projects with multiple servos and PWM outputs.
Project Idea: A Simple Robot Arm
Section titled “Project Idea: A Simple Robot Arm”Now that you can control one servo, the next step is to control several. A great mini-project is to build a simple 2 or 3-axis robotic arm. You can use one potentiometer for each servo (e.g., base, shoulder, elbow) to control each joint independently. This teaches you how to manage multiple servos and is a fantastic introduction to robotics.