Using an analog joystick module

Submitted by james on
Analog joystick module

The analog joystick module is basically two potentiometers arranged at right angles to each other. As you manipulate the joystick, the potentiometers change in different ratios, which your code can use to determine the joystick's angle and distance from center. Some joystick modules also act like a button when pressed.

Connections

The module pictured above has five pins, two of which (GND and +5V) are mostly self-explanatory. GND connects to the same ground as the rest of the circuit. The +5V pin connects to 5-volt power. The joystick also works with a 3.3-volt source if that's what you're already using for the rest of the circuit. In that case, your analog readings will range from 0 to 3.3V instead of 0 to 5V.

Warning: Some microcontrollers only support up to 3.3 volts on their input pins! If your joystick is connected to 5 volts, ensure that your microcontroller inputs are also 5V tolerant, or else use a logic level shifter to convert the values to 3.3V.

The three remaining pins are VRx, VRy, and SW. The VRx and VRy pins are the two potentiometer outputs and will connect to the analog input pins on your microcontroller. Finally, SW is the switch that is closed when the joystick is pressed in. This pin, if used, connects to one of the digital inputs on the microcontroller.

Reading values

The Arduino code for reading the values from VRx and VRy is quite simple. The analogRead function reads the voltages on an analog input pin and converts the value to a number from 0 to 1023. The center position is at approximately (511, 511).

// A1 and A2 are the analog pins being used
const int xInputPin = A1;
const int yInputPin = A2;

void setup() {
	// Configure analog pins for reading
	pinMode(xInputPin, INPUT);
	pinMode(yInputPin, INPUT);

	// Initialize anything else...
}

void loop() {
	// Read X and Y values
	int xValue = analogRead(xInputPin);
	int yValue = analogRead(yInputPin);

	// Use the values...
}

Calibration

Often the "center" position on the joystick does not quite lead to 0 voltage on the ADC, leading to some number other than 0 being returned by analogRead.

There are two ways to fix this:

  1. Physically adjust the potentiometers until the central position reads a true zero.
  2. Provide a calibration routine in your code.

For the best results, you will do a combination of both: Build a device that is as close to perfect as possible, and then write some code to compensate for any remaining discrepancies. Calibration adds a small amount of complexity to the code, as well as to the circuit because you need some way to enter/exit calibration mode. Entering calibration mode can be as simple as holding down a push-button.

Typically, you'll just collect some measurements while the joystick is centered, and then when it is at two opposite corners. Once this is done, you can remap the analogRead values into new numbers that more accurately describe the position of the joystick.