Skip to Content
This is the Beta version of our new Learning Paths approach. Please email feedback.

Joystick

A joystick is an input device that is used for providing directional inputs to a microcontroller board generally used to control moving objects, physical or on-screen, by translating the directional inputs to movement.

A joystick can be pushed in any direction along a circle, the most typical directions being up (north), down (south), left (west), right (east), and diagonal (northwest, northeast, southwest, and southeast). Joysticks may also provide an additional push or click input when the stick is pressed down.

The joystick input is translated into movement depending on the context and the object being moved.

For example, if a joystick is controlling a car, the up and down movements will translate to forward and backward movements for the car, the left and right movements will turn the car left or right. And any diagonal movements may control the degree of turn.

If the joystick is controlling a flying airplane, the up and down movements will translate to nose down and nose up movements for the airplane (known as the pitch), the left and right movements, will cause the airplane to tip its wings left or right (known as the roll) and at the same time turn left or right (known as the yaw).

The joystick module has two analog ouput pins that output analog signals, one for the up-down (y-axis) movement, and one for the left-right (x-axis) movement. On the y-axis pin the signal voltage will go from 0 when the joystick is moved to the extreme bottom and the maximum operating voltage of the module (5V or 3.3V) when the joystick is moved to the extreme top (or it could be the other way round depending on how the joystick is calibrated). The voltage will vary similarly for the x-axiz movement from extreme left to extreme right. When the joystick is in its center (known as resting) position, the output voltage is about half of the operating voltage.

Joystick Values

The analog values are read by the microcontroller’s Analog-to-Digital Converter (ADC) and converted to a value between 0 and 1023. The microcontroller program can translate these values into motion as required.

If the joystick has a push or click signal pin, it will send a digital (HIGH or LOW) signal to the microcontroller.

This project reads values from a Joystick and displays the readings on the serial monitor.

Components

ComponentPurpose
Arduino NanoThe microcontroller
Dual axis joystickJoystick for input

Circuit Diagram

Nano Joystick Fritzing

Connections

Dual-axis Joystick Pin Connections

Nano PinJoystick Pin
A0Vertical Pin
A1Horizontal Pin
D12Select Pin
5VVCC
GndGnd

Code

/* Project: Process Joystick Input Project Description: This sketch reads the joystick input, translates it to a direction, and prints the input value and direction on the serial monitor. Author: STEMVentor Educonsulting This code is copyrighted. Please do not reuse or share for any purpose other than for learning with subscribed STEMVentor programs. This code is for educational purposes only and is not for production use. */ // LIBRARIES // PIN DEFINITIONS // For Arduino Nano #define VERTICAL_PIN A1 #define HORIZONTAL_PIN A0 #define SELECT_PIN 12 // For ESP32 // #define VERTICAL_PIN 12 // #define HORIZONTAL_PIN 13 // #define SELECT_PIN 14 // GLOBAL VARIABLES // The range of analog values for a Nano is 0-1024 while for an ESP32 it is 0-4096. // Set thresholds to count as a complete movement in a direction. // This code assumes the joystick module sends a value of 0 for extreme down and left // and a value of 1023 for extreme up and right. // For Arduino Nano const int north_threshold = 1000; // Greater than const int south_threshold = 100; // Less than const int west_threshold = 100; // Less than const int east_threshold = 1000; // Greater than /* INITIALIZE OBJECTS */ /* LOCAL FUNCTIONS */ // Read joystick values void readJoystickValues() { int vertical_value = analogRead(VERTICAL_PIN); // Read the vertical pin value int horizontal_value = analogRead(HORIZONTAL_PIN); // Read the horizontal pin value bool select_value = digitalRead(SELECT_PIN) ; // Read the sel pin value // Serial print the values Serial.println(vertical_value); Serial.println(horizontal_value); Serial.println(select_value); // Position identification logic customized as required by your application. Serial.println("Select pressed!"); if(vertical_value > north_threshold){ if(horizontal_value < west_threshold){ Serial.println("Pushed North-West!"); }else if(horizontal_value > east_threshold){ Serial.println("Pushed North-East!"); }else{ Serial.println("Pushed North!"); } }else if(vertical_value < south_threshold){ if(horizontal_value < west_threshold){ Serial.println("Pushed South-West!"); }else if(horizontal_value > east_threshold){ Serial.println("Pushed South-East!"); }else{ Serial.println("Pushed South!"); } }else{ // Vertical value is neither north or south, so centered. if (horizontal_value < west_threshold){ Serial.println("Pushed West!"); }else if (horizontal_value > east_threshold){ Serial.println("Pushed East!"); }else{ Serial.println("Joystick centered!"); } } } void joystickSetup() { // Joystick pins pinMode(VERTICAL_PIN, INPUT); pinMode(HORIZONTAL_PIN, INPUT); // for ESP32 // pinMode(SELECT_PIN, INPUT_PULLUP); // for Arduino Nano pinMode(SELECT_PIN, INPUT); } /* SETUP CODE: runs once when the board starts up or resets */ void setup() { // Start the serial communication with baud rate suitable for your components. Serial.begin(9600); joystickSetup(); Serial.println("The joystick is ready!"); } /* MAIN LOOP: runs repeatedly at a very high frequency (1000s of times a second) */ void loop() { delay(3*1000); readJoystickValues(); }