Level 2Unit C · Session 17
17

Unit C · Telling a machine what you want

A knob, and then a joystick

What we are making: a joystick you can read — two numbers that change as you push it, printed in the Serial Monitor.

The idea

A button gives you one of two answers: pressed, or not. A knob gives you a whole range — any number from 0 to 1023, depending on how far round it is turned. That is the difference between digital and analogue, and it is worth ten seconds of your attention because it never stops mattering.

A joystick is simply two knobs mounted at right angles, with a button underneath. Push it left and one number changes; push it forward and the other does. There is nothing else in there.

New words
AnalogueA value with a range, not just on or off.
analogRead()Reads a pin and gives a number from 0 to 1023.
PotentiometerThe proper name for a knob. Often shortened to ‘pot’.
Centre valueWhat the joystick reads when you are not touching it. About 512.
Arduino UnoUSB to the laptop5VGNDA0A14Joysticktwo knobs and a button+5VGNDVRxVRySWleft–rightup–downpress
A joystick is just two knobs at right angles, plus a button underneath.
Reading a joystick
1void setup() {
2 Serial.begin(9600);
3}
4 
5void loop() {
6 int x = analogRead(A0); // left and right
7 int y = analogRead(A1); // up and down
8 
9 Serial.print("x = ");
10 Serial.print(x);
11 Serial.print(" y = ");
12 Serial.println(y);
13 
14 delay(200);
15}

Do it

  1. Wire it up, then open the Serial Monitor at 9600 baud.
  2. Do not touch the stick. Write down both numbers — that is your centre.
  3. Push it fully in each of the four directions and write down what you get.
  4. Let go. Does it come back to exactly the same centre, or near it?

Change it

  1. Add a line that prints "LEFT" when x drops below 300.
  2. Do the same for right, up and down.
  3. Read the button on pin 4 with digitalRead(4) and print when it is pressed.
💡 Tip
The centre is never exactly 512, and that is fine. Yours might rest at 498 or 517. Every joystick is slightly different. This is why you never test for x == 512 — test for a range, like ‘below 300’, and your program works on everybody's hardware, not just yours.
What you seeWhyWhat to do
Both numbers stuck at 0No power to the module.Check +5V and GND. Almost always this.
Both numbers stuck at 1023GND is not connected.Trace the black wire from the module to a GND pin.
The numbers drift by a few countsAnalogue readings always wobble.Normal. It is why you test ranges, not exact values.
The button reads pressed constantlyThe pin is floating.Add pinMode(4, INPUT_PULLUP); it then reads LOW when pressed.

What you learned

  • Digital is two answers. Analogue is a range of them.
  • analogRead() always gives 0 to 1023, whatever the sensor.
  • Test for a range, never an exact value. Hardware is never exact.
Challenge optional — only if you finish early
  • Use the joystick to drive the servo's angle directly.
  • Then make the button send it back to the middle.
16. Show it