Push the joystick left or right and the servo turns smoothly in that direction, then stays where you leave it. Press down on the stick and it returns to the centre. It's the starting point for a camera mount, a robot head or a turret.
What you need
- UNO R3 board and USB cable
- Joystick module
- Servo motor
- Breadboard and jumper wires (all from the UNO R3 Starter Kit)
Wiring

| From | To |
|---|---|
| Joystick GND | GND (breadboard − rail) |
| Joystick +5V | 5V (breadboard + rail) |
| Joystick VRx | UNO A0 |
| Joystick VRy | Not connected |
| Joystick SW | UNO pin 2 |
| Servo brown (GND) | GND (breadboard − rail) |
| Servo red (power) | 5V (breadboard + rail) |
| Servo orange (signal) | UNO pin 9 |
Build it step by step
- Plug the joystick into the breadboard and connect the UNO's 5V and GND to the rails.
- Wire VRx to A0 and SW to pin 2.
- Connect the servo's three wires to the rails and to pin 9.
- Upload the code. The servo moves to the centre (90°).
- Push the stick left and right, then press it to return to the centre.
The code
#include <Servo.h>
const int X_PIN = A0;
const int BUTTON_PIN = 2;
const int SERVO_PIN = 9;
const int DEAD_ZONE = 60; // ignore tiny movements around the centre
const float MAX_STEP = 3.0; // degrees per update at full tilt
Servo pan;
float angle = 90;
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP); // pressed = LOW
pan.attach(SERVO_PIN);
pan.write(90);
}
void loop() {
int offset = analogRead(X_PIN) - 512; // about -512 to +511
if (abs(offset) > DEAD_ZONE) {
angle += offset / 512.0 * MAX_STEP; // further tilt = faster turn
angle = constrain(angle, 0, 180);
}
if (digitalRead(BUTTON_PIN) == LOW) {
angle = 90; // press the stick to centre
}
pan.write((int)angle);
delay(20);
}
How it works
The joystick's X axis is a potentiometer, so analogRead() gives about 512 in the middle and 0 or 1023 at the ends. Instead of mapping the stick straight to an angle, the sketch uses the tilt as a speed: the further you push, the faster the angle changes, and letting go keeps the servo where it is. The dead zone stops the servo creeping when the stick rests slightly off-centre.
Make it your own
- Add a second servo on pin 10 and VRy on A1 for a pan-and-tilt mount.
- Change
MAX_STEPto make the movement faster or gentler. - Map the stick straight to the angle with
map()and compare how it feels.
Troubleshooting
-
The servo drifts on its own: increase
DEAD_ZONE. -
It moves the wrong way: change
angle +=toangle -=. - The board resets when the servo moves: use a better USB port, or a separate 5 V supply for the servo with GND shared.
Learn the basics first
New to these parts? These lessons explain them step by step: Control a servo motor and Read a joystick.
0 comments