STANNUM
Open the simulator

Tutorials / Input

Analog joystick

Two potentiometers and a button in one stick: two ADC channels and one digital input.

Parts in the example:
  • Joystick
  • RGB LED
The Joystick block as it appears on the canvas.

What it is

The KY-023 joystick module is two potentiometers at right angles, moved by the stick, plus a push button you reach by pressing the stick down. At rest both wipers sit in the middle, so a resting joystick reads about 2048 on each axis; the button is a normal contact to ground.

In the simulator

The block is the module seen from above. Drag the cap: it moves within a circle, like the real lever, and both readings follow; release it and it springs back to the center. Press SW for the button. The Y axis setting flips the direction of Y — modules on the market disagree about which way is up, and here you match yours.

Pins

PinWhat it is
VXX axis — to a GPIO with an ADC
VYY axis — to a GPIO with an ADC
SWthe stick's push button — to a GPIO (LOW when pressed)
3V3power — to a 3V3 symbol
GNDground — to a GND symbol

Wiring

The circuit below is the example RGB LED colors with a joystick from the lab — open it with Project → Open example… and it comes ready to run.

The wired circuit, as the lab draws it.
Joystick pinGoes to
VXD34 on the board (GPIO 34)
VYD35 on the board (GPIO 35)
SWD33 on the board (GPIO 33)
3V3a 3V3 symbol
GNDa GND symbol

Settings

Double-click the block's title bar to open its card, then the Settings tab. Changes apply to the running simulation right away.

The Settings tab of the Joystick.
SettingAcceptsDefaultNotes
Y axisNormal (up = lower) · Inverted (up = higher)Normal (up = lower)Joystick modules disagree on the Y axis direction; here you match yours.

Code

sketch.cpp
#include <Arduino.h>

const int VX = 34;   // joystick X axis (ADC)
const int VY = 35;   // Y axis (ADC)
const int SW = 33;   // joystick button
const int R = 25, G = 26, B = 27;

void setup() {
  Serial.begin(115200);
  pinMode(R, OUTPUT); pinMode(G, OUTPUT); pinMode(B, OUTPUT);
  pinMode(SW, INPUT_PULLUP);
}

void loop() {
  int x = analogRead(VX);          // 0..4095, at rest ~2048
  int y = analogRead(VY);
  bool apertado = digitalRead(SW) == LOW;

  digitalWrite(R, x > 2800 ? HIGH : LOW);
  digitalWrite(B, y > 2800 ? HIGH : LOW);
  digitalWrite(G, apertado ? HIGH : LOW);

  Serial.printf("x=%d y=%d button=%d\n", x, y, apertado);
  delay(100);
}

Two analogRead calls and one digitalRead with the pull-up on. The example compares each axis with 2800 to decide whether a channel of the RGB LED lights; the button lights green.

Run it

Press Build and run. The first build of a project takes a while; after that, only what changed is rebuilt.

The simulation running: the canvas reacts and the serial monitor shows what the code prints.

Drag the cap to the right: red. Drag it up: blue. Press SW: green. The serial monitor prints x, y and the button on every pass.

How the simulation models it

Try this

  1. Print the direction as text (“north”, “south-east”…) instead of numbers, using a dead zone around the center.
  2. Drive the servo of another example with the X axis.

See also