Source: https://mokxi.com/learn/arduino-servo-motor
Updated: 2026-09-27

Learn

# Control a servo motor with an Arduino and a potentiometer

Written by the Mokxi team, updated September 27, 2026

Try it now, no account Sign up free or see every lesson

- 192 parts on the bench
- 25 boards running now
- 1.00x real time, on every board

Click to open it in the editor

The servo example: a slide potentiometer on A0 sets the angle of a servo on pin 9. Open it in the editor to move the slider.

A hobby servo is the easiest way to make an Arduino move something to an exact angle: three wires, one signal pin, and a number from 0 to 180. The circuit above is an SG90-style servo on pin 9 of an Arduino Uno, with a slide potentiometer on A0 setting where the horn points. It is running in your browser on a simulated ATmega328P.

Open it in the editor and drag the slider while it runs: the horn walks to the new angle at the speed a real SG90 does, and the serial monitor prints the reading and the angle each time it changes.

## What you need

- An Arduino Uno
- An SG90 (or similar) hobby servo
- A 10 k potentiometer (a slide pot here; a rotary one is wired the same way)
- A breadboard and jumper wires

## Wiring

Part and pin

Goes to

Note

Servo brown wire (GND)

GND

Servo red wire (VCC)

5 V

Below 4 V the servo does not move at all

Servo orange wire (signal)

Pin 9

Any digital pin works

Potentiometer end 1

5 V

Potentiometer end 3

GND

Potentiometer wiper

A0

Reads 0 to 1023 across the travel

## What a servo actually listens to

The servo’s signal wire does not take PWM in the sense an LED does. The duty cycle means nothing to it. What it measures is the width of each pulse: about 1 millisecond puts the horn at one end, 2 milliseconds at the other, 1.5 milliseconds in the middle, repeated about fifty times a second. The servo holds whatever it was last told and walks there at its own speed, roughly a tenth of a second for sixty degrees.

That is also why you cannot drive a servo with analogWrite() on an Uno. The Uno’s PWM runs at about 490 or 980 hertz, far too fast for a servo to read as a pulse width. The Servo library makes the pulse itself.

## The code, explained

The sketch reads the potentiometer four times and averages the readings, so the horn does not twitch on the last, noisy bit of the converter. map() turns 0 to 1023 into 0 to 180 degrees, write() sends the matching pulse, and the loop waits 20 milliseconds, which is the servo’s own frame period. The angle is printed only when it changes, so the serial monitor reads as a sentence rather than a waterfall.

The loop, from the servo example (trimmed)

## The same thing with the Servo library

The built-in example uses Mokxi’s own servo header, but the Arduino Servo library’s calls compile as they stand, on every board that compiles in the browser. The classic sweep sketch below runs unchanged. Two small differences are worth knowing: attach(pin) with no widths uses 1000 to 2000 microseconds, the SG90’s window, where the upstream library uses 544 to 2400; and each write() sends one pulse rather than starting a timer, so a sketch that needs the servo held under load calls refresh() from loop().

For an ESP32 tutorial, ESP32Servo.h is the same class under the name those tutorials use.

The Servo library sweep, as it compiles here

## Try it in the editor

Open the circuit in the editor and change the map() call to map(reading, 0, 1023, 45, 135). The slider now covers only the middle ninety degrees, which is how you give a knob a finer feel over a smaller range.

Then select the servo and look at its properties: min_pulse, max_pulse, range and speed. Set the speed to 60 degrees a second and move the slider quickly; the horn now crawls after it, the way a large, slow servo would. Setting min_pulse to 544 and max_pulse to 2400 makes it match the upstream Servo library’s default window.

To drive a second servo, drag another one onto the canvas, wire its signal to pin 10, and add a second Servo object in the sketch.

## Common mistakes

Powering the servo from the board and expecting it to be fine. On a real bench an SG90 can pull a quarter of an amp when it stalls, enough to brown out an Uno running from USB, and it is the most common reason a servo project resets itself. The simulator does not model supply current, so a circuit that would sag on your desk runs cleanly here. If you build it for real, give the servo its own 5 volt supply and join the grounds.

Forgetting the common ground. The signal is measured against the servo’s own ground, so if the two supplies share nothing the pulse means nothing.

Asking for angles the servo cannot reach. A pulse outside the servo’s window is ignored rather than obeyed, just as a real SG90 strains against its end stop. If the horn stops short of 0 or 180, check the pulse widths the library is sending.

Updating the servo in a tight loop with no delay. Sending pulses faster than every 20 milliseconds gains nothing, because the servo only updates at its own frame rate.

## Questions

Which Arduino pins can drive a servo?

Any digital pin. The library makes the pulse in software, so the servo does not need one of the PWM pins marked with a tilde.

Can I drive two servos at once?

Yes. Create two Servo objects on two pins and write to each. Give real servos their own supply once there is more than one, because the current adds up.

Why does my servo jitter?

Usually because the reading it follows is noisy. Averaging a few analogRead() samples, as this sketch does, or ignoring changes of a degree or two, steadies it. On real hardware a sagging supply causes jitter too.

What is the difference between a servo and a stepper motor?

A servo goes to an angle and holds it, with its own feedback inside, usually over 180 degrees. A stepper turns by counted steps, as far as you like, and has no idea where it is unless you count. The stepper tutorial covers the 28BYJ-48.

Related

## Keep going

Arduino Potentiometer: analogRead and a Dimmer Arduino Stepper Motor: 28BYJ-48 and ULN2003 PWM: Faking an Analog Voltage on a Digital Pin The servo, pin by pin How the servo is modeled The project page, with the full sketch

## Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.

Start building Open the editor
