The joystick module is a versatile input device commonly used in maker projects. In this article, you’ll learn how to connect an Arduino joystick to an Arduino UNO, how it works, and how to use it in your next project.
How the Joystick Works
The joystick module uses potentiometers for the x-axis and y-axis. When the joystick is moved, the resistance of the potentiometers changes, resulting in a change in the output voltage. This voltage is read by the Arduino and converted into a numerical value between 0 and 1023.
You can use these values to determine the direction the joystick was moved: up, down, left, or right. In addition to the potentiometers for the x- and y-axes, there is usually a button that you can activate by pressing the stick down. You can read this input in your sketch and use it in your project as needed.
Connecting the Joystick
A typical Arduino joystick has five pins. Power, ground, and the connections for the x- and y-axes are mandatory. The SW pin is connected to the button—if your project doesn’t require a button, you can leave this pin unconnected. However, in this guide, we’ll use all five pins.
Note: The labeling of the pins may vary depending on the model. Typically, VRx is for the horizontal x-axis, and VRy is for the vertical y-axis.
Initial Test with the Arduino Joystick
Now that the joystick is connected, it’s time for an initial test. Here, you’ll simply read the joystick’s movements and the button state and display the actions on the Serial Monitor.
___STEADY_PAYWALL___
Copy the following sketch and upload it to your Arduino:
const int joyPinX = A0; // Pin for the joystick's x-axis
const int joyPinY = A1; // Pin for the joystick's y-axis
const int joyPinSW = A2; // Pin for the joystick's button
void setup() {
pinMode(joyPinSW, INPUT_PULLUP); // Set the button pin as input with internal pull-up resistor
Serial.begin(9600); // Start serial communication
}
void loop() {
int xValue = analogRead(joyPinX); // Read x-axis
int yValue = analogRead(joyPinY); // Read y-axis
int swValue = analogRead(joyPinSW); // Read button state
// Determine direction
String direction = "Center";
if (xValue > 600) {
direction = "Right";
} else if (xValue < 400) {
direction = "Left";
}
if (yValue > 600) {
direction = "Down";
} else if (yValue < 400) {
direction = "Up";
}
// Display values on Serial Monitor
Serial.print("Direction: ");
Serial.print(direction);
Serial.print(" | X: ");
Serial.print(xValue);
Serial.print(" | Y: ");
Serial.print(yValue);
Serial.print(" | Button: ");
Serial.print(swValue);
if (swValue < 20) {
Serial.println(" | Pressed!");
} else {
Serial.println(" | ");
}
delay(100); // Short pause
}
Test your joystick now—do you see the directions and a message when the button is pressed in the Serial Monitor? If the directions don’t align with your movements, position the joystick as shown in this photo. 😉
How the Sketch Works
First, you define the pins where your joystick is connected to the Arduino UNO:
const int joyPinX = A0; // Pin for the joystick's x-axis
const int joyPinY = A1; // Pin for the joystick's y-axis
const int joyPinSW = A2; // Pin for the joystick's button
In the setup, you specify that the button pin uses the internal pull-up resistor for reliable readings. You also initialize the Serial Monitor:
void setup() {
pinMode(joyPinSW, INPUT_PULLUP); // Button pin as input with pull-up resistor
Serial.begin(9600); // Start serial communication
}
The loop starts by reading the current values of the joystick and determining the pressed direction:
void loop() {
int xValue = analogRead(joyPinX); // Read x-axis
int yValue = analogRead(joyPinY); // Read y-axis
int swValue = analogRead(joyPinSW); // Read button state
// Determine direction
String direction = "Center";
if (xValue > 600) {
direction = "Right";
} else if (xValue < 400) {
direction = "Left";
}
if (yValue > 600) {
direction = "Down";
} else if (yValue < 400) {
direction = "Up";
}
As mentioned earlier, the joystick has two potentiometers, one for each axis. For the x-axis, for example, moving the joystick fully to the left results in a value of 0. These values increase until they reach around 500 in the neutral position. Moving it fully to the right results in the maximum value of 1023.
Finally, the sketch outputs the directions in the Serial Monitor and checks if the button is pressed:
// Display values on Serial Monitor
Serial.print("Direction: ");
Serial.print(direction);
Serial.print(" | X: ");
Serial.print(xValue);
Serial.print(" | Y: ");
Serial.print(yValue);
Serial.print(" | Button: ");
Serial.print(swValue);
if (swValue < 20) {
Serial.println(" | Pressed!");
} else {
Serial.println(" | ");
}
delay(100); // Short pause
}
A unique aspect of the joystick is that you need to detect the button press via an analog pin. An unpressed button typically gives a value of around 500. When pressed, this value drops to zero, which is detected using an if-statement in the sketch.
Analog Stick and Diagonal Movements
As seen in the Serial Monitor, your Arduino detects values based on the intensity of your movements with the Arduino Joystick. For example, moving right gradually increases the x-axis value until a value above 600 is registered as “moved right.” You can even detect fine movements, similar to an analog stick on a standard game controller.
To enhance your project, you can set multiple thresholds for different levels of movement. A value of 600 could represent slow motion, while the maximum value of 1023 indicates full speed.
Diagonal movements are also possible, as they are combinations of x- and y-values. Replace the “Determine direction” section of your sketch with the following code:
// Determine direction
String direction = "Center";
if (xValue > 600 && yValue > 600) {
direction = "Down-Right";
} else if (xValue > 600 && yValue < 400) {
direction = "Up-Right";
} else if (xValue < 400 && yValue > 600) {
direction = "Down-Left";
} else if (xValue < 400 && yValue < 400) {
direction = "Up-Left";
} else if (xValue > 600) {
direction = "Right";
} else if (xValue < 400) {
direction = "Left";
} else if (yValue > 600) {
direction = "Down";
} else if (yValue < 400) {
direction = "Up";
}
For instance, a movement to the top-left corner is detected when both the x- and y-values are below 400. This logic can be applied to the other three diagonal directions. With some effort, you can even implement additional gradations.
What’s Next?
Now that you know how to connect and use your Arduino joystick, you might want to build a project. Check out our tutorial on creating the classic Snake game using an Arduino and ESP32!