Lesson 1.4: Analog joystick
A thumb joystick turns a gesture into two numbers. Use it to move a servo, steer a robot or navigate a menu.
Parts
How it works
Each axis is a potentiometer: moving the stick changes the voltage on its middle pin between 0 and 5 V. analogRead() turns it into a number between 0 and 1023, and at rest both axes read close to 512.
No joystick returns exactly to the centre, so you define a dead zone: while the reading stays near 512, it counts as at rest.
Pushing the stick down closes a button between SW and GND. As with any push button, use INPUT_PULLUP: released reads HIGH and pressed reads LOW.
Wiring
| Component | Connects to | Note |
|---|---|---|
| Joystick, GND | GND | |
| Joystick, +5V | 5V | |
| Joystick, VRx | A0 | |
| Joystick, VRy | A1 | |
| Joystick, SW | Pin 2 |
Code
// Reads the joystick and prints where it points.
const int X_PIN = A0;
const int Y_PIN = A1;
const int SW_PIN = 2;
const int DEAD_ZONE = 100; // margin around the centre
void setup() {
pinMode(SW_PIN, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
int x = analogRead(X_PIN);
int y = analogRead(Y_PIN);
bool pressed = digitalRead(SW_PIN) == LOW;
Serial.print("X: ");
Serial.print(x);
Serial.print(" Y: ");
Serial.print(y);
Serial.print(" ");
if (x < 512 - DEAD_ZONE) Serial.print("left ");
if (x > 512 + DEAD_ZONE) Serial.print("right ");
if (y < 512 - DEAD_ZONE) Serial.print("up ");
if (y > 512 + DEAD_ZONE) Serial.print("down ");
if (pressed) Serial.print("[pressed]");
Serial.println();
delay(200);
}What the code does
- analogRead() returns 0 to 1023 because the Uno's analog converter is 10-bit.
- DEAD_ZONE stops noise around the centre from reading as movement. Tune it to your joystick.
- The ifs have no else: on a diagonal two of them match and both directions are printed.
Step by step
- Connect the module with five female-to-male wires following the table.
- Upload the code and open the serial monitor at 9600 baud.
- Move the stick in all four directions and push it down.
Result
The serial monitor shows the X and Y values, the direction the stick points and whether it's pressed.
If it doesn't work
- If the directions come out reversed, it depends on how the module is oriented: swap the labels or invert the comparisons.
- If a direction appears at rest, increase DEAD_ZONE.
- If the button doesn't respond, press firmly: on many modules the click is stiff.