Thumb Joystick Hookup Guide a learn.sparkfun.com tutorial
Available online at: http://sfe.io/t870
Introduction
Whether you're blasting aliens, driving a robot, or write your awesome classic Arcade Game for your Arduino, you'll find the analog thumb joystick a very useful addition to your projects. This tutorial will go over the analog thumb joystick breakout board with some Arduino examples.
Later, we'll also go over the thumb joystick shield for Arduino and Processing examples. You can follow along with the examples using the breakout board if you have some additional hardware!
Suggested Viewing
For a simple demo of the thumb joystick, check out the video below!
Required Materials
To follow along with this tutorial, you will need the following materials. You may not need everything though depending on what you have. Add it to your cart, read through the guide, and adjust the cart as necessary.
Tools
You will need a soldering iron, solder, and general soldering accessories.
Suggested Reading
If you aren’t familiar with the following concepts, we recommend checking out these tutorials before continuing.
How to Solder: Through-Hole Soldering
Analog to Digital Conversion
Installing Arduino IDE
Connecting Arduino to Processing
How Does an Analog Thumb Joystick Work?
Imagine a volume control or other knob. These controls are generally made from potentiometers, which are variable resistors. By connecting the potentiometer as a voltage divider, you can get a varying voltage out of the device, which can be fed to an analog to digital converter on a microprocessor. This allows the software to read the knob position.
Potentiometers
This joystick contains two potentiometers, connected with a gymbal mechanism that separates the "horizontal" and "vertical" movements. (If the joystick is flat on a table, these movements are more "front / back" and "left / right", but you get the idea.) The potentiometers are the two blue boxes on the sides of the joystick. If you move the joystick while watching the center shaft of each potentiometer, you'll see that each of the potentiometers pick up movement in only one direction. Clever, isn't it!
Momentary Push Button
This joystick also contains a switch which activates when you push down on the cap. The switch is the small black box on the rear of the joystick. If you push down on the cap, you can see a lever pushing down on the head of the switch. The lever works no matter what position the joystick is in. Cool!
Hardware Overview: Breakout
The breakout board has 5 pins broken out to easily connect to the thumb joystick. When mounting and programming with the joystick, make sure to keep track of the orientation of the board to determine what position the joystick is in.
- VCC - Connect this to your positive supply (usually 5V or 3.3V depending on your logoc levels).
- VERT - This is the vertical output voltage (will be about half of VCC when the joystick is centered).
- HORIZ - This is the horizontal output voltage (will be about half of VCC when the joystick is centered).
- SEL - This is the output from the pushbutton, normally open, will connect to GND when the button is pushed.
- GND - Connect this to your ground line (GND).
Hardware Assembly: Breakout
To easily connect to the joystick, you'll need a "breakout board" (the red printed-circuit board, or PCB). You'll need to solder the breakout board to the joystick. If this is your first time soldering you'll probably want to check out our introductory soldering tutorial first. Read the guide and you'll pick up some good tips that will help your first soldering experience go more smoothly.
How to Solder: Through-Hole Soldering
September 19, 2013
Once this is done, it will be much easier to connect the joystick to your project (you won't have to solder wires to all those little pins). To attach the breakout board to the joystick, follow these steps.
Insert Thumb Joystick to Breakout Board
First, test-fit the breakout board to the joystick. If any pins on the joystick are bent, gently straighten them. The joystick goes into the side of the board with the white outline (not the side with the SparkFun logo). Insert the joystick into the board, matching the white outline, and ensure that all the pins go into their holes (if they don't, you may not have the joystick oriented correctly).
Solder
If everything fits OK, carefully solder the pins from the opposite side of the board (the side with the SparkFun logo). Never soldered before? It's easy, check out our tutorial on how to solder. If this is your first time soldering, practice a bit before working on this board. Before and during soldering, ensure that the joystick stays tight against the breakout board. There are 14 solder connections to make, including the four posts at the corners of the joystick.
If you'd like to connect a 5-pin header to the board, or solder bare wires to the output holes, you may do that now.
Once you're done soldering, you're ready to use your joystick! If you have not already, insert the cap on the joystick.
Arduino Examples: Breakout
Hardware Hookup
The breakout board provides five labeled connections. You'll connect these lines to your project or microcontroller. In this example, we'll use the RedBoard with ATmega328P. For stability, make sure to have part of the breadboard under the joystick.
Hookup Table
RedBoard w/ Atmega328P | Thumb Joystick Breakout |
---|---|
5V | VCC |
A0 | VER |
A1 | HOR |
2 | SEL |
GND | GND |
Thumb Joystick Breakout Board Example
Here's an example Arduino sketch which sets up the microcontroller to read the inputs, and then continuously prints the values to the serial monitor. If you're using a different microcontroller, the steps should be similar; you'll just need to determine how to read analog and digital inputs on your device. Copy the code and paste it in the Arduino IDE. Select Arduino/Genuino Uno as the board, the COM port that it enumerated on, and hit the upload button.
language:c
// Thumb Joystick Breakout Board Example
// Modified by: Ho Yun "Bobby" Chan, SparkFun Electronics, 2/19
// Written by: Mike Grusin, SparkFun Electronics 3/11
// This code is free, baby. Use it however you like.
// This sketch shows the basic operation of the Thumb Joystick (COM-09032) and breakout board (BOB-09110).
// The joystick outputs two analog voltages (VERT and HORIZ), and one digital signal (SEL) for the pushbutton.
// Connections to joystick (change if you use different pins):
const int VERT = 0; // analog
const int HORIZ = 1; // analog
const int SEL = 2; // digital
// Also connect the joystick VCC to Arduino 5V, and joystick GND to Arduino GND.
// This sketch outputs serial data at 9600 baud (open Serial Monitor to view).
//initialize variables for analog and digital values
int vertical, horizontal, select;
void setup(){
/* old method to turn on the pull-up resistor for the SEL line
before Arduino IDE v1.01 (see http://arduino.cc/en/Tutorial/DigitalPins)
make the SEL line an input*/
//pinMode(SEL, INPUT);
//digitalWrite(SEL, HIGH);
// make the SEL line an input
pinMode(SEL, INPUT_PULLUP);
// set up serial port for output
Serial.begin(9600);
}
void loop(){
// read all values from the joystick
vertical = analogRead(VERT); // will be 0-1023
horizontal = analogRead(HORIZ); // will be 0-1023
select = digitalRead(SEL); // will be HIGH (1) if not pressed, and LOW (0) if pressed
// print out the values
Serial.print("vertical: ");
Serial.print(vertical, DEC);
Serial.print(" horizontal: ");
Serial.print(horizontal, DEC);
Serial.print(" select: ");
if (select == HIGH) {
Serial.println("not pressed");
}
else {
Serial.println("PRESSED!");
}
}
What You Should See
Open the serial monitor at 9600 baud to begin seeing the raw output values. With the vertical "↑ V" pointing away from you, start moving the joystick around.
In this case, the joystick was sitting around 520 for the vertical and horizontal values when not moving. Moving the joystick up toward the up arrow and in a clockwise motion, the joystick will read a value of about 1023 for the vertical component while the horizontal sits at the same value. Moving it to the right, the vertical component will sit at the resting value of about 520 again while the horizontal component will read a value of about 0. As the joystick moves down toward you, you'll notice the vertical component will drop to 0 and the horizontal will sit at it's resting value again. Moving the joystick to the left, you'll noitice the vertical component sit back to its resting value while the horizontal component jump up to 1023. Finally, you'l receive a the "PRESSED!" message when pressing down on the joystick.
This joystick is a low-power device. The analog and switch outputs should be connected only to high-impedance inputs, such as I/O ports on a microcontroller or op-amp inputs. Don't try to hook the joystick directly to LEDs, motors, or other high-current devices (more than 1mA), or you may damage it.
Looking for more examples with the joystick? Check out the examples in the next section for the shield!
Hardware Overview: Shield
Below is a top view of the shield before any component is soldered.
Joystick - On the left of the board is the footprint for the thumb joystick. The potentiometers are connected to analog pins A0 and A1. The "select" button for the joystick is connect is connected to pin 2.
Prototyping Area - The center includes general plated through holes to prototype and solder additional components like a small OLED screen, XBee Explorer, or sensors. You'll need to wire it up to the respective pins depending on your project.
12mm Buttons - On the right are locations for four 12mm momentary pushbuttons. Up is connected to pin 4, right to pin 3, down to pin 5, and left to pin 6.
Edge Pins - The board was designed for the original Arduino Uno footprint so you'll see the standard headers on the edge of the board.
Note: From the inception of Arduino until some time in 2012, every Arduino had the same standard footprint: two 6-pin headers on one side, two 8-pin headers on the other. Lately, though, Arduinos have been transitioning to a new shield-header layout, called the R3 footprint. This layout has a 6-pin and 8-pin headers on one side, and an 8-pin and 10-pin on the other. While this board uses the old style version, it still has the same functionality when stacked on an Arduino Uno R3 footprint.Reset Button - Just beside the reset pin is the location for the mini push button to reset an Arduino when stacked on top.
Hardware Assembly: Shield
Before assembling the shield, make sure that you have all the components needed to solder the board together.
If you ordered a kit, you should have the following components included.
- 1 x Thumb Joystick (COM-09032)
- 1 x Joystick Shield PCB (DEV-09490)
- 4 x Momentary Push Button Switch - 12mm Square (COM-09190)
- 2 x 8-pin Arduino Stackable Header (PRT-09279)
- 2 x 6-pin Arduino Stackable Header (PRT-09280)
- 1 x Mini Push Button Switch (COM-00097)
All parts present and accounted for? Great, let's start to put the shield together.
Insert Thumb Joystick and Buttons to Shield
Before I start to solder parts into place, I like to do a "test fit" of the kit components. This allows me to check that everything fits as expected plus it's fun. Just work through the rest of these instructions carefully putting the components into place but don't solder anything. This is entirely optional.
Once you've done a test fit, you can pull the components out with care and then put the shield together for real!
Soldering Tips
If this is your first time soldering you'll probably want to check out our introductory soldering tutorial first. Read the guide and you'll pick up some good tips that will help your first soldering experience go more smoothly.
How to Solder: Through-Hole Soldering
September 19, 2013
Below you'll find a suggested order for assembling the shield, your personal preference might give you other ideas on how to proceed and that's fine too. When no order for assembling is provided, soldering the smallest components in first is a good rule to follow. Just make sure all the pieces go in the right place and in the correct orientation.
If you don't have a PCB vise then you might want to put the header pins in before the thumb joystick — that way you can rest the PCB on the headers as you solder the pins. (In fact, you might want to do this even if you do have a vise.)
Another approach to consider is to attach the headers first so you can test each component is working after you add it.
Alright, let's start with...
Mini Push Button Switch
The mini push button resets the main Arduino board — it's present because once the shield is connected to the Arduino, it's difficult to access the normal reset button.
Ensure you're looking at the top of the PCB — the top is where the components sit — it will have the "sparkfun.com" text and logo on it.
Begin by pushing the four legs (or leads) of the button into the correct location on the PCB as shown in the photograph below. It sits just below the word "Reset" on the PCB. The button can be orientated in four different directions with the legs pointing down but only two of them are correct — you shouldn't need to apply much force to seat the push button in the holes. See the next closeup image for a better view of how the button should sit.
You can see more clearly below that the legs splay out slightly. There's two pairs of legs on opposite sides of the body — one pair should sit in the set of holes close to the edge of the PCB while the other pair should sit on the opposite short-edge side of the white rectangle marked ("silk screened") on the PCB.
If you bend one of the legs too much gently move it back into place — but don't do this too often or the metal will break from metal fatigue.
With enough room below the PCB for the legs to extend apply pressure to the top of the push button so the plastic bottom sits on the PCB — this allows the PCB to take most of the force when you press the button rather than the thin metal legs.
Next turn the board over and you should see those cute little legs pointing through the holes in the PCB. If they don't extend as far as shown in this picture check you have the orientation correct and then apply a little more pressure to pop the legs through. The button shouldn't fall out of the holes when you turn the PCB upside down.
Now it's time to solder the first leg — it doesn't matter which of the four you start with — but ensure the plastic bottom of the button is still flat against the PCB. Apply heat with the soldering iron simultaneously to the leg of the button and the pad (the circle of track around the hole) on the PCB then carefully feed a little piece of the solder into the joint formed between the soldering iron, pad, and component leg. Then remove the solder wire and then the soldering iron — in that order.
Once you have completed one leg, again check the bottom of the button is touching the PCB and then solder the diagonally opposite leg as well. Soldering the legs in this order ensures the button sits well and you can solder the two remaining legs without needing to double-check if the button is still sitting correctly.
When you have soldered all four legs of the button it should look something like the photo below:
If you like, you can flip the board back over and give the mini push button a triumphant press and show it to your friends.
Push Buttons
It is now time to attach the four larger push buttons to the shield. These are the "action" buttons of your joystick shield and you can use them to control the actions of a character on screen, perhaps causing the character to shoot, punch or arrange flowers as the mood strikes. ("Flower Arranger II : This time it's Perennial!")
You'll notice the method we use is very similar to the approach we took with the mini push button — this is because the buttons are almost identical in construction apart from their size.
First, insert the legs of the four buttons into the holes on the PCB — their orientation should mean the edges without legs cover the white silk screen lines above and below the white silk screen circles. For each button ensure all four legs are inside their respective holes before applying pressure to the top of the button to push the legs through to the other side — if you're not careful you can bend one or more of the legs under the button by accident. If you do bend one of the legs under, remove the button and use a small screwdriver or pair of pliers to straighten the bent leg enough that it will again sit in the correct place to fit through the hole.
I suggest putting all four buttons into place before soldering them because the legs will prevent them from falling out when you flip the board over and it's nice to be able to get into the flow of things and solder all the joints at one time. But if you prefer to solder each button in place before adding the next that should work okay too.
You can now flip the board over and see the push button legs all poking through in a manner resembling the view of the pool during a synchronized swimming competition.
Once again it's time to solder the first of the button legs. My suggestion is to start with the button closest to the middle of the board and work left to right and down from there so you don't have to move the soldering iron over already soldered joints. Again the order isn't critical though.
As before, it doesn't matter which of the four legs of the button you start to solder — but remember to ensure the plastic bottom of the button is still flat against the PCB. You may have to hold the buttons from underneath against the PCB as the legs might be a little loose, be sure to touch only the plastic part as the metal part will heat up. Apply the heat with the soldering iron simultaneously to the leg of the button and the pad then carefully feed a little piece of the solder roll into the joint formed between the soldering iron, pad, and component leg. Then remove the solder wire and then the soldering iron — in that order.
Once you have completed one leg, again check if the bottom of the button is touching the PCB and then solder the diagonally opposite leg as well. Soldering the legs in this order ensures the button sits well and you can solder the two remaining legs without needing to double-check if the button is still sitting correctly.
After you've finished all sixteen legs the board should look like this — I hope those swimmers weren't planning on leaving the pool today:
Thumb Joystick
As you may recall from the introduction to this soldering section I suggest you learn from my experience (especially if you don't have a PCB vise) and solder the headers before you solder the thumb joystick. If that's the case, feel free to skip ahead to the headers section and then return to this joystick section.
Ha, I can't believe they fell for that "solder the headers first" trick, can you? Well, joke's on you because it really is easier to solder the headers before the joystick but if you insist, here's how to get the joystick connected. Just remember if you have the headers connected then your board will look a little different to these photos.
You first need to insert the legs of the joystick into the board similar to the breakout board. There's quite a number of legs of different sizes so it pays to be careful pushing the joystick into place.
You'll notice there's a number of sets of legs:
- Four legs for the small mini push button used for the center button functionality. This sits on an outcrop that juts out from one side of the white plastic base and will look suspiciously similar to our reset mini push button. These are quite thin legs.
- Four legs which are thicker than the others and are located at the four corners of the main part of the white plastic base. These legs are structural only and aren't intended to connect to any electrical signals.
- Two sets of three legs each connected to the green bodies of the potentiometers used to detect the joystick position in two dimensions.
You might find it easier to remove the black plastic top or "hat" from the joystick first like I have in these photos — just give the hat a gentle tug and it should slide off the center stick. Put the hat to one side so you don't lose it or see if you can wear it as a hat yourself in which case you probably will lose it.
The mini push button legs are the most difficult to get in the correct place so I suggest you line those ones up with the appropriate holes first. Note the whole joystick will only fit in one orientation which has the mini push button facing the center on the PCB. It might help to tilt the base of the joystick slightly so that the two structural legs closest the mini push button fit into their associated holes around the same time as the button legs are in the right place. Then tilt the base level so the remaining legs fit into their proper holes. It's like putting on trousers, there's few things more annoying than getting your leg in the wrong hole — so take your time to make sure everything's where it should be.
If you do bend a leg, first try to see if you can push it gently into position with the head of a small screwdriver, otherwise take the joystick out, straighten the leg and try again — but once again if you do this too often the leg might snap off from metal fatigue.
Once you've applied enough pressure to the top of the joystick case all the legs should poke through the bottom of the PCB — the structural legs will protrude further than the others:
You have a couple of options for the order in which you solder the legs but my suggestion is to start with the structural legs:
- Ensure the base is sitting as close to the PCB as possible — it won't sit entirely flush as there are plastic bumps on the base that prevent this.
- Then solder the four structural legs starting with any leg. You can use more solder than you might normally use to provide extra support.
- Check the base is still somewhat flush.
- Solder the diagonally opposite structural leg into place.
- Then solder the two remaining structural legs in any order.
- After the structural legs are in place, I'd suggest soldering the two sets of three potentiometer legs.
Finally, ensure the mini push button legs are through the PCB as far possible and solder the button in place in the same way you've done before.
When you're finished your board should look somewhat like this:
If you've already attached the headers you can now flip the board over and reattach the plastic hat to the white center post of the joystick — take note that it will only fit in two orientations as the center post is rectangular. You can now skip to the Completed Solder Joints section.
If you still need to attach the headers you can move on to the next section.
Feel free to pretend you're using the joystick to dock the Apollo before you move on. ("Psssh" thruster noises aren't optional if you do though.)
Headers
Now it's time to solder the headers. You'll notice in these images and the parts list we use the stackable headers which allow an additional shield to be stacked on top of this one. The alert among you will notice however that a standard shield won't fit on top of this shield due to the position of the joystick and even if it did it would obscure at least one of the push buttons.
So what's the advantage of using the stackable headers in this case? It means you can still insert jumpers into the headers to gain access to the unused pins. If you wanted you could also add a custom mini shield on top if you'd like — perhaps with a couple of extra buttons?
If you don't think you'll need this extra functionality you can use standard breakaway headers instead. If you only populate the used pins with headers you can probably still insert jumpers into the other through the holes in the PCB if you need.
Six Pin Headers
Let's start by soldering the two six pin headers that will supply power and access to the analog pins. First, you can insert one of the headers into the correct location like this:
If you don't have a PCB vise then you will probably want to temporarily put one of the 8 pin headers into its location so that the PCB is level when you solder the headers. The headers won't stay in place when you flip the board over so hold them in place when you turn the PCB over to leave the pins sticking upwards.
If you have a PCB vise you might want to hold the header in place like the following photo:
Next solder one of the pins into place. Ensure the header is aligned as parallel as possible to the edge of the board when you do this:
The reason we start with just one pin is because it makes it easier to obtain the correct alignment and fix any mistakes. Once you've soldered one pin, you might want to test the alignment by inserting the shield into an Arduino. Just be careful when you do so because the header's still only held in place with one solder joint.
If the alignment of the header isn't quite right, carefully reheat the solder joint and move the header slightly. Don't move it after you've removed the heat however, or you'll end up with a poor joint. Here is an example of checking the header alignment:
Once you're happy with the alignment of the header, you can solder another pin into place — my recommendation is to solder the pin at the opposite end of the header to the first pin you soldered. The reason for this is that once the two end pins are in place, the alignment won't change. I recommend double checking the alignment is still okay again by connecting it to your Arduino again.
Once again, if the alignment's not quite right you can reheat the joint and carefully move the pin.
After you've confirmed the alignment you can solder the remaining four pins into place:
At this stage you can repeat these instructions for the second 6 pin header or skip ahead to solder the diagonally opposite 8 pin header. Soldering a 8 pin header now helps to get the alignment right.
Eight pin headers
All right class, who can tell me how we're going to solder the 8 pin header..? Yes, you're correct, exactly the same as the 6 pin header except for the last step where we have an extra two pins to solder into place. As before, first we solder a pin at one end and check the alignment:
Then we solder the pin at the opposite end of the header and re-check the alignment:
And finally we solder the remainder of the pins in the middle of the header.
Repeat this for the second 8 pin header and you're done!
Don't forget to go back and solder the last 6 pin header if you skipped ahead. And if you still need to solder the joystick into place you can go back to that section.
Completed Solder Joints
Once you've finished soldering all the components into place your board will look something like this:
Doesn't that red PCB look just spiffy?
Now's the time to double check all your soldering and fix up any problems:
- Do the joints all look shiny and volcano shaped?
- Do you have any "shorts" or "bridges" between joints where you've accidentally connected the two joints with solder? Check out the soldering guide for advice to avoid these problems.
Don't be too fussy though because re-heating and moving the joints is to be avoided if possible.
Completed Shield
Once you've completed your shield it should look like this when connected on top of your Arduino:
Now it's time to make your joystick shield control something!Arduino Examples: Shield
The joystick shield provides simple analog inputs along with four separate buttons and one button under the joystick itself. The joystick can be used for controlling outputs such as a melody or pixels on a screen. The buttons can be used for navigation or game control. If you want to jump directly into the example sketches, download and unzip the examples from the GitHub repo to dive in.
- JoystickArduinoBasicExample.ino - Printing joystick values and button presses to the console.
- JoystickArduinoIntermediateExample.ino - This code does the same thing as the basic code but includes more positions on the joystick.
- JoystickArduinoMelodyControl.ino - Controlling a melody and tempo with the joystick and a piezo buzzer.
- SparkFunJoystickShieldSampleSketch.ino - Example from the demo video to use with the a serial enabled LCD.
For the scope of this tutorial, we will focus on the first two examples to read the joystick and buttons using the shield. If you have the joystick breakout, you can still follow along as long as everything is wired like the shield and use the pins definitions in the code for reference. Also, you can check out the additional examples if you have additional hardware like a piezo buzzer or serial enabled LCD.
Basic Example
After downloading the examples, open the JoystickArduinoBasicExample.ino sketch, select Arduino/Genuino Uno as the board and the COM port that the board enumerated on, and hit the upload button. Open the serial monitor at 9600 baud and test out the joystick shield to observe the joystick and button behaviors.
If you've been following along with the tutorial, the output looks similar to the output from the breakout board example.There are two differences between the breakout and shield. One apparent difference is the output. There are more values for each line due to additional four buttons. If no button is pressed, they will read as a 1. If a button is pressed, they will read as 0.
The second difference is more subtle. The orientation of the joystick is rotated 90°. The "vertical" position is referenced with as the "x-axis" while the "horizontal" is referenced as the "y-axis". The output indicates that the joystick is not moving when the values are around 520. Moving the joystick up toward the "AREF" pin, the joystick will read the same value for the x-axis while y-axis component will jump to 1023. Moving it clockwise to the right, the x-axis will read a value of about 0 while the y-axis component will sit at the resting value of about 520 again. As the joystick moves down toward you, you'll notice the x-axis will sit at it's resting value again while the y-axis component will drop to 0. Moving the joystick to the left, you'll notice the x-axis component jump up to 1023 while the y-axis component sit back to its resting value. Finally, the select button will read as 0 when pressing down on the joystick.
Intermediate Example
Open the JoystickArduinoIntermediateExample.ino sketch, select Arduino/Genuino Uno as the board and the COM port that the board enumerated on, and hit the upload button. Open the serial monitor at 9600 baud and test out the joystick shield to observe the joystick and button behaviors.
Again, you'll notice that the raw output is the same as the basic example. However, there is an additional line indicating the position of the joystick. The code is a little bit more complicated with the nested if
statements to check the joystick's position. The code breaks the position up into 9 positions:
- center
- up
- right-up
- right
- right-down
- down
- left-down
- left
- left-up
Code To Note
Once you've got the shield assembled, you can begin to change the example code to make the joystick do your bidding. Here are a few in-depth explanations about the code.
- How do I find the current position of the joystick?
- How do I find the current direction of the joystick?
- How do I set up the Arduino so I can know when a button has been pushed on the Joystick Shield?
- How do I know when a button on the Joystick Shield has been pressed?
How Do I Find the Current Position of the Joystick?
The position of the joystick is calculated from the two potentiometers in the joystick. The joystick can move in two dimensions which typically would represent X and Y coordinates but could represent any two dimensional quantity. To read the potentiometers we use the analogRead()
function which returns a number from 0 to 1023. We need to supply an analog pin number to the function — for the joystick shield the X position is read from analog pin 0 and the Y position is read from analog pin 1:
language:c
Serial.println(analogRead(0)); // Prints current X position
Serial.println(analogRead(1)); // Prints current Y position
It is a good technique — because it clarifies your intent — to use ''constants'' for values that will not change when your sketch runs. With this in mind, the following sketch snippet sets up constants for the analog pins used and prints the current X and Y positions to the serial console:
language:c
const byte PIN_ANALOG_X = 0;
const byte PIN_ANALOG_Y = 1;
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.print("x:");
Serial.print(analogRead(PIN_ANALOG_X));
Serial.print("");
Serial.print("y:");
Serial.print(analogRead(PIN_ANALOG_Y));
Serial.print("");
Serial.println();
}
How Do I Find the Current Direction of the Joystick?
It can be useful to use the value of the X and Y position to determine if the joystick is centered or moved in one of 8 directions (i.e. up, right-up, right, right-down, down, left-down, left, left-up).
Since we know the value in each dimension will be between 0 and 1023 you might expect the centre value to be around 511 or 512 but because the joysticks are physical devices the actual value is unlikely to be that exact. If we choose the wrong value we'll find that our joystick will be detected as moving in a particular direction even though it is centered.
To work around this issue we specify two "threshold" values and consider that any value within that range should be considered "centered":
language:bash
|----------|----|----------|
0 505 515 1023
The threshold values you choose may be different depending on your joystick. We specify the values as constants in the code:
language:c
const int X_THRESHOLD_LOW = 505;
const int X_THRESHOLD_HIGH = 515;
const int Y_THRESHOLD_LOW = 500;
const int Y_THRESHOLD_HIGH = 510;
Next, we want to map our value in each dimension from a position range of 0 to 1023 to a direction value in the range -1 to 1. For the X, dimension -1 means moved to the left, 0 means not moved in the X dimension and 1 means moved to the right. For the Y dimension -1 means moved down, 0 means not moved in the Y dimension and 1 means moved up.
We start by setting the direction in each dimension to 0 ("centered") and then we use if/else
statements to check if the position value in either dimension is above or below our threshold values:
language:c
x_direction = 0;
y_direction = 0;
x_position = analogRead(PIN_ANALOG_X);
y_position = analogRead(PIN_ANALOG_Y);
if (x_position > X_THRESHOLD_HIGH) {
x_direction = 1;
} else if (x_position < X_THRESHOLD_LOW) {
x_direction = -1;
}
if (y_position > Y_THRESHOLD_HIGH) {
y_direction = 1;
} else if (y_position < Y_THRESHOLD_LOW) {
y_direction = -1;
}
The Arduino provides a map()
function which in theory we could use instead of if/else
but the method is complicated by the centering issues so we won't consider that approach here.
As you can see in the next complete example we then use if/else
statements to print the direction — you can modify this example to perform whatever action you need:
language:c
const byte PIN_ANALOG_X = 0;
const byte PIN_ANALOG_Y = 1;
const int X_THRESHOLD_LOW = 505;
const int X_THRESHOLD_HIGH = 515;
const int Y_THRESHOLD_LOW = 500;
const int Y_THRESHOLD_HIGH = 510;
int x_position;
int y_position;
int x_direction;
int y_direction;
void setup() {
Serial.begin(9600);
}
void loop () {
x_direction = 0;
y_direction = 0;
x_position = analogRead(PIN_ANALOG_X);
y_position = analogRead(PIN_ANALOG_Y);
if (x_position > X_THRESHOLD_HIGH) {
x_direction = 1;
} else if (x_position < X_THRESHOLD_LOW) {
x_direction = -1;
}
if (y_position > Y_THRESHOLD_HIGH) {
y_direction = 1;
} else if (y_position < Y_THRESHOLD_LOW) {
y_direction = -1;
}
if (x_direction == -1) {
if (y_direction == -1) {
Serial.println("left-down");
} else if (y_direction == 0) {
Serial.println("left");
} else {
// y_direction == 1
Serial.println("left-up");
}
} else if (x_direction == 0) {
if (y_direction == -1) {
Serial.println("down");
} else if (y_direction == 0) {
Serial.println("centered");
} else {
// y_direction == 1
Serial.println("up");
}
} else {
// x_direction == 1
if (y_direction == -1) {
Serial.println("right-down");
} else if (y_direction == 0) {
Serial.println("right");
} else {
// y_direction == 1
Serial.println("right-up");
}
}
}
How Do I Set Up the Arduino So I Can Know When a Button has Been Pushed on the Joystick Shield?
Before you can know if a button on the shield has been pushed, you need to set up your Arduino to recognize the buttons. Unsurprisingly, you will perform this setup in the... setup()
function!
First, we define constants for the Arduino pin associated with each button:
language:c
// Select button is triggered when joystick is pressed
const byte PIN_BUTTON_SELECT = 2;
const byte PIN_BUTTON_RIGHT = 3;
const byte PIN_BUTTON_UP = 4;
const byte PIN_BUTTON_DOWN = 5;
const byte PIN_BUTTON_LEFT = 6;
If you've used a pushbutton switch before you may have noticed a resistor is normally required in order to detect a known voltage when the button is not pressed. To reduce the number of parts required this shield has been designed not to require resistors on the shield itself. Are you thinking to yourself "if push buttons require resistors and the shield has no resistors how can we get the shield to work?"? If you're not thinking that then you can probably skip reading this bit. (And if you're thinking "I'm really hungry" it might be time to put down the electronics and get some food.)
It turns out your Arduino actually has internal resistors connected to the pins inside the microcontroller. In order to use the internal resistors we need to "enable the internal pull-up resistors". If that sounds to you like "hoist the jib and unfurl the main stay" then I can explain some more:
When a "pull-up" resistor is connected to a push button it means that the voltage level when the button is not pressed will be HIGH because the resistors "pulls the voltage level up" to HIGH when the button is not pressed. On a typical Arduino a pin that is HIGH will be at 5 volts. When the push button is pressed the pin will read as LOW because there is less resistance between the pin and ground than there is between the pin and 5 volts.
To enable a pin's pull-up resistor you first set the pin as an input and then enable the pull-up:
language:c
pinMode(PIN_BUTTON_RIGHT, INPUT);
digitalWrite(PIN_BUTTON_RIGHT, HIGH);
The actual code to enable the pull-up doesn't really make any sense if you read it literally but that's the way it works.
Other than remembering that an unpressed button will read as HIGH with a pull-up resistor and a pressed button will read as LOW you don't need to remember or understand the other details.
In order to configure each pin to be an input and enable the pull up resistors we use the following code:
language:c
void setup() {
pinMode(PIN_BUTTON_RIGHT, INPUT);
digitalWrite(PIN_BUTTON_RIGHT, HIGH);
pinMode(PIN_BUTTON_LEFT, INPUT);
digitalWrite(PIN_BUTTON_LEFT, HIGH);
pinMode(PIN_BUTTON_UP, INPUT);
digitalWrite(PIN_BUTTON_UP, HIGH);
pinMode(PIN_BUTTON_DOWN, INPUT);
digitalWrite(PIN_BUTTON_DOWN, HIGH);
pinMode(PIN_BUTTON_SELECT, INPUT);
digitalWrite(PIN_BUTTON_SELECT, HIGH);
}
See the next section to learn how to read whether a button is pressed or not.
How Do I Know When a Button On the Joystick Shield has Been Pressed?
Once you have set up your Arduino to recognize the buttons (see above) you can tell whether the button is pressed with the digitalRead() function. When the value read is LOW the button is pressed and when the value is HIGH the button is not pressed.
language:c
if (digitalRead(PIN_BUTTON_LEFT) == LOW) {
// Button is pressed
} else {
// Button is not pressed
}
The following complete example will print the state of each button and the value of the joystick to the Arduino serial console:
language:c
// Store the Arduino pin associated with each input
// Select button is triggered when joystick is pressed
const byte PIN_BUTTON_SELECT = 2;
const byte PIN_BUTTON_RIGHT = 3;
const byte PIN_BUTTON_UP = 4;
const byte PIN_BUTTON_DOWN = 5;
const byte PIN_BUTTON_LEFT = 6;
const byte PIN_ANALOG_X = 0;
const byte PIN_ANALOG_Y = 1;
void setup() {
Serial.begin(9600);
pinMode(PIN_BUTTON_RIGHT, INPUT);
digitalWrite(PIN_BUTTON_RIGHT, HIGH);
pinMode(PIN_BUTTON_LEFT, INPUT);
digitalWrite(PIN_BUTTON_LEFT, HIGH);
pinMode(PIN_BUTTON_UP, INPUT);
digitalWrite(PIN_BUTTON_UP, HIGH);
pinMode(PIN_BUTTON_DOWN, INPUT);
digitalWrite(PIN_BUTTON_DOWN, HIGH);
pinMode(PIN_BUTTON_SELECT, INPUT);
digitalWrite(PIN_BUTTON_SELECT, HIGH);
}
void loop() {
Serial.print("l:");
Serial.print(digitalRead(PIN_BUTTON_LEFT));
Serial.print("");
Serial.print("r:");
Serial.print(digitalRead(PIN_BUTTON_RIGHT));
Serial.print("");
Serial.print("u:");
Serial.print(digitalRead(PIN_BUTTON_UP));
Serial.print("");
Serial.print("d:");
Serial.print(digitalRead(PIN_BUTTON_DOWN));
Serial.print("");
Serial.print("x:");
Serial.print(analogRead(PIN_ANALOG_X));
Serial.print("");
Serial.print("y:");
Serial.print(analogRead(PIN_ANALOG_Y));
Serial.print("");
Serial.print("s:");
Serial.print(digitalRead(PIN_BUTTON_SELECT));
Serial.print("");
Serial.println();
}
Resources and Going Further
Now that you've successfully got your joystick up and running, it's time to incorporate it into your own project!
For more information, check out the resources below:
Breakout Board
Shield
Need some inspiration for your next project? Check out some of these related tutorials:
If you have no idea what to do with a joystick, checkout the following videos:
learn.sparkfun.com | CC BY-SA 3.0 | SparkFun Electronics | Niwot, Colorado