Move robot arms, control vehicles, build game controllers and more with joysticks and Arduino!
In this introduction to using joysticks with Arduino, I’ll walk you through how to wire a KY-023 joystick module to an Arduino Uno. Then we’ll write an Arduino sketch so we can see the analog values that the joystick produces in 2D space as we move it around.
These x- and y-values can then be mapped to control a variety of other components in your Arduino project.
Whether you’re creating a custom game controller, navigating menus, or controlling a robot, understanding how to integrate a joystick with your Arduino setup will add a new level of interactivity and precision to your creations.
Let’s get started on this exciting journey into the world of Arduino and joysticks!
Joystick Module Pinout

The KY-023 joystick module has 5 pins that can all be connected directly to the Arduino Uno:
- GND pin: Provides ground for the joystick module.
- +5V pin: Provides power to the joystick module.
- VRx pin: Outputs an analog value (0-1023) corresponding to the X-axis position.
- VRy pin: Outputs an analog value (0-1023) corresponding to the Y-axis position.
- SW pin: Outputs a digital signal (HIGH or LOW) indicating the switch/button state (pressed or not pressed).
How a Joystick Module Works with Arduino
A joystick module converts physical movements into electrical signals that can be read and processed by a microcontroller like an Arduino to then control other electronic components.
Joystick Movement
The joystick consists of a lever that can be moved in two dimensions: X-axis (left-right) and Y-axis (up-down). When you move the joystick lever, it changes the position of two potentiometers inside the module.
Potentiometers
Potentiometers are variable resistors that change their resistance based on the position of the joystick lever. The joystick module typically has two potentiometers:
- VRx: Measures the position along the X-axis.
- VRy: Measures the position along the Y-axis.
As the joystick lever moves, the resistance of these potentiometers changes, which alters the voltage output.
Analog Signals
The changing resistance of the potentiometers generates corresponding analog voltage signals. These analog signals are proportional to the position of the joystick lever, ranging from 0V (corresponding to an ADC value of 0) to the supply voltage, which is usually 5V (corresponding to an ADC value of 1023) or 3.3V depending on the microcontroller you’re using.
Reading the Signals
The analog signals from the VRx and VRy pins are read by the analog input pins of the Arduino using the analogRead() function. The analogRead() function converts the analog voltage into a digital value between 0 and 1023, representing the position of the joystick along each axis.
Push Button Switch
Many joystick modules also include a push-button switch that is activated when the joystick lever is pressed down. The switch generates a digital signal (HIGH or LOW) that can be read by a digital input pin on the Arduino using the digitalRead() function.
Processing the Data
The Arduino processes the analog and digital signals to determine the position and state of the joystick. These values can be used to control various outputs, such as moving a robot, adjusting the position of a servo, or navigating a user interface.
Hook-up Guide: Connect a Joystick to Arduino
Here’s how I connected my joystick to an Arduino Uno:

Joystick-to-Arduino Connections
| JOYSTICK | ARDUINO UNO |
|---|---|
| GND | GND |
| +5V | 5V |
| VRx | A0 |
| VRy | A1 |
| SW | 2 |
Arduino Code: Read ADC Values from the Joystick
This sketch will allow you to see the analog (ADC) values for the x- and y-axis as you move the joystick. You’ll also be able to test the joystick button to make sure it works.
Upload this sketch and open your serial monitor. Be sure to hold your joystick in the same orientation I did in the video. Point the joystick pins to the left of your thumb.
int xPin = A0;
int yPin = A1;
int buttonPin = 2;
int xVal; // variable for storing joystick x values
int yVal; // variable for storing joystick y values
int switchState; // variable for storing joystick switch state
void setup() {
pinMode(xPin, INPUT);
pinMode(yPin, INPUT);
pinMode(switchPin, INPUT_PULLUP);
Serial.begin(9600); // initialize the serial monitor
}
void loop() {
// read the x, y and joystick switch values
xVal = analogRead(xPin);
yVal = analogRead(yPin);
buttonState = digitalRead(switchPin);
// print readings to the serial monitor
Serial.print("X: ");
Serial.print(xVal);
Serial.print(" | Y: ");
Serial.print(yVal);
Serial.print(" | Switch: ");
Serial.println(switchState);
delay(100);
}
Watch the values being produced for the X and Y coordinates.
Pay special attention to your X and Y values with the joystick in the idle position. In a perfect world, both X and Y should be 511-512. Unfortunately this will rarely be the case.
Write down the value you see most for the x- and y-axis when your joystick is at idle. It may be different than mine and you’ll be using your values in the next Arduino joystick tutorials for controlling LEDs, servos and DC motors.
I got 511 for the x-axis and 489 for the y-axis.
Next, try moving the joystick slowly in each direction to see what happens to the analog values:
- Moving the joystick all the way UP should give you a value of 0 along the Y-AXIS
- Moving the joystick all the way DOWN should give you a value of 1023 along the Y-AXIS
- Moving the joystick all the way LEFT should give you a value of 0 along the X-AXIS
- Moving the joystick all the way RIGHT should give you a value of 1023 along the X-AXIS
Finally, push down on the joystick switch. You should see the value for the switch go from 1 to 0 while the switch is pushed. The switch value should then return to 1 when you release the switch.
Now that you know how the ADC values for both the X and Y coordinates relate to the position of the joystick, we can now map these values to control all kinds of components in Arduino projects.
Affiliate Disclosure: Some links here might earn me enough nuts and bolts (aka commission) to keep the LEDs blinking and servos turning. No extra cost to you, just a lil’ fuel for my caffeine-powered nights of DIY-ing. I only endorse stuff that’s survived my “Did-it-Explode?” test. Build on, and thanks for the recharge!
