A joystick is two potentiometers and a push button in one. Moving the stick changes two voltages, one for left and right and one for up and down, which the ESP32 reads with its analog inputs. It's the perfect controller for robots and games.
What you'll learn
- How the ESP32 reads analog values (0 to 4095)
- How to turn readings into directions
- How to read a button with the internal pull-up resistor
What you need
- ESP32-DevKitC V4 board and USB cable
- Joystick module (KY-023)
- Breadboard
- 5 jumper wires
Wiring
Power the joystick from 3V3, even though its pin is labelled +5V. That way its outputs stay within the ESP32's 3.3 V input range.

| Joystick pin | ESP32 pin |
|---|---|
| GND | GND |
| +5V | 3V3 |
| VRx | GPIO 34 |
| VRy | GPIO 35 |
| SW | GPIO 32 |
The sketch
const int X_PIN = 34;
const int Y_PIN = 35;
const int SW_PIN = 32;
void setup() {
Serial.begin(115200);
pinMode(SW_PIN, INPUT_PULLUP); // the button connects SW to GND when pressed
}
void loop() {
int x = analogRead(X_PIN); // 0 to 4095
int y = analogRead(Y_PIN);
bool pressed = digitalRead(SW_PIN) == LOW;
String direction = "centre";
if (x < 1000) direction = "left";
else if (x > 3000) direction = "right";
else if (y < 1000) direction = "up";
else if (y > 3000) direction = "down";
Serial.print("X: ");
Serial.print(x);
Serial.print(" Y: ");
Serial.print(y);
Serial.print(" ");
Serial.print(direction);
if (pressed) Serial.print(" [button pressed]");
Serial.println();
delay(100);
}
Open the Serial Monitor at 115200 baud and move the stick. Depending on how you hold the module, "up" and "down" may be swapped. That's fine, just rename them in the code.
How it works
The ESP32's analog-to-digital converter turns a voltage between 0 and about 3.3 V into a number from 0 to 4095. In the centre, both axes read roughly the middle of that range (often around 1800 to 2000 on the ESP32). The sketch treats anything below 1000 or above 3000 as a clear push in that direction. Pressing the stick down closes the built-in button, which pulls SW to GND.
Try this next
- Use the joystick to set the brightness of the LED from lesson 1 with
analogWrite(). - Print the readings in the Serial Plotter to see both axes as live graphs.
Troubleshooting
- The values jump around: that's normal for the ESP32's ADC. Average a few readings, or widen the thresholds.
-
The button always reads pressed: check that SW is on GPIO 32 and
INPUT_PULLUPis set. - An axis always reads 0 or 4095: check the +5V and GND wires.