Summary
Introduction
How do you steer a drone using a controller with a joystick? Find out in this activity as you program an Arduino to interface with an analog joystick, similar to those found in most video game controllers. You can use the joystick to make a mini popsicle stick drone tilt side to side or move up and down.
See this page for a complete list of our mini drone projects. You may wish to do the projects in order.
Materials
In addition to the materials in the DIY Mini Drone: Arduino™ Altitude Control project or the materials in the Program Drone Steering with an Arduino® project, you will need:
The parts to build a basic drone are available in the DIY Mini Drone Kit.Prep Work
Instructions
Joystick for Altitude Control
If you did the DIY Mini Drone: Arduino™ Altitude Control project, follow these instructions to replace the potentiometer with the joystick for altitude control.- Rebuild your circuit as shown in the diagram below (click for a bigger version of the breadboard layout or circuit diagram). Note that the circuit diagram and code are for the PING ultrasonic distance sensor. If you have an HC-SR04 ultrasonic sensor instead, you should follow the instructions in our HC-SR04 ultrasonic distance sensor tutorial to modify your circuit and code.
- Remove the potentiometer completely.
- You will need to move the button up on the breadboard to make room for the joystick.
- Connect the joystick's pins, as follows:
- L/R+ and U/D+ to 5V (breadboard positive bus)
- L/R to Arduino analog input A1
- U/D to Arduino analog input A0
- GND to breadboard ground bus
- Download drone_altitude_joystick.ino and upload it to your Arduino.What happens when you run the code and push the joystick up and down?Does anything happen if you push the joystick left to right?
- Try changing the scale variable in the code. This variable controls how quickly the analog voltage from the joystick changes the drone's target height. The smaller the number, the faster the drone will move.What happens when you change this number? Can you find a value that feels "just right" for controlling the drone with the joystick?
Joystick for Drone Steering
If you did the Program Drone Steering with an Arduino® project, follow these instructions to replace the buttons with the joystick for steering control.- Rebuild your circuit as shown in the diagram below (click for a bigger version of the breadboard layout or circuit diagram).
- Remove all four push buttons from the breadboard.
- Connect the joystick's pins, as follows:
- L/R+ and U/D+ to 5V (breadboard left positive bus in the diagram below—the right bus is used for 6 V from the battery pack. Do not connect the two!).
- L/R to Arduino analog input A1.
- U/D to Arduino analog input A0.
- GND to breadboard ground bus.
- Download drone_steering_joystick.ino and upload it to your Arduino.What happens when you run the code and press the joystick up and down or side to side?Does anything happen if you move the joystick in a circle?
- There are several variables in the code that you can experiment with changing, but you need to be careful (explained in more detail in the next step). You will not break your drone, but you might see some strange or unexpected behavior depending on the values you enter for these variables.
- defaultSpeed sets the default speed for each motor when the joystick is in the neutral position.
- speedChange sets the maximum possible speed change for each motor.
- a is a multiplier that converts the analog joystick voltage to a speed change for each motor.
- Why do you need to be careful when changing these values? Because of something called overflow. The Arduino controls the motors' speed using a pulse-width modulation (PWM) signal via the analogWrite() function. For the Arduino UNO, analogWrite() only accepts values between 0 and 255. If you try to enter a value of 256, it will overflow and wrap back around to zero. Conversely, if you try to enter a value of -1, it will wrap back around to 255. This is why you need to be careful when changing the defaultSpeed, speedChange, and a variables. Depending on the values you enter, the code may calculate motor speed values (e.g. the variable motor1speed) that are outside the allowed 0–255 range. This will result in strange drone behavior, such as a motor spinning very slowly when you expect it to spin very fast, causing your drone to tilt in the wrong direction. You could get around this problem by adding IF statements to make sure the motor speeds stay within the allowed range, such as:
if(motor1speed>255){motor1speed=255;}
if(motor1speed<0){motor1speed=0;}
Cleanup
What Happened?
If you did the altitude control project, then when the joystick is in its neutral position, the drone should automatically hover in place (thanks to the automatic feedback control from the Arduino and ultrasonic distance sensor). When you push the joystick up (or down), the drone will move up (or down) until you let go of the joystick. When you let go of the joystick, it will automatically hover in place at the new altitude. Pushing the joystick farther will make the drone move faster. Changing the scale variable will change how quickly the drone responds to the joystick input. If it responds too quickly, the joystick may feel too sensitive, and it will be hard to make small adjustments to the drone's height. Conversely, if it responds too slowly, then it may take a long time to move between positions, even when you push the joystick all the way up or down.
If you did the steering project, then when the joystick is in the neutral position, all four motors spin at the same speed, and the drone should fly level. When you tilt the joystick in any direction, it will proportionally increase the speed of some motors and decrease the speed of the opposite motors, causing the drone to tilt in the same direction you push the joystick. Changing some of the variables in the code can change the joystick's sensitivity, but as explained in the procedure, you may see strange behavior (the drone tilting in the wrong direction) if you change the variables too much.
Digging Deeper
In this activity, you used a single joystick to either control your drone's up-and-down motion or side-to-side tilt, while the drone was constrained (either by guide poles or springs) and could not move in other directions. Real drones are free-flying and free to move in three-dimensional space. A free-flying object has a total of six degrees of freedom, or ways that it can move. Three of these motions are translational (moving in a straight line): forward/backward, left/right, and up/down. Three are rotational (spinning): roll (tilting side to side), pitch (tilting forward and backward), and yaw (spinning left to right while remaining level).
Real drone controllers typically have two joysticks for you to use to control their motion. However, two joysticks only gives you four total directions to control, not six (up/down and left/right on the left joystick, and up/down and left/right on the right joystick). So how do you control a flying drone that has six degrees of freedom? Even though the drone has six degrees of freedom, they are not all independent. That means that some of them depend on each other. For example, when a drone rolls (tilts) to the right, it will also start moving to the right. This means that the drone's roll and left/right translation are coupled. The same applies to the drone's pitch and forward/backward motion. You cannot change one without changing the other. This means that you can steer the drone in 3D space with two joysticks instead of three.

Ask an Expert
For Further Exploration
- Can you build or 3D-print a handheld controller for your joystick instead of mounting it on a breadboard? You could also include some buttons, like the lift off/land button in the altitude control project.