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.
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.
Parts list
11 parts, plus the jumper wires. They retail for about $34; on Mokxi they're free.
- 1 × Arduino Uno R3In Starter Kit, Claw Machine Kit, Vending Machine Kit.
- 1 × Full-size breadboard
- 4 × Resistor, 220 ΩIn Starter Kit, Claw Machine Kit, Halloween Prop Kit.
- 1 × LED, redIn Starter Kit, Halloween Prop Kit, Logic Lab Kit.
- 1 × LED, yellowIn Starter Kit, Halloween Prop Kit, Logic Lab Kit.
- 1 × LED, greenIn Starter Kit, Halloween Prop Kit, Logic Lab Kit.
- 1 × LED, blueIn Starter Kit, Halloween Prop Kit, Logic Lab Kit.
- 1 × Thumb stickIn Claw Machine Kit, Spaceship Panel Kit.
Kits that can build it
These 8 starter kits have every part in the circuit. Each kit's page lists what else it can build.
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 pin | Connects to |
|---|---|
| LED, red pin C | Arduino Uno R3 pin GND |
| LED, yellow pin C | Arduino Uno R3 pin GND |
| LED, green pin C | Arduino Uno R3 pin GND |
| LED, blue pin C | Arduino Uno R3 pin GND |
| Thumb stick pin GND | Arduino Uno R3 pin GND |
| Resistor, 220 Ω (1) pin 1 | Arduino Uno R3 pin 11 |
| Resistor, 220 Ω (2) pin 1 | Arduino Uno R3 pin 10 |
| Resistor, 220 Ω (3) pin 1 | Arduino Uno R3 pin 9 |
| Resistor, 220 Ω (4) pin 1 | Arduino Uno R3 pin 8 |
| Thumb stick pin SW | Arduino Uno R3 pin 2 |
| Thumb stick pin VCC | Arduino Uno R3 pin 5V |
| Thumb stick pin VRX | Arduino Uno R3 pin A0 |
| Thumb stick pin VRY | Arduino Uno R3 pin A1 |
| LED, red pin A | Resistor, 220 Ω (1) pin 2 |
| LED, yellow pin A | Resistor, 220 Ω (2) pin 2 |
| LED, green pin A | Resistor, 220 Ω (3) pin 2 |
| LED, blue pin A | Resistor, 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.
// 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.