Lesson 11 of 13
Sweep a servo
Objective: Use the Servo library and a for loop to step a servo through angles, and give it time to get there: the turret that turns a rover's distance sensor.
Solid: where the horn is. Dashed: the angle the latest pulse asks for. The model's horn starts at 0° and turns 60° in 0.1 s, as the SG90 data sheet gives.
While the sketch runs, a loop trace shows each value of angle, a scope shows the pulses on D9 and on the servo's signal wire, and a chart compares the angle written with where the horn really is.
Stage 1 of 7 · What am I building?
Explore
A servo turns to an angle you choose and holds it there. On the rescue rover it becomes a turret: it turns the distance sensor to look right, ahead and left before the rover decides where to go. Select each part on the circuit, or below.
Pick a part. 0/6 inspected.
⚠ Power: the board's 5V pin is only for a small servo with no load, as a quick test. Never power a servo from a signal pin.
Before you start (optional refreshers)
setup() and loop()
setup() runs once after power-up or reset. loop() then runs again and again, as fast as its statements allow.
Variables and constants
A variable is a named value that can change; `const` makes a name for a value that never changes. Declared outside every function (global), a variable keeps its value between passes of loop(); declared inside loop(), it starts again on every pass.
Timing and delay()
delay(ms) pauses the whole program. Nothing else happens while it waits, so a blink lasts ON delay + OFF delay.
Conditional logic
if (condition) { … } else { … } chooses what to do from a reading. The same test runs on every pass of loop().
New ideas in this lesson
for loops
for (int angle = 0; angle <= 180; angle += 30) { … } repeats its body a counted number of times. The first part runs once; the condition is tested before every pass and the loop ends as soon as it is false; the step runs after each pass. With <= the end value is included, with < it is not, and a step that jumps over the end never lands on it.
Libraries and objects
#include <Servo.h> adds the Servo library: ready-made code. Servo myServo; makes an object, and its functions are called with a dot: myServo.attach(9) gives it a pin and starts the pulses, myServo.write(90) sets its angle. A library can take over hardware: on an Uno, using Servo stops analogWrite() working on pins 9 and 10.
Servos and position control
A hobby servo turns to the angle its pulses ask for and holds it. Every 20 ms the library sends a pulse whose width sets the angle (by default 544 µs for 0° to 2400 µs for 180°). The horn turns at its own top speed (an SG90: 0.1 s per 60° at 4.8 V), write() does not wait for it, and read() only returns the angle you last wrote: the servo cannot report where it really is.
Build it for real · Arduino Uno R3
You need
- Arduino Uno R3 (or compatible) and its USB cable
- Micro servo (e.g. SG90)
- Jumper wires
- Recommended beyond a quick test: a separate 5 V supply (the SG90 sheet gives 4.8 V)
Wiring
- Servo brown/black → GND.
- Servo red → 5V for a small unloaded servo, or → its own 5 V supply (the SG90 sheet gives 4.8 V).
- Servo orange/yellow (signal) → D9.
- With a separate supply, join its − to the board's GND.
Before you power up: A moving servo draws more current, and more again under a load: more than is safe to take from the board. Beyond a quick test with a small unloaded servo, power it separately and share GND.
The lab models ideal parts. Real circuits add tolerances, noise and loose wires, so check your wiring against this list before you plug in.
// Sweep a servo back and forth
// Servo: brown to GND, red to 5V, orange (signal) to D9
#include <Servo.h> // the Servo library: ready-made servo code
Servo myServo; // an object: one servo, with its own pin and angle
void setup() {
myServo.attach(9); // pulses go out on D9
}
void loop() {
// angle starts at 0; the body runs while angle <= 180; then angle += 1
for (int angle = 0; angle <= 180; angle += 1) {
myServo.write(angle); // sets the pulse width; does not wait
delay(15); // time for the horn to turn
}
// angle starts at 180; the body runs while angle >= 0; then angle -= 1
for (int angle = 180; angle >= 0; angle -= 1) {
myServo.write(angle); // sets the pulse width; does not wait
delay(15); // time for the horn to turn
}
}Press ▶ Run, then watch the horn, the loop trace and the scope.