Objectives
- Introduce joysticks
- Reading the joystick
- Moving the servo by using the joystick
- Filtering the readings
BILL OF MATERIALS
![]() |
Arduino Uno or equivallent. We can use any other Arduino board in this chapter. |
![]() |
A solderless Breadboard plus some jumper wires. |
![]() |
A Joystick. |
![]() |
A Servo with its horns, these small pieces of plastic put on the shaft. |
WHAT IS A JOYSTICK?
A joystick is usually composed of two potentiometers, placed at 90º one from each other, which transform the movement from the X and Y axes of the joystick in an electrical signal proportional to its position. They also use to include a button.
Normally a joystick have 5 pins: X axis, Y axis, button, 5V and GND.
Actually we have used all these components before and its only special feature is to provide a very comfortable way to position something, although it is not too precise.
Let’s mount a prototype with a servo, as in the previous chapter. We will use one of the axes of the joystick to position it and the button to turn on an LED. (We’ll ignore the other axis, although we could use it to position a second servo).
The pin corresponding to the button is usually labelled as SW, Switch.
Here we have the circuit schematic diagram:

And this is the wiring schematic diagram:

THE CONTROL PROGRAM
Let’s start off by writing the program
Sketch 17.1#include <Servo.h> // Includes Servo library Servo servo1; // Creates a Servo type object called servo1 int angle = 0; int X_Axis = A1; int Y_Axis = A2; int button = 4 , LED = 12; void setup() { servo1.attach(6) ; // Connects servo1 to pin 6 pinMode(button, INPUT_PULLUP); } void loop() { angle = map(analogRead(A1), 0, 1024, 0, 180); servo1.write(angle); if (!digitalRead(button)) digitalWrite(LED, HIGH); else digitalWrite(LED, LOW); delay(250); }
- The part corresponding to the servo is exactly the same as that in the chapter 16. Moreover, we have included some definitions at the beginning indicating that we have connected the X axis to the analog pin A1 and the Y axis to the analog pin A2.
- The button is connected to digital pin 4 and the LED to the pin 12 so that if we want to change the pin number, for whatever reason, you can simply update this list at the beginning of the program.
Pay attention to the fact that we have defined the button input of the joystick as INPUT_PULLUP and not as INPUT, because it does not need to include a resistor as a pull-up resistor is already internally attached to the Arduino.
This way we will read LOW when the button is pressed and HIGH in the meantime, that is why we reverse the condition in the if statement. We will switch on the LED only when the button is pressed.
The servo follows the position of the joystick and when we release it, it comes back to the center.
But the servo moves in a somehow epileptic way (even more in my case, as I am using a cheap one).The servo receives many interferences and its movement is very troubled, because although servos have a certain accuracy (which is an assumption between optimistic and highly optimistic), potentiometers and analog to digital converters (ADCs) always have a noise margin.
We can think of some way to improve that movement for sure. Think about it. What can we do to filter that noise?
Seriously, think on it before proceeding.
Well, in the real world, things are never black or white, but rather shades of gray (or very frequently chocolate), so it is not a good idea to send the readings directly control the servo, or whatever you’re moving .
We have to filter the signal a little bit. Without going too much on this issue (on which there have been written encyclopedias), we will use a very basic though very effective technique, on many occasions, that you should know.
We will read the potentiometer to decide whether we increase or decrease the angle value, not to calculate the angle directly.
As the potentiometer sends values between 0 and 1000, when it is centered or loose it will send a value of about 500, more or less (although it will fluctuate). So we will give it a tolerance margin. We will only increase the angle, a given value, if the reading of the potentiometer exceeds the value of 600 and we will decrease it when it falls from 400.
This way, small oscillations around the midpoint will not affect the movement of the servo. That is, we have filtered them.
The following sketch includes all these improvements:
Sketch 17.2#include <Servo.h> // Includes the Servo library Servo servo1; // Creates a Servo type object called servo1 int angle = 90; // We start in the middle int offset = 3; // Controls the movement's offset int X_axis = A1; int Y_axis = A2; int button = 4; void setup() { servo1.attach(6); // Connects servo1 to pin 6 pinMode(button, INPUT_PULLUP); } void loop() { int p = analogRead(X_axis); if (p < 400) // If the reading is less than 400 angle = angle - offset; // Decreases the angle else if (angle > 600) // If the reading is greater than 600 angle = angle + offset; // Increases the angle servo1.write(angle); // Moves the servo delay (50); // This delay controls movement speed if (!digitalRead(button)) digitalWrite(LED, HIGH); else digitalWrite(LED, LOW); delay(250); }
You will check that the movement is more fluid and consistent and that the convulsions of the servo are virtually eliminated. We also use this method to fix the servo in the desired position (although we release the joystick), something that would be impossible otherwise.
Summary
- We have seen that a joystick is composed of two potentiometers, placed at 90º one from each other, plus a button, all of them ordinary
- We have taken advantage of the assembly of the previous chapter to move the servo with the joystick and map its value between 0 and 180º.
- We have introduced the concept of signal filtering, which in itself is a specific branch of electronics and computing, and every day is more important in all fields of technology.
Give a Reply