Bench NotesUno handbook

Analog Five-Position Servo Control

A potentiometer snaps a servo between five fixed angles: 0°, 45°, 90°, 135° and 180°.

BeginnerServoPotentiometer

Overview

Instead of following the knob smoothly, the servo jumps between five positions. The potentiometer's range is split into five equal bands, and each band selects one angle, 45° apart.

You will need

  • Arduino Uno R3 and USB cable
  • 10 kΩ potentiometer (5 mm leg pitch)
  • Hobby servo, for example an SG90 micro servo
  • Jumper wires; optional separate 5–6 V servo supply

Wiring

Uno pinConnects toNotes
A0Potentiometer outer legSketch sets A0 as an OUTPUT, LOW. This is the pot's 0 V end.
A2Potentiometer wiper (middle leg)Analog input. Reads 0–1023.
A4Potentiometer other outer legSketch sets A4 as an OUTPUT, HIGH. This is the pot's 5 V end.
10Servo signal wire (orange or yellow)Servo library pulse output.
5VServo V+ (red)Only for one small, lightly loaded micro servo. Otherwise use a separate supply; see the power note.
GNDServo GND (brown or black)Must be shared with any external servo supply.
Wiring for Analog Five-Position Servo ControlArduino Uno A0 (driven LOW) to 10 kΩ potentiometer outer leg 1; Arduino Uno A2 (input) to 10 kΩ potentiometer wiper (middle); Arduino Uno A4 (driven HIGH) to 10 kΩ potentiometer outer leg 2; Arduino Uno D10 to Servo signal (orange/yellow); Arduino Uno 5V to Servo V+ (red); Arduino Uno GND to Servo GND (brown/black).Connections (each line is one wire)Arduino Uno10 kΩ potentiometerServoA0 (driven LOW)outer leg 1A2 (input)wiper (middle)A4 (driven HIGH)outer leg 2D10signal (orange/yellow)5VV+ (red)GNDGND (brown/black)
Original wiring diagram. Each line is one jumper wire; boxes on a line are series resistors.

How the pins are arranged

Read before wiring

This project powers the potentiometer from analog pins instead of the 5V and GND sockets. A 10 kΩ potentiometer has three legs about 5 mm apart, which matches every second socket on the Uno's analog header. Push its outer legs into A0 and A4 and its wiper into A2. The sketch sets A0 as a LOW output (0 V) and A4 as a HIGH output (5 V), so the pot sees a full 0–5 V span and the wiper on A2 reads anywhere from 0 to 1023.

This works because a 10 kΩ pot draws only about 0.5 mA, far below what a pin can supply. Do not use this trick with a pot under about 5 kΩ, and keep in mind that A4 is also the I²C data line (SDA): the pot and an I²C device cannot share it. See Using analog pins as digital outputs for the details.

A single micro servo such as an SG90, moving freely with nothing attached to its horn, can usually run from the Uno's 5V pin while the board is on USB. Any bigger servo, more than one servo, or a servo pushing against a load can pull several hundred milliamps in bursts. That causes the board to reset, the USB connection to drop, or the servo to jitter. In those cases power the servo from a separate regulated 5–6 V supply and connect that supply's ground to the Uno's GND. See Powering servos safely.

Diagrams

Header placementA 10 kilohm potentiometer with its outer legs in A0 and A4 and its wiper in A2. The sketch drives A0 LOW and A4 HIGH so the pot gets 0 and 5 volts. The servo signal wire goes to pin 10.Arduino Uno R3 — parts plugged straight into the headerGND13121110A0A1A2A3A410 kΩ potentiometerA0 = LOW (0 V), A2 = wiper, A4 = HIGH (5 V)Servo signal wire to pin 10
Potentiometer in A0/A2/A4; servo signal on pin 10.
Five servo positionsSemicircle from 0 to 180 degrees showing servo arm positions in order: 0 degrees, 45 degrees, 90 degrees, 135 degrees, 180 degrees. One per fifth of the knob's travel0°90°180°04590135180Angles1. 0°2. 45°3. 90°4. 135°5. 180°One per fifth of the knob's travel
The five angles the servo can take.

The sketch

five_position_analog_servo.ino
#include <Servo.h>
Servo servoMotor;

int potentiometerPin = A2;
int potentiometerReading;

void setup() {
  pinMode(A2, INPUT);
  pinMode(A0, OUTPUT);
  pinMode(A4, OUTPUT);
  digitalWrite(A0, LOW);
  digitalWrite(A4, HIGH);
  servoMotor.attach(10);
}

void loop() {
  potentiometerReading = analogRead(potentiometerPin);
  int stepIndex = map(potentiometerReading, 0, 1024, 0, 5);
  servoMotor.write(stepIndex * 45);
  delay(15);
}

How the code works

The upper bound of 1024 in map(…, 0, 1024, 0, 5) is deliberate. map() uses integer maths and rounds down, so readings 0–204 give 0, 205–409 give 1, and so on, with 819–1023 giving 4. Every band is about the same width and the result never reaches 5. Using 1023 would make index 4 occur only at the single reading 1023.

The Servo library on the Uno uses Timer1, which disables analogWrite() on pins 9 and 10. This sketch uses neither for PWM, so there is no conflict.

Review result: no changes were needed.

What you should observe

  • The servo holds still while you turn the knob within one band, then jumps 45° when you cross into the next.
  • Full counter-clockwise (A0 end) gives 0°; full clockwise (A4 end) gives 180°.
  • Near a band boundary the servo may twitch between two positions; this is noise in the reading, not a fault.