Built-in project · Arduino Uno R3

Joystick lights the way (LEDs on 8 to 11), on an Arduino Uno

A joystick on A0, A1 and pin 2 lights one of four LEDs: left on 11, right on 8, up on 10 and down on 9. Press the stick and all four flash. The whole build, an Arduino Uno and 9 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.

Teaching? Assign it to your class in one click.

Beginner About 20 minutes to build and run. Runs in your browser. Free, and no account needed.

The parts retail for about $34. On Mokxi they're free.

The circuit runs here once the page has loaded.

What you'll learn

  • Reading a joystick with two analog inputs
  • Thresholds around a center value
  • Internal pull-up for a button
  • Using one function to set several pins
  • Difficulty: Beginner
  • Time: About 20 minutes
  • Board: Arduino Uno R3
  • Parts: 11

How it works

A thumb stick has two potentiometers, one per axis, and a button. VRX goes to A0 and VRY to A1. At rest each reads about 512. Pushed one way it moves toward 0, pushed the other way toward 1023. The button, SW on pin 2, joins to ground when pressed.

Four LEDs on pins 8 to 11, each through a 220 ohm resistor, show the direction: left is pin 11, right is pin 8, up is pin 10 and down is pin 9.

Each pass the sketch turns all four off, then checks the button first. A press flashes all four for 150 ms. Otherwise the first axis past 300 or 700 lights one LED. It also prints x and y.

Wiring table

Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.

Part and pinConnects to
LED, red pin CArduino Uno R3 pin GND
LED, yellow pin CArduino Uno R3 pin GND
LED, green pin CArduino Uno R3 pin GND
LED, blue pin CArduino Uno R3 pin GND
Thumb stick pin GNDArduino Uno R3 pin GND
Resistor, 220 Ω (1) pin 1Arduino Uno R3 pin 11
Resistor, 220 Ω (2) pin 1Arduino Uno R3 pin 10
Resistor, 220 Ω (3) pin 1Arduino Uno R3 pin 9
Resistor, 220 Ω (4) pin 1Arduino Uno R3 pin 8
Thumb stick pin SWArduino Uno R3 pin 2
Thumb stick pin VCCArduino Uno R3 pin 5V
Thumb stick pin VRXArduino Uno R3 pin A0
Thumb stick pin VRYArduino Uno R3 pin A1
LED, red pin AResistor, 220 Ω (1) pin 2
LED, yellow pin AResistor, 220 Ω (2) pin 2
LED, green pin AResistor, 220 Ω (3) pin 2
LED, blue pin AResistor, 220 Ω (4) pin 2

The code

The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.

sketch.ino · Arduino Uno R3
// A joystick navigator: push the stick and the LED on that side lights.
//
//   joystick VRX -> A0   VRY -> A1   SW -> pin 2   +5V -> 5V   GND -> GND
//   pin 11 -> 220 ohm -> LED (left)    pin 8 -> 220 ohm -> LED (right)
//   pin 10 -> 220 ohm -> LED (up)      pin 9 -> 220 ohm -> LED (down)
//
// Each axis is a potentiometer: about 512 in the middle, near 0 at one end
// and near 1023 at the other. The switch under the stick joins SW to ground
// when you press it, so the pin uses the internal pull-up and reads LOW.

const int LEFT = 11;
const int RIGHT = 8;
const int UP = 10;
const int DOWN = 9;
const int X_PIN = A0;
const int Y_PIN = A1;
const int SW_PIN = 2;

void allLeds(int level) {
  digitalWrite(LEFT, level);
  digitalWrite(RIGHT, level);
  digitalWrite(UP, level);
  digitalWrite(DOWN, level);
}

void setup() {
  pinMode(LEFT, OUTPUT);
  pinMode(RIGHT, OUTPUT);
  pinMode(UP, OUTPUT);
  pinMode(DOWN, OUTPUT);
  pinMode(SW_PIN, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Mokxi Uno: push the joystick to light the way");
}

void loop() {
  int x = analogRead(X_PIN);
  int y = analogRead(Y_PIN);
  allLeds(LOW);
  if (digitalRead(SW_PIN) == LOW) {
    allLeds(HIGH);
    delay(150);
    allLeds(LOW);
  } else if (x < 300) {
    digitalWrite(LEFT, HIGH);
  } else if (x > 700) {
    digitalWrite(RIGHT, HIGH);
  } else if (y < 300) {
    digitalWrite(UP, HIGH);
  } else if (y > 700) {
    digitalWrite(DOWN, HIGH);
  }
  Serial.print("x ");
  Serial.print(x);
  Serial.print("  y ");
  Serial.println(y);
  delay(100);
}

Code walkthrough

The key functions of the sketch, and what each one does.

allLeds sketch.ino

Writes the same level to all four LED pins. Calling it with LOW clears the display and calling it with HIGH lights everything, which saves repeating four lines.

void allLeds(int level) {
  digitalWrite(LEFT, level);
  digitalWrite(RIGHT, level);
  digitalWrite(UP, level);
  digitalWrite(DOWN, level);
}

setup sketch.ino

Sets the four LED pins as outputs. The switch pin uses INPUT_PULLUP, so it reads HIGH until the stick is pressed. Then it starts serial at 9600 baud.

void setup() {
  pinMode(LEFT, OUTPUT);
  pinMode(RIGHT, OUTPUT);
  pinMode(UP, OUTPUT);
  pinMode(DOWN, OUTPUT);
  pinMode(SW_PIN, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Mokxi Uno: push the joystick to light the way");
}

loop sketch.ino

Reads x and y, clears the LEDs, then goes through the choices in order: button, x under 300 for left, x over 700 for right, y under 300 for up, y over 700 for down. Only one LED lights at a time. Then it prints x and y and waits 100 ms.

void loop() {
  int x = analogRead(X_PIN);
  int y = analogRead(Y_PIN);
  allLeds(LOW);
  if (digitalRead(SW_PIN) == LOW) {
    allLeds(HIGH);
    delay(150);
    allLeds(LOW);
  } else if (x < 300) {
    digitalWrite(LEFT, HIGH);
  } else if (x > 700) {
    digitalWrite(RIGHT, HIGH);
  } else if (y < 300) {
    digitalWrite(UP, HIGH);
  } else if (y > 700) {
    digitalWrite(DOWN, HIGH);
  }
  Serial.print("x ");
  Serial.print(x);
  Serial.print("  y ");
  Serial.println(y);
  delay(100);
}

Troubleshooting

The usual mistakes with this circuit, and the fix for each.

  • Left and right are swapped This project
    Left is pin 11 and right is pin 8. Check which LED sits on which pin, or swap the two constants.
  • An LED stays lit when the stick is centered This project
    Center should read about 512. If it does not, check the joystick's VCC and GND.
  • The LED is dim, burns out, or the pin reads wrong because the resistor value is off. Resistor
    Read the color bands again. A 220 ohm to 330 ohm resistor suits a typical LED on 5 V. 10k is a common pull-up or pull-down value. Check with a multimeter if unsure.
  • A pull-up or pull-down resistor is missing, so the input floats and reads random values. Resistor
    Tie the input to 5 V or ground through about 10k. Or use INPUT_PULLUP and wire the switch to ground.
  • The LED does not light, or it lights once and then dies. LED
    LEDs have polarity. The longer leg (anode) goes toward the positive side. Always add a series resistor, about 220 ohms to 1 k ohm on a 5 V pin.
  • A blue or white LED stays dark on 3.3 V. LED
    Blue and white LEDs drop about 3 V, so 3.3 V leaves almost nothing for the resistor. Use a 5 V supply, or a smaller resistor and a red or green LED.
  • The axis reads about half scale at rest instead of exactly zero, and the values drift a little, so the cursor or motor creeps. Thumb stick
    Center is about half of the ADC range (about 512 on a 10 bit Arduino). Read it at startup and subtract that, then add a dead zone of a few counts.
  • The push button reads random values or always looks pressed. The switch pin is a plain contact to ground and has no pull-up on the stick. Thumb stick
    Set the switch pin to INPUT_PULLUP and treat LOW as pressed. Debounce it in code. Power the stick from the same voltage as the ADC reference.

Change it and keep it

Open it in the editor, change the circuit or the code, and keep your version in a free account.