ArduinoTutorials

How to use an Analog Joystick with Arduino – Everything you need to know

Connecting a joystick to Arduino will let you remotely control a machine or robot with Arduino. In this lesson, I’ll show you how to use the analog joystick module with Arduino Uno.

Basics. How Does It Work?

The analog joystick has a handle that is attached to the joint with two regulators that determine the joysticks location on the X and Y-axes and the button on the Z-axis. The handle’s angle rotates the regulators and changes the output voltage letting it monitor the handle’s gradient from the central spot. When the joystick is released, it smoothly returns to its central (0) location. The value on every analog channel can vary from 0 to 1023. When connected to analog ports, VRx to A0 and VRy to A1 respectively, they should transmit the values as shown in the image below.

The KY-023 joystick model has its own deficiencies. That’s because the joystick handle doesn’t always return exactly to the central location, so you have to take this into account when programming the handle’s central location as a small range of values, not a specific one. Meaning when the joystick is in the center, the X and Y coordinate values might be in a range from 490 to 530 and not exactly 512.

The module has 5 pins: VCC, GND, HORIZ, VERT, SEL. Be aware that the notation might be different in your module. It depends on the manufacturer.

Analog Joystick
Analog Joystick
Analog Joystick
Analog Joystick
Analog Joystick
Analog Joystick

I’ve described the corresponding pin names for various manufacturers below.

VCC (5v) – Connect this to your positive supply (usually 5V or 3.3V depending on your logic levels).
VERT (vrY) – This is the vertical analog output voltage (will be about half of VCC when the joystick is centered).
HORIZ (vrX) – This is the horizontal analog output voltage (will be about half of VCC when the joystick is centered).
SW (KEY or SEL) – This is the digital output from the pushbutton, normally open, will connect to GND when the button is pushed.
GND – Connect this to your ground line (GND).

If you don’t need the button then you can use only 4 pins.

Analog Joystick Technical Specifications

Operating Voltage3.3V to 5V
Internal Potentiometer value10k
Dimensions1.57 in x 1.02 in x 1.26 in (4.0 cm x 2.6 cm x 3.2 cm)
Operating temperature0 to 70 °C
Weight12 g
CostCheck price

For more information, you can check out the datasheet here:

KY-023 Datasheet

Things used in this tutorial

To follow this tutorial you need the following components:

Hardware components:

Arduino Unox1Check price
Joystick modulex1Check price
Jumper wires x5Check price
USB Type-B Cablex1Check price
Note: Elekonika.com is a participant in the Amazon Services LLC Associates Program

Software

Arduino IDE

Wiring – Connecting the Joystick to Arduino UNO

The wiring diagram below shows you how to connect the analog joystick to the Arduino.

joystick arduino

 

Joystick Connections

We need 5 connections to the joystick.

JoystickArduino
VCC5 V
vrYA3
vrXA2
GNDGND
SELPin 2

In the end, it should look something like the pictures:

Analog joystick connected to Arduino
Analog joystick connected to Arduino
Analog joystick connected to Arduino
Analog joystick connected to Arduino
Analog joystick connected to Arduino
Analog joystick connected to Arduino

Example code for the analog joystick with Arduino

Now that you have wired up the joystick it is time to connect the Arduino to the computer and upload some code. You can upload the following example code to your Arduino using the Arduino IDE. Next, I will explain how the code works.

Below, there’s a code of getting data from the joystick. The data from the regulators on the X and Y axes can be from 0 to 1023. The standing location for the joystick is 511 for each regulator. If you press the button on Arduino’s 3rd port, you’ll see a 0. You need to raise the button’s value to +5 V. We will input the data into the following port.

const int switchPin = 8;  // Joystick button
const int pinX = A1; // Joystick X axis
const int pinY = A2; // Joystick Y axis
const int ledPin = 13;
 
void setup() {
  pinMode(ledPin, OUTPUT)
  pinMode(pinX, INPUT);
  pinMode(pinY, INPUT);
  pinMode(switchPin, INPUT);
  digitalWrite(switchPin, HIGH); // Connect the built-in wind-up resistor
  Serial.begin(9600);
}
 
void loop() {
  int ledState = digitalRead(switchPin); // Read the button's state
  digitalWrite(ledPin, ledState); // Turn on/off light when pressing the button
  int X = analogRead(pinX); // Read the X axis analog value
  int Y = analogRead(pinY); // Read the Y axis analog value
  Serial.print(X); // Input the values into Serial Monitor
  Serial.print("\t"); // Tabulation
  Serial.println(Y);
}

Upload the sketch to the Arduino board, open the monitor of the serial port and you can see the data input when moving the joystick.

X and Y values from the analog joystick displayed in the serial port monitor
X and Y values from the analog joystick input into the monitor of the serial port.

Be aware that the X and Y axes values in the joystick’s neutral position could be different and not exactly 512.

How the code works

Declare the pins and put them in work mode. Make sure that in the setup() procedure, we’re on the switchPin high-level input. Use it to turn off the built-in wind up resistor on this port. If it isn’t off, then when the joystick isn’t pressed, the Arduino’s 8th port will hang in the air and catch interference. This will lead to undesired chaotic false operations.

In the loop() procedure, we will gradually examine the button’s state and mirror it using the light on output 13. Because the switchPin input is pulled towards power, the light will always light up and go out when the button is pressed, not the other way around.

Next, we will read the readouts of the joystick’s two regulators the X and Y axes’ outputs. Arduino has a 10-bit coder, so the values from the joystick will be in the 0 to 1023 range. The central location of the joystick, as you can see in the image, has a value in the 500 range, roughly in the middle.

Controlling the brightness and light’s color using the analog joystick and Arduino

Usually, the joystick is used to control electric motors. But why not use it, for example, to control the diode’s brightness? Let’s connect the RGB diode scheme (or three typical diodes) to the digital ports 9, 10 and 11 on the Arduino and don’t forget, of course, about the resistors.

We need the following things:

Arduino Unox1Check price
Joystick modulex1Check price
Jumper wires x5Check price
USB Type-B Cablex1Check price
RGB Tri-Color 4Pin LED Diodesx1Check price
Note: Elekonika.com is a participant in the Amazon Services LLC Associates Program

Connection

Connect RGB LED and joystick to Arduino
Connect an RGB LED and joystick to Arduino

We will change the brightness of the corresponding colors when moving the joystick as shown in the drawing.

Because the joystick might not be accurately oriented by the manufacturer and not have its midpoint on the indicated 512, but in the range from 490 to 525, the light might slightly light up even when the joystick is in the neutral position. If you want it to turn on completely, then make the following adjustments.

The brightness location diagram of the red, blue and green diode channels depends on the joystick's location
The brightness location diagram of the red, blue and green diode channels depends on the joystick’s location

While orienting on the given diagram, write code for controlling the Arduino with the brightness of the RGB diodes using the joystick.

const int pinRed    = 9;
const int pinGreen  = 10;
const int pinBlue   = 11;
const int swPin = 8; 
const int pinX      = A1; // X 
const int pinY      = A2; // Y 
const int ledPin    = 13;
boolean ledOn = false;  // Current button state
boolean prevSw = false; // Previous button state

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(pinRed, OUTPUT);
  pinMode(pinGreen, OUTPUT);
  pinMode(pinBlue, OUTPUT);
  pinMode(pinX, INPUT);
  pinMode(pinY, INPUT);
  pinMode(swPin, INPUT);  
  digitalWrite(swPin, HIGH); // Connect the built-in wind-up resistor
}

void loop() {
  if (isLedOn()) freeMode(); // If you press the button and the 13th pin diode lights up, turn on "flashlight" mode
  else discoMode(); // Otherwise turn on "color music"
}

boolean isLedOn() { // Define the button presses
  if (digitalRead(swPin) == HIGH && prevSw == LOW) {
    ledOn = !ledOn;
    prevSw = HIGH;
  }
  else  prevSw = digitalRead(swPin); 
  digitalWrite(ledPin, ledOn); // Turn on the 13th pin diode
  return ledOn;
}

void freeMode() { // Turn on "flashlight"
  int X = analogRead(pinX); // Read the joystick's position
  int Y = analogRead(pinY);
  int RED = map(Y, 512, 1023, 0, 255);
  int GREEN = map(X, 512, 1023, 0, 255);
  int BLUE = map(X, 511, 0, 0, 255);
  analogWrite(pinRed, RED);     // Turn on the RGB channels
  analogWrite(pinGreen, GREEN);
  analogWrite(pinBlue, BLUE);
}

void discoMode() { // "Color music" mode
    for (int i=0; i <= 255; i++) {
      if (isLedOn()) { break; } // Exit the cycle when pressing the button
      analogWrite(pinRed, i); // RED channel works
      analogWrite(pinGreen, 0);
      analogWrite(pinBlue, 0);  
      delay(5);
    }
    for (int i=0; i <= 255; i++) {
      if (isLedOn()) { break; } // Exit the cycle when pressing the button
      analogWrite(pinRed, 0);
      analogWrite(pinGreen, 0);
      analogWrite(pinBlue, i);  // BLUE channel works
      delay(5);
    }
    for (int i=0; i <= 255; i++) {
      if (isLedOn()) { break; } // Exit the cycle when pressing the button
      analogWrite(pinRed, 0);
      analogWrite(pinGreen, i); // GREEN channel works
      analogWrite(pinBlue, 0);  
      delay(5);
    }
}

How the code works

First, update the relationship of the pins and the two variables ledOn and prevSw to work with the button. In the setup() procedure, set the pin functions and connect the button with the wind-up resistor to the pin with the digitalWrite(swPin, HIGH) command.

In the loop() cycle, define pressing the joystick button. When pressing the button, reset the working status of the “flashlight” and “color music” modes.

In freeMode() control the diode brightness by moving the joystick in various directions. The larger the angle, the brighter the light. The transformation of the values takes the functions of map(value, fromLower, fromUpper, toLower, toUpper).

The map() function is very useful and convenient for changes. It takes changed values (fromLower, fromUpper) along the joystick’s axes in the desired range of brightness (toLower, toUpper). You can do the same thing with standard arithmetic but using the map() function is significantly shorter.
While in discoMode(), the three colors brighten and dim alternately. We check every iteration to see if the button was pressed so you can leave the cycle by pressing the button.

As a result, you have a flashlight with three colors RGB diodes whose brightness can be determined using the joystick. And pressing the button turns on “color music” mode.

Controlling the brightness and RGB diode colors with the joystick connected to Arduino
Controlling the brightness and RGB diode colors with the joystick connected to Arduino

In this example, we learned to connect the dual-axis joystick with a button to Arduino and read its values. You can think of and achieve more interesting uses of the joystick than my example.

Joystick Shield

As mentioned above, there are many joystick modules. Sparkfun has an interesting option. They make a Joystick Shield that will be discussed further. The appearance of the joystick shield is shown below.

Joystick shield assembly

I’ll note that the shield is sold disassembled, so, you’ll have to solder it. You can find full assembly instructions here. The document has fairly informative pictures so it shouldn’t be difficult.

The joystick shield has four buttons on the right, one button on the joystick and the analog joystick itself. You can use the shield to control melodies or pixels on a monitor. You can use the buttons for navigation and control in games.

You can watch the video below for additional motivation:

Conclusion

In this article, I have shown you how the analog joystick works with Arduino and how you can use it in your projects. I hope you found it useful and informative. If you did, please share it with a friend that also likes electronics!
If you have any questions, suggestions or if you think that things are missing in this tutorial, please leave a comment down below (note that comments are held for moderation in order to prevent spam).

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Frequently asked questions

The data on the analog outputs on the Arduino don't change when the joystick is moved.

Check the connection of the joystick to the Arduino board.

 

Damon Coleman

Entrepreneur, robotics fan. I have a Diploma in Technical Education, interested in robotics. My favorite platforms are Arduino and Raspberry Pi. Welcome to the world of robotics!

2 Comments

  1. Very useful article! Joystick comes with a select switch. It can be very handy for retro gaming, robot control or RC cars.

  2. Lots of robotic projects need a joystick. This module offers an affordable solution to that. The joystick module is similar to analog joysticks found in gamepads. It is made by mounting two potentiometers at a 90 degrees angle. The potentiometers are connected to a short stick centered by springs.

Leave a Reply

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

Related Articles

Back to top button