How to Use a Joystick with ESP32: Complete Beginner’s Guide (Wiring + Code)

An analog joystick module wired to an ESP32 development board on a transparent breadboard, with a laptop screen in the background showing real-time X and Y coordinate data in the Arduino IDE Serial Monitor.

The “I Control This” Moment | Joystick with ESP32 

Remember old-school gaming controllers? PlayStation, Xbox, arcade machines.

That joystick in your thumb? It wasn’t magic.

Inside, it’s just two variable resistors (potentiometers) and a button. Your thumb moves the stick. The stick moves the potentiometers. The potentiometers change voltage. The microcontroller reads that voltage.

And suddenly, you’re controlling a robot. Or a camera. Or a game.

Today, you’ll learn exactly how a joystick works. You’ll wire it to Joystick with ESP32. You’ll read real-time X and Y values. You’ll detect button presses.

And by the end, you’ll be ready to build your own RC car, robot arm, or game controller.

What is a Joystick Module?

A joystick module is an input device that tells you two things:

 
 
AxisWhat It Measures
X-axisLeft (-) to Right (+) movement
Y-axisForward (-) to Backward (+) movement

Plus, most modules have a push button when you press the stick down.

Inside the module:

  • Two 10kΩ potentiometers (one for X, one for Y)

  • One momentary push button (the “SW” pin)

  • Springs that return the stick to center when released

An extreme close-up view of two hands carefully holding a disassembled analog joystick module over a green grid mat. The black thumbstick cap is off to the side, exposing the white mechanical center and the two green side potentiometers. Clear pin labeling for GND, +5V, VRx, VRy, and SW is visible on the PCB edge.

How the Joystick Outputs Values | Joystick with ESP32 

When you move the joystick, the potentiometers change resistance. This changes the voltage on the signal pins.

The ESP32 reads this voltage using its ADC (Analog to Digital Converter) pins.

 
 
InputVoltage RangeESP32 Reading Range
Minimum (full left/up)0V0
Center (rest position)~1.65V~2048
Maximum (full right/down)3.3V4095

Important: The ESP32’s ADC is 12-bit, giving readings from 0 to 4095. This is more precise than Arduino Uno’s 10-bit (0-1023) range.

A screenshot of a dark-themed integrated development environment (IDE) terminal window showing a continuous stream of data. Each line displays X and Y axis coordinate values along with a "Button: 1" status, representing real-time input from a Joystick with ESP32.

What You’ll Need to Connect the Joystick with ESP32

 
 
ComponentSpecs / NotesPrice (USD)
ESP32 Development BoardAny 30-pin version$5.00 – $7.00
Joystick ModuleXY axes + center push button$1.00 – $2.00
Breadboard400 points (optional)$1.00 – $2.00
Jumper WiresMale-to-Female and Male-to-Male$2.00 – $4.00
USB CableFor programming and power$2.00 – $4.00

Total: ~$11.00 – $19.00 USD

Quick Buy Links

 
 
ComponentWhere to Find
ESP32 Development BoardAliExpress
Joystick ModuleAliExpress
Breadboard (400 points)AliExpress
Jumper Wires KitAliExpress
A top-down view on a green cutting mat showing a black analog joystick module being held by a thumb, connected via four jumper wires (orange, green, black, white) to an ESP32 development board. The ESP32 is mounted on a small white breadboard, illustrating a clean prototype setup for a Joystick with ESP32 project.

Wiring the Joystick to ESP32 | Joystick with ESP32 

The joystick module has 5 pins:

 
 
Joystick PinESP32 PinFunction
GNDGNDGround
5V (or VCC)VIN (5V)Power (5V works, 3.3V also works but range may differ)
VRx (X-axis)GPIO 34Analog input (ADC)
VRy (Y-axis)GPIO 35Analog input (ADC)
SW (button)GPIO 15Digital input (with internal pull-up)

Note about analog pins: GPIO 34, 35, 36, and 39 are input-only pins. They don’t have internal pull-up or pull-down resistors, but they’re perfect for reading analog sensors like this joystick.

The Code | Joystick with ESP32 

This code reads the joystick position 50 times per second and prints the values to the Serial Monitor.

➕➕
filename.cpp
// ============================================================
// ESP32 Joystick Reader - Complete Beginner Guide
// Reads X/Y analog values and button state
// ============================================================

// Pin Definitions
#define JOYSTICK_X 34
#define JOYSTICK_Y 35
#define JOYSTICK_SW 15

// Variables for calibration
int xValue = 0;
int yValue = 0;
int swValue = 0;

void setup() {
  Serial.begin(115200);
  
  // Configure button pin with internal pull-up
  // (INPUT_PULLUP means pin reads HIGH when not pressed, LOW when pressed)
  pinMode(JOYSTICK_SW, INPUT_PULLUP);
  
  // Analog pins don't need pinMode setup
  
  Serial.println("ESP32 Joystick Reader");
  Serial.println("=====================");
  Serial.println("Move the joystick and press the button...\n");
  delay(1000);
}

void loop() {
  // Read analog values (0-4095)
  xValue = analogRead(JOYSTICK_X);
  yValue = analogRead(JOYSTICK_Y);
  
  // Read digital button (LOW when pressed, HIGH when not pressed)
  // The ! (NOT) inverts the reading so pressed = true
  bool buttonPressed = !digitalRead(JOYSTICK_SW);
  
  // Map values to -100 to +100 range for easier understanding
  int mappedX = map(xValue, 0, 4095, -100, 100);
  int mappedY = map(yValue, 0, 4095, -100, 100);
  
  // Small dead zone to eliminate jitter at center
  if (abs(mappedX) < 10) mappedX = 0;
  if (abs(mappedY) < 10) mappedY = 0;
  
  // Print to Serial Monitor
  Serial.print("X: ");
  Serial.print(xValue);
  Serial.print(" (");
  Serial.print(mappedX);
  Serial.print(") | Y: ");
  Serial.print(yValue);
  Serial.print(" (");
  Serial.print(mappedY);
  Serial.print(") | Button: ");
  Serial.println(buttonPressed ? "PRESSED" : "released");
  
  delay(50);  // Read 20 times per second (smooth enough, not too fast)
}

Understanding the Serial Monitor Output | Joystick with ESP32 

After uploading, open Serial Monitor (Tools → Serial Monitor, baud 115200).

Move the joystick. You’ll see something like:

text
X: 2048 (0) | Y: 2048 (0) | Button: released
X: 4095 (100) | Y: 2048 (0) | Button: released
X: 0 (-100) | Y: 2048 (0) | Button: released
X: 2048 (0) | Y: 4095 (100) | Button: released
X: 2048 (0) | Y: 0 (-100) | Button: released
X: 2048 (0) | Y: 2048 (0) | Button: PRESSED
 
 
ReadingMeaning
X: 2048 (0)Joystick centered left-right
X: 4095 (100)Full right
X: 0 (-100)Full left
Y: 2048 (0)Joystick centered forward-back
Y: 4095 (100)Full forward (away from you)
Y: 0 (-100)Full backward (toward you)
Button: PRESSEDJoystick knob pressed down

Calibrating Your Joystick | Joystick with ESP32 

Every joystick is slightly different. The center position might not be exactly 2048.

To calibrate:

  1. Run the code and open Serial Monitor

  2. Let go of the joystick (let it center itself)

  3. Note the X and Y values at rest

  4. Adjust the map function if needed:

cpp
// If your center X is 2100 instead of 2048, adjust the mapping:
int mappedX = map(xValue, 0, 4095, -100, 100);
// Or apply an offset:
int mappedX = map(xValue - 52, 0, 4095, -100, 100);

Most of the time, the default mapping is fine. The dead zone (if (abs(mappedX) < 10) mappedX = 0;) will ignore small center offsets.


What You Can Control with a Joystick | Joystick with ESP32 

Once you can read joystick values, you can control almost anything:

 
 
OutputHow to Control
LED brightnessMap Y value (0-4095) to PWM value (0-255)
Servo angleMap X value to servo degrees (0-180)
Motor speedMap Y value to motor speed (-255 to +255)
RGB LED colorUse X for red, Y for green
Camera pan/tiltX controls pan servo, Y controls tilt servo
Robot movementX = turning, Y = forward/backward
A hand operates an analog joystick module connected to an ESP32 on a breadboard. The system is wired to an SG90 micro servo motor, which is shown in motion. In the background, a laptop displays the Arduino IDE Serial Monitor showing live coordinate data.

Simple Project: Joystick-Controlled LED Brightness | Joystick with ESP32 

Here’s a quick project to test your joystick. It uses the Y-axis to control an LED’s brightness.

Add to your circuit: LED anode (+) → GPIO 26 through 220Ω resistor, LED cathode (-) → GND.

➕➕
filename.cpp
#define JOYSTICK_Y 35
#define LED_PIN 26

int yValue = 0;
int ledBrightness = 0;

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
  ledcSetup(0, 5000, 8);
  ledcAttachPin(LED_PIN, 0);
}

void loop() {
  yValue = analogRead(JOYSTICK_Y);
  ledBrightness = map(yValue, 0, 4095, 0, 255);
  ledcWrite(0, ledBrightness);
  
  Serial.print("Y: ");
  Serial.print(yValue);
  Serial.print(" | Brightness: ");
  Serial.println(ledBrightness);
  
  delay(50);
}

Push the joystick forward → LED gets brighter. Pull back → LED dims.

More ESP32 output projects – Sound Sensor Module Project: ESP32 Sound Activated LED + Buzzer Project

Mini Project: Joystick-Controlled Servo (Pan Camera)

Let’s build a simple but fun project: control a servo motor using the joystick’s X-axis. This is the perfect next step after learning to read joystick values.

What You’ll Need | Joystick with ESP32

 
 
ComponentQuantity
ESP32 (from the main project)1
Joystick module (already wired)1
SG90 Servo motor1
Jumper wires (female-to-female)3

Additional Wiring | Joystick with ESP32

 
 
Servo WireESP32 Pin
Brown/Black (GND)GND
Red (VCC)5V (or external 5V power)
Orange/Yellow (Signal)GPIO 13

Power note: A single SG90 servo can be powered from the ESP32’s 5V pin for testing. For multiple servos or長時間 use, use external power.

The Code

➕➕
filename.cpp
#include <ESP32Servo.h>

// Joystick pins (same as main project)
#define JOYSTICK_X 34
#define JOYSTICK_Y 35
#define JOYSTICK_SW 15

// Servo pin
#define SERVO_PIN 13

Servo myServo;

void setup() {
  Serial.begin(115200);
  
  // Attach servo
  myServo.attach(SERVO_PIN);
  
  // Configure joystick button
  pinMode(JOYSTICK_SW, INPUT_PULLUP);
  
  Serial.println("Joystick Servo Control Ready!");
  Serial.println("Move joystick left/right to control servo angle");
}

void loop() {
  // Read joystick X-axis value (0-4095)
  int xValue = analogRead(JOYSTICK_X);
  
  // Map to servo angle (0-180 degrees)
  int angle = map(xValue, 0, 4095, 0, 180);
  
  // Move servo
  myServo.write(angle);
  
  // Print to Serial Monitor
  Serial.print("X: ");
  Serial.print(xValue);
  Serial.print(" | Angle: ");
  Serial.println(angle);
  
  // Optional: Read joystick button
  bool buttonPressed = !digitalRead(JOYSTICK_SW);
  if (buttonPressed) {
    Serial.println("Button pressed!");
    myServo.write(90);  // Center servo when button pressed
    delay(500);
  }
  
  delay(15);  // Small delay for smooth servo movement
}
A top-down view of an electronics workbench featuring an ESP32-Dev-Kit-V1 connected to a 3D-printed pan-tilt module. The module holds a small camera and is powered by two blue micro servos. Nearby are an OLED display, a schematic diagram, and various assembly tools on a wooden board labeled "Next Project Idea."

How It Works | Joystick with ESP32

 
 
Joystick PositionServo Angle
Full left (X = 0)0 degrees
Center (X = 2048)90 degrees
Full right (X = 4095)180 degrees
Button pressCenters servo to 90 degrees

What You’ll See | Joystick with ESP32

Move the joystick left and right. The servo arm will follow your movement smoothly. Press the joystick down – the servo centers automatically.

Challenge Yourself | Joystick with ESP32

Once this works, try these upgrades:

 
 
ChallengeWhat to Change
Use Y-axisChange analogRead(JOYSTICK_Y) and map to servo
Add second servoConnect second servo to GPIO 14, one for X, one for Y
Reverse directionSwap map values: map(xValue, 0, 4095, 180, 0)
Finer controlReduce movement range: map(xValue, 0, 4095, 45, 135)

Complete System Diagram | Joystick with ESP32

text
Joystick X-axis → ESP32 GPIO 34 → map(0-4095 → 0-180) → Servo on GPIO 13

This mini project teaches you:

  • ✅ How to read analog input from a joystick

  • ✅ How to convert sensor values to control outputs

  • ✅ How to control a servo with PWM

  • ✅ Real-world application: camera pan mechanism

This is the exact same principle used in CCTV pan-tilt systems, robot head movement, and RC camera gimbals. Once you master this, you can build a complete pan-tilt camera system by adding a second servo for tilt control!

Troubleshooting | Joystick with ESP32 

 
 
ProblemLikely CauseFix
Serial Monitor shows no valuesWrong baud rateSet Serial Monitor to 115200 baud
Values stuck at 4095 or 0VCC or GND not connectedCheck joystick power wiring
X and Y values swappedWiring mismatchSwap VRx and VRy pins, or swap in code
Button always shows “released”SW pin not connectedCheck jumper from SW to GPIO 15
Button always shows “pressed”Missing pull-upUse pinMode(JOYSTICK_SW, INPUT_PULLUP)
Values jump erraticallyFloating analog pinsAnalog pins are fine, but check power stability
Center position not at 2048Normal variationAdd dead zone or calibration offset

🎥 Watch the Complete Video Tutorial | Joystick with ESP32 

See the joystick in action with real-time demonstrations and code explanation:

📺 How to Use a Joystick with ESP32 | Complete Guide for Beginners

👉 Don’t forget to Subscribe to Roborear on YouTube for more ESP32 tutorials and robotics projects every week!

How It Works | Joystick with ESP32

 
 
Joystick PositionServo Angle
Full left (X = 0)0 degrees
Center (X = 2048)90 degrees
Full right (X = 4095)180 degrees
Button pressCenters servo to 90 degrees

What You’ll See | Joystick with ESP32

Move the joystick left and right. The servo arm will follow your movement smoothly. Press the joystick down – the servo centers automatically.

Challenge Yourself | Joystick with ESP32

Once this works, try these upgrades:

 
 
ChallengeWhat to Change
Use Y-axisChange analogRead(JOYSTICK_Y) and map to servo
Add second servoConnect second servo to GPIO 14, one for X, one for Y
Reverse directionSwap map values: map(xValue, 0, 4095, 180, 0)
Finer controlReduce movement range: map(xValue, 0, 4095, 45, 135)

Complete System Diagram | Joystick with ESP32

text
Joystick X-axis → ESP32 GPIO 34 → map(0-4095 → 0-180) → Servo on GPIO 13

This mini project teaches you:

  • ✅ How to read analog input from a joystick

  • ✅ How to convert sensor values to control outputs

  • ✅ How to control a servo with PWM

  • ✅ Real-world application: camera pan mechanism

This is the exact same principle used in CCTV pan-tilt systems, robot head movement, and RC camera gimbals. Once you master this, you can build a complete pan-tilt camera system by adding a second servo for tilt control!

Your Turn | Joystick with ESP32 

The joystick is one of the most versatile input devices for robotics. Master it, and you can control anything.

Now go build something. An RC car. A robot arm. A game controller.

The joystick is waiting. I hope you liked the tutorial on the Joystick with ESP32 connection. Read all Roborear tutorials for beginners – Blogs

FAQs

1. Why are my joystick values stuck at 4095 or 0? - Joystick with ESP32

This means your ESP32 isn't reading varying voltage from the joystick. First, check that you connected the joystick's VCC pin to the ESP32's VIN (5V) pin, not 3.3V. While 3.3V works, the voltage range will be different. The more common issue is a missing GND connection – the joystick needs a ground reference to output varying voltages. Second, verify you're using analog pins (GPIO 34, 35, 36, or 39). These are the only pins on the ESP32 that support analog input. Third, if values are stuck at 0, your VRx/VRy wires might be swapped with GND or VCC. Double-check the wiring against the pin table. Finally, test with a multimeter. Measure voltage between GND and VRx while moving the joystick. You should see voltage change from 0V to ~3.3V. If not, the joystick module may be faulty.

2. My readings are jumpy or unstable, even when the joystick is still - Joystick with ESP32 

This is usually electrical noise, not a faulty joystick. First, add a small dead zone in your code. The example code already includes if (abs(mappedX) < 10) mappedX = 0; – this ignores tiny movements near center. Adjust the 10 value higher (e.g., 15 or 20) if needed. Second, check your power supply. The ESP32's analog readings can be noisy when powered from a computer's USB port. Try a phone charger or add a 100µF capacitor between 3.3V and GND near the joystick. Third, the ESP32's ADC is known to have non-linearity, especially at extreme values. For most joystick applications (RC car, robot arm), this isn't noticeable. For precision applications, consider averaging multiple readings: cpp int smoothRead(int pin) { int total = 0; for (int i = 0; i < 10; i++) { total += analogRead(pin); delay(1); } return total / 10; } Fourth, keep wires short. Long jumper wires act as antennas and pick up noise.

3. How do I use this joystick to control a servo or motor? - Joystick with ESP32 

The core concept is mapping the joystick's analog values to control signals. For a servo (from earlier tutorial library): cpp #include Servo myServo; int servoAngle = map(xValue, 0, 4095, 0, 180); myServo.write(servoAngle); For a motor (using L298N or similar driver): cpp int motorSpeed = map(yValue, 0, 4095, -255, 255); if (motorSpeed > 0) { digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); } else { digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); } ledcWrite(0, abs(motorSpeed)); For an RGB LED: cpp int red = map(xValue, 0, 4095, 0, 255); int green = map(yValue, 0, 4095, 0, 255); ledcWrite(0, red); // Assuming red on channel 0 ledcWrite(1, green); // Assuming green on channel 1 The key pattern is: Read analog → Map to output range → Send to output device. For a complete RC car project using two ESP32s (one for joystick, one for car), check the internal link to the ESP32 RC Car tutorial below.

4. Can I use two joysticks with one ESP32? How many analog pins do I need? - Joystick with ESP32 

Yes, absolutely! Using two joysticks is common for projects like dual-stick game controllers, RC tank controls, or camera + movement control . Each joystick requires: 2 analog pins (VRx and VRy) 1 digital pin (SW button) For two joysticks, you need 4 analog pins and 2 digital pins. Important: GPIO 34, 35, 36, and 39 are input-only pins – perfect for analog joysticks since they don't need output functionality. For a complete dual-joystick controller example, you can adapt the single joystick code by creating separate variables and reading each joystick independently in the loop. Many RC projects use this setup for controlling movement with one joystick and camera/servo with the other.

5. Why are my joystick values jumping around even when the stick is centered? - Joystick with ESP32 

This is called ADC noise or signal jitter, and it's completely normal, especially with ESP32's built-in analog-to-digital converter. The ESP32 has a 12-bit ADC, which gives readings from 0 to 4095. When the joystick is centered, the theoretical value should be around 2048. But in reality, you'll see values like 2042, 2051, 2038 – constantly fluctuating by 5-15 counts. The fix: Add a "dead zone" in your code. This dead zone prevents your robot or servo from twitching when the joystick is centered . Any movement less than 10% of full range is treated as "center." If the jitter is extreme (50+ count jumps), check your power supply – noisy power can cause unstable ADC readings . Adding a 100µF capacitor across the joystick's VCC and GND can help stabilize the readings.

Subscribe to The Newsletter

Join robotics enthusiasts getting weekly project ideas:

• 🔧 Under $50 projects

• ⚙️ Under $100 projects

• 🎥 New video tutorials

• 📝 Blog updates

We don’t spam! Read our privacy policy for more info.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

Roborear Logo
Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.