Introduction: Arduino Drone With GPS

We set out to build an Arduino-controlled and stabilized, GPS-enabled first-person-view (FPV) quadcopter drone with return to home, go to coordinate, and GPS hold functions. We naively assumed that combining existing Arduino programs and wiring for a quadcopter without GPS with those of a GPS transmission system would be relatively straightforward and that we could quickly move on to more complex programming tasks. However, a surprising amount had to change in order to mesh these two projects, and thus we ended up making a GPS-enabled FPV quadcopter, without any of the added functionality.

We have included instructions on how to replicate our product if you are happy with the more limited quadcopter.

We have also included all the steps we took on the way to a more autonomous quadcopter. If you feel comfortable digging deep into Arduino or already have a lot of Arduino experience and would like to take our stopping point as a jumping-off point for your own exploration, then this Instructable is also for you.

This a great project to learn something about building and coding for Arduino no matter how much experience you have. Also, you will hopefully walk away with a drone.

The setup is as follows:

In the materials list, parts with no asterisk are required for both goals.

Parts with one asterisk are required only for the unfinished project of a more autonomous quadcopter.

Parts with two asterisks are required only for the more limited quadcopter.

Steps common to both projects have no marker after the title

Steps only required for the more limited non-autonomous quadcopter have "(Uno)" after the title.

Steps only required for the in-progress autonomous quadcopter have "(Mega)" after the title.

To build the Uno-based quad, follow steps in order, skipping any steps with "(Mega)" after the title.

To work on the Mega-based quad, follow steps in order, skipping any steps with "(Uno)" after the title.

Step 1: Gather Materials

Components :

1) One quadcopter frame (the exact frame likely doesn't matter) ($15)

2) Four 2830, 900kV brushless motors (or similar), and four mounting accessory packs (4x$6 + 4x$4 = $40 total)

3) Four 20A UBEC ESCs (4x$10 = $40 total)

4) One power distribution board (with XT-60 connection) ($20)

5) One 3s, 3000-5000mAh LiPo battery with XT-60 connection (3000mAh corresponds with approx. 20 min of flight time) ($25)

6) Lots of propellors (these break a lot) ($10)

7) One Arduino Mega 2560* ($40)

8) One Arduino Uno R3 ($20)

9) A second Arduino Uno R3** ($20)

10) One Arduino Ultimate GPS Shield (you don't need the shield, but using a different GPS will require different wiring) ($45)

11) Two HC-12 wireless transceivers (2x$5 = $10)

12) One MPU- 6050, 6DOF (degree of freedom) gyro/accelerometer ($5)

13) One Turnigy 9x 2.4GHz, 9 channel transmitter/receiver pair ($70)

14) Arduino female (stackable) headers ($20)

15) LiPo Battery Balance charger (and 12V DC adapter, not, included) ($20)

17) USB A to B male to male adapter cord ($5)

17) Duct tape

18) Shrink tubing

Equipment:

1) A soldering iron

2) Solder

3) Plastic Epoxy

4) Lighter

5) Wire stripper

6) A set of Allen wrenches

Optional components for real-time FPV (first person view) video transmission:

1) A small FPV camera (this links to the pretty cheap and bad-quality one we used, you may substitute a better one) ($20)

2) 5.6GHz video transmitter/receiver pair (832 models used) ($30)

3) 500mAh, 3s (11.1V) LiPo battery ($7) (we used on with a banana plug, but we recommend in retrospect that you use the linked battery, as it has a connector compatible with the TS832 transmitter, and thus doesn't require soldering).

4) 2 1000mAh 2s (7.4V) LiPo battery, or similar ($5). Number of mAh not critical as long as it is more than 1000mAh or so. The same statement as above applies to the plug type for one of the two batteries. The other will be used to power the monitor, so you'll have to solder no matter what. Probably best to get one with a XT-60 plug for this (that is what we did). A link for that type is here: 1000mAh 2s (7.4V) LiPo with XT-60 plug

5) LCD monitor (optional) ($15). You could also use an AV-USB adapter and DVD copying software in order to view directly on a laptop. This also gives the option of recording video and photos, rather than just viewing them realtime.

6) If you've bought batteries with different plugs from the ones linked, you may need appropriate adapters. Regardless, get an adaptor corresponding to the plug for the battery that powers the monitor. Here is where to get XT-60 adapters

* = only for more advanced project

** = only for more basic project

Costs:

If starting from scratch (but with a soldering iron, etc...), no FPV system: ~$370

If you already have an RC transmitter/receiver, LiPo battery charger, and LiPo battery: ~$260

Cost of FPV system: $80

Step 2: Assemble the Frame

This step is fairly straightforward, especially if using the same pre-made frame we used. Simply use the included screws and put the frame together as shown, using an appropriate allen wrench or screwdriver for your frame. Make sure that arms of the same color are adjacent to each other (as in this picture), so that the drone has a clear front and back. Further, make sure that the long part of the bottom plate sticks out in between opposite-colored arms. This becomes important later.

Step 3: Mount Motors and Connect Escs

Now that the frame is assembled, take out the four motors and four mounting accessories. You can use either screws included in the mounting sets, or screws left over from the quadcopter frame to screw the motors and mounts in place. If you buy the mounts we've linked to, you will receive two extra components, pictured above. We have had good motor performance without these parts, so we left them off to reduce weight.

Once the motors are screwed in place, epoxy the power distribution board (PDB) in place on top of the top plate of the quadcopter frame. Make sure that you orient it such that the battery connector points out in between differently-colored arms (parallel with one of the long portions of the bottom plate), as in the picture above.

You should also have four propeller cones with female threads. Set these aside for now.

Now take out your ESCs. One side will have two wires coming out of it, one red and one black. For each of the four ESCs, insert the red wire into the positive connector on the PDB and the black into the negative. Note that if you use a different PDB, this step may require soldering. Now connect each of the three wires coming out of each motor. At this point, it doesn't matter which ESC wire you connect with which motor wire (as long as you are connecting all the wires of one ESC with the same motor!) You will correct any backwards polarity later on. It is not dangerous if wires are reversed; it only results in the motor spinning backwards.

Step 4: Prepare Arduino and Shield

A note before you begin

First, you may choose to solder all the wires together directly. However, we found it invaluable to use pin headers because they provide a lot of flexibility for troubleshooting and adapting the project. What follows is a description of what we did (and recommend others do).

Prepare Arduino and shield

Take out your Arduino Mega (or an Uno if doing the non-autonomous quad), GPS shield, and stackable headers. Solder the male end of the stackable headers in place on the GPS shield, in the rows of pins parallel to the pre-soldered pins, as shown in the above image. Also solder in stackable headers on the pin row labeled 3V, CD, ... RX. Use a wire cutter to clip off excess length on the pins sticking out the bottom. Place male headers with bent tops in all of these stackable headers. These are what you will solder wires to for the rest of the components.

Attach the GPS shield to the top, making sure that the pins match up with those on the Arduino (Mega or Uno). Note that if using the Mega, plenty of the Arduino will still be exposed after you put the shield in place.

Place electrical tape on the bottom of the Arduino, covering all of the exposed pin solders, to prevent any short circuit as the Arduino rests on the PDB.

Step 5: Wire Together Components and Place Battery (Uno)

The schematic above is almost identical to that made by Joop Brooking as we heavily based our design off his.

*Note that this schematic is assuming a properly mounted GPS shield, and thus the GPS does not appear in this schematic.

The schematic above was prepared using Fritzing software, which is highly recommended especially for schematics involving Arduino. We mostly made use of generic parts which can be edited flexibly, as our parts generally weren't in Fritzing's included part library.

-Make sure that the switch on the GPS shield is switched to "Direct Write."

-Now wire up all the components according to the above schematic (except for the battery!) (Important note on GPS data wires below).

-Note that you've already wired up the ESCs to the motors and PDB, so this part of the schematic is done.

-Further, note that GPS data (yellow wires) comes out of pins 0 and 1 on the Arduino (not the separate Tx and Rx pins on the GPS). That is because configured to "Direct Write" (see below), the GPS outputs directly to the hardware serial ports on the uno (pins 0 and 1). This is most clearly shown on the second picture above of the complete wiring.

-When wiring the RC receiver, refer to the picture above. Observe that the data wires go into the top row, while the Vin and Gnd are on the second and third rows, respectively (and on the second-to-farthest column of pins).

-To do the wiring for the HC-12 transceiver, RC receiver, and 5Vout from the PDB to Vin of the Arduino we used stackable headers, whereas for the gyro we soldered the wires directly to the board and using heat-shrink tubing around the solder. You may choose to do either for any of the components, however soldering directly to the gyro is recommended as it saves space which makes the small part easier to mount. Using headers is a small amount more work up front, but provides more flexibility. Soldering wires directly is a more secure connection long-term, yet means that using that component on another project is harder. Note that if you've used headers on the GPS shield, you still have a decent amount of flexibility regardless of what you do. Crucially, make sure that the GPS data wires in pins 0 and 1 on the GPS are easy to remove and replace.

At the end of our project, we were unable to design a good method for attaching all of our components to the frame. Due to the time pressure of our class, our solutions generally revolved around double sided foam tape, duct tape, electrical tape, and zip ties. We highly recommend that you spend more time designing stable mounting structures if you plan this to be a longer-term project. With all that said, if you just want to make a quick prototype, then feel free to follow in our process. However, make sure that the gyro is mounted securely. This is the only way the Arduino knows what the quadcopter is doing, so if it moves in flight you will have issues.

With everything wired up and in place, take your LiPo battery and slide it in between the top and bottom plates of the frame. Make sure that its connector is pointing the same direction as the PDB's connector, and that they can in fact connect. We used duct tape to hold the battery in place (velcro tape also works, but is more annoying than duct tape). Duct tape works well because one can easily replace the battery or remove it for charging. However, you must be sure you tape the battery down TIGHTLY, as if the battery moves around during flight this could seriously upset the balance of the drone. Do NOT connect the battery to the PDB yet.

Step 6: Wire Together Components and Place Battery (Mega)

The schematic above was prepared using Fritzing software, which is highly recommended especially for schematics involving arduino. We mostly made use of generic parts, as our parts generally weren't in Fritzing's included part library.

-Note that this schematic is assuming a properly mounted GPS shield, and thus the GPS does not appear in this schematic.

-Flip the switch on your Mega 2560 to "Soft Serial."

-Now wire up all the components according to the above schematic (except for the battery!)

-Note that you've already wired up the ESCs to the motors and PDB, so this part of the schematic is done.

-The jumper cables from Pin 8 to Rx and Pin 7 to Tx are there because (unlike the Uno, for which this shield was made), the mega lacks a universal asynchronous receiver-transmitter (UART) on pins 7 and 8, and thus we have to use hardware serial pins. There are more reasons we need hardware serial pins, discussed later on.

-When wiring the RC receiver, refer to the picture above. Observe that the data wires go into the top row, while the Vin and Gnd are on the second and third rows, respectively (and on the second-to-farthest column of pins).

-To do the wiring for the HC-12 transceiver, RC receiver, and 5Vout from the PDB to Vin of the Arduino we used stackable headers, whereas for the gyro we soldered the wires directly and using heat-shrink tubing around the solder. You may choose to do either for any of the components. Using headers is a small amount more work up front, but provides more flexibility. Soldering wires directly is a more secure connection long-term, yet means that using that component on another project is harder. Note that if you've used headers on the GPS shield, you still have a decent amount of flexibility regardless of what you do.

At the end of our project, we were unable to design a good method for attaching all of our components to the frame. Due to the time pressure of our class, our solutions generally revolved around double sided foam tape, duct tape, electrical tape, and zip ties. We highly recommend that you spend more time designing stable mounting structures if you plan this to be a longer-term project. With all that said, if you just want to make a quick prototype, the feel free to follow in our process. However, make sure that the gyro is mounted securely. This is the only way the Arduino knows what the quadcopter is doing, so if it moves in flight you will have issues.

With everything wired up and in place, take your LiPo battery and slide it in between the top and bottom plates of the frame. Make sure that its connector is pointing the same direction as the PDB's connector, and that they can in fact connect. We used duct tape to hold the battery in place (velcro tape also works, but is more annoying than duct tape). Duct tape works well because one can easily replace the battery or remove it for charging. However, you must be sure you tape the battery down TIGHTLY, as if the battery moves around during flight this could seriously upset the balance of the drone. Do NOT connect the battery to the PDB yet.

Step 7: Bind Receiver

Take the RC receiver and temporarily connect it to a 5V power supply (either by powering up the Arduino with USB or 9V power, or with a separate power supply. Do not connect the LiPo to the Arduino yet). Take the binding pin that came with the RC receiver and place it to the BIND pins on the receiver. Alternately, short the top and bottom pins in the BIND column as shown in the photo above. A red light should blink rapidly on the receiver. Now take the controller and press the button on the back while it is off, as shown above. With the button pressed, turn on the controller. Now the blinking light on the receiver should turn solid. The receiver is bound. Remove the binding cable. If you were using a different power supply, reconnect the receiver to the 5V out of the Arduino.

Step 8: (Optional) Wire Together and Mount the FPV Camera System.

First, solder together the XT-60 adapter with the power and ground wires on the monitor. These may vary from monitor to monitor, but the power will almost always be red, the ground almost always black. Now insert the adapter with soldered wires into your 1000mAh LiPo with the XT-60 plug. The monitor should turn on with (usually) blue background. That's the hardest step!

Now screw on the antennas on your receiver and transmitter.

Connect up your small 500mAh Lipo to the transmitter. The rightmost pin (right below the antenna) is ground (V_) of the battery, the next pin to the left is V+. They come the three wires that go to the camera. Your camera should come with a three-in one plug that fits into the transmitter. Make sure you have the yellow data wire in the middle. If you used the batteries we linked to with plugs meant for this, this step shouldn't require any soldering.

Finally, wire up your other 1000mAh battery with the DC out wire that came with your receiver, and in turn plug that into the DC in port on your receiver. Finally, connect the black end of the AVin cable that came with your receiver to the AVin port on your receiver, and the other (yellow, female) end to the yellow male end of the AVin cable of your monitor.

At this point, you should be able to see a camera view on the monitor. If you cannot, make sure that the receiver and transmitter are both on (you should see numbers on their small screens) and that they are on the same channel (we used channel 11 for both and had good success). Further, you may need to change the channel on the monitor.

Mount the components on the frame.

Once you have the setup working, unplug the batteries until you are ready to fly.

Step 9: Set Up GPS Data Reception

Wire up your second Arduino with your second HC-12 transceiver as show in the above schematic, keeping in mind that the setup will only be powered as displayed if plugged into a computer. Download the provided transceiver code, open your serial monitor to 9600 baud.

If using the more basic setup, you should begin receiving GPS sentences if your GPS shield is powered and properly wired to the other HC-12 transceiver (and if the switch on the shield is on "Direct Write").

With the Mega, make sure the switch is on "Soft Serial."

Step 10: Perform Setup Code (Uno)

This code is identical to that used by Joop Brokking in his Arduino quadcopter tutorial, and he deserves all the credit for its writing.

With the battery disconnected, use the USB cord to connect your computer to the Arduino, and upload the attached Setup Code. Turn on your RC transmitter. Open your serial monitor to 57600 baud and follow the prompts.

Common errors:

If the code fails to upload, make sure that pins 0 and 1 are unplugged on the UNO/GPS shield. This is the same hardware port that the device uses to communicate with the computer, so it must be free.

If the code skips through a bunch of steps all at once, check that your GPS switch is on "Direct Write."

If no receiver is detected, make sure that there is a solid (but dim) red light on your receiver when the transmitter is on. If so, check the wiring.

If no gyro is detected, this could be because the gyro is damaged or if you have a different type of gyro from that which the code is designed to write to.

Step 11: Perform Setup Code (Mega)

This code is identical to that used by Joop Brokking in his Arduino quadcopter tutorial, and he deserves all the credit for its writing. We simply adapted the wiring for the Mega so that the receiver inputs corresponded to the correct Pin Change Interrupt pins.

With the battery disconnected, use the USB cord to connect your computer to the Arduino, and upload the attached Setup Code. Open your serial monitor to 57600 baud and follow the prompts.

Step 12: Calibrate the ESCs (Uno)

Once again, this code is identical to Joop Brokking's code. All the modifications were made in an effort to integrate the GPS and Arduino and can be found later on, in the description of construction of the more advanced quadcopter.

Upload the attached ESC calibration code. On the serial monitor, write the letter 'r' and hit return. You should begin to see realtime RC controller values listed. Verify that they vary from 1000 to 2000 on the extremes of throttle, roll, pitch, and yaw. Then write 'a' and hit return. Let the gyro calibration go, and then verify that the gyro registers motion of the quad. Now uplug the arduino from the computer, push the throttle all the way up on the controller, and connect the battery. The ESCs should cycle different beep tons (but this may be different depending on the ESC and its firmware). Push the throttle all the way down. The ESCs should emit lower beeps, then fall silent. Unplug the battery.

Optionally, you can at this point use the cones that came with your motor mounting accessory packs to tightly screw on propellors. Then enter the numbers 1 - 4 on the serial monitor to power up motors 1 - 4 respectively, at the lowest power. The program will register the amount of shaking due to imbalance of the props. You can try to remedy this by adding small amounts of scotch tape to one side or the other of the props. We found we could get fine flight without this step, but perhaps slightly less efficiently and more loudly than had we balanced the props.

Step 13: Calibrate ESCs (Mega)

This code is very similar to Brokking's code, however we adapted it (and corresponding wiring) to work with the Mega.

Upload the attached ESC calibration code. On the serial monitor, write the letter 'r' and hit return. You should begin to see realtime RC controller values listed. Verify that they vary from 1000 to 2000 on the extremes of throttle, roll, pitch, and yaw.

Then write 'a' and hit return. Let the gyro calibration go, and then verify that the gyro registers motion of the quad.

Now uplug the arduino from the computer, push the throttle all the way up on the controller, and connect the battery. The ESCs should emit three low beeps followed by a high beep (but this may be different depending on the ESC and its firmware). Push the throttle all the way down. Unplug the battery.

The changes that we made to this code were to switch from using PORTD for the ESC pins to using PORTA and then changing the bytes written to these ports so that we activate the proper pins as shown in the wiring schematic. This change is because the PORTD register pins aren't in the same location on the Mega as they are in the Uno. We haven't been able to fully test this code as we were working with an old off-brand Mega that our school's shop had. This meant that for some reason not all of the PORTA register pins were able to activate the ESCs properly. We also had trouble with using the or equals operator (|=) in some of our test code. We are unsure as to why this was causing problems when writing the bytes to set the ESC pin voltages, so we modified Brooking's code as little as possible. We think that this code is very close to functional, but your mileage may vary.

Step 14: Get Airborne!! (Uno)

And again, this third bit of genius code is the work of Joop Brokking. Alterations to all these three pieces of code are present only in our attempted integration of the GPS data into the Arduino.

With your propellors firmly mounted onto the frame and all components strapped, taped, or otherwise mounted on, load on the flight controller code to your Arduino, then unplug the Arduino from your computer.

Take your quadcopter outside, plug in the battery and turn on your transmitter. Optionally, bring along a laptop connected to your GPS receiving setup as well as your video receiving setup and monitor. Load the transceiver code onto your terrestrial Arduino, open your serial monitor to 9600 baud and watch the GPS data roll in.

Now you are ready to fly. Push throttle down and yaw left to arm the quadcopter, then gently bring up the throttle to hover. Begin by flying low to the ground and over soft surfaces like grass until you become comfortable.

See the imbedded video of us excitedly flying the drone the first time we were able to get the drone and GPS working simultaneously.

Step 15: Get Airborne!! (Mega)

Due to our hangup with the ESC calibration code for the Mega, we were never able to create flight controller code for this board. If you have gotten to this point, then I imagine that you have at least fiddled with the ESC calibration code to make it work for the Mega. Therefore, you will likely have to make similar modifications to the flight controller code as you made in the last step. If our ESC calibration code for the Mega magically works without any other modifications, then there are only a few things you will have to do to the stock code to make it work for this step. You will first need to go through and replace all instances of PORTD with PORTA. Also, don't forget to change DDRD to DDRA. Then, you will need to change all of the bytes being written to the PORTA register so that they activate the proper pins. To do this, use the byte B11000011 to set the pins to high and B00111100 to set the pins to low. Good Luck, and please let us know if you successfully fly using a Mega!

Step 16: How We Got to Where We Currently Are With the Mega Design

This project was an immense learning experience for us as Arduino and electronics hobby beginners. Therefore, we though we would include the saga of everything that we encountered while trying to GPS enable Joop Brokking's code. Because Brokking's code is so thorough and much more complicated than anything that we were writing, we decided to modify it as little as possible. We tried to get the GPS shield to send data to the Arduino and then have the Arduino send that information to us via the HC12 transceiver without modifying the flight code or wiring in any way. After looking at the schematics and wiring of our Arduino Uno to figure out what pins were available, we changed the GPS transceiver code that we were using to work around the existing design. Then we tested it to make sure everything worked. At this point, things seemed promising.

The next step was to integrate the code that we had just modified and tested with Brokking's flight controller. This wasn't too difficult, but we quickly ran into an error. Brokking's flight controller relies on the Arduino Wire and EEPROM libraries while our GPS code was using both the Software Serial library and Arduino GPS library. Because the Wire Library references the Software Serial library, we ran into an error where the code wouldn't compile because there were "multiple definitions for _vector 3_", whatever that means. After looking on Google and digging around in the libraries, we eventually realized that this library conflict made it impossible to use these pieces of code together. So, we went searching for alternatives.

What we figured out is that the only combination of libraries that didn't throw error at us were switching the standard GPS library to neoGPS and then using AltSoftSerial instead of Software Serial. This combination worked, however, AltSoftSerial can only operate with specific pins, which were not available in our design. This is what lead us to using the Mega. Arduino Megas have multiple hardware serial ports, which meant that we could bypass this library conflict by not needing to open software serial ports at all.

However, when we started using the Mega, we quickly realized that the pin configuration was different. Pins on the Uno which have interrupts are different on the Mega. Similarly, the SDA and SCL pins were in different locations. After studying the pin diagrams for each type of Arduino, and refrencing the registers called in the code, we were able to run the flight setup code with only minimal re-wiring and no software changes.

The ESC calibration code is where we started to run into problems. We touched on this briefly before, but basically the code uses pin registers to regulate the pins used to control the ESCs. This makes the code harder to read than using the standard pinMode() function; however, it makes the code run faster and activate pins simultaneously. This is important because the flight code runs in a carefully timed loop. Because of the pin differences between the Arduinos, we decided to use port register A on the Mega. However, in our testing, not all of the pins gave us the same output voltage when told to run high. Some of the pins had an output of around 4.90V and others gave us closer to 4.95V. Apparently the ESC's that we have are somewhat finicky, and so they would only operate properly when we used the pins with the higher voltage. This then forced us to change the bytes we wrote to register A so that we were talking to the correct pins. There is more info about this in the ESC calibration section.

This is about as far as we got in this part of the project. When we went to test this modified ESC calibration code, something shorted and we lost communication with our Arduino. We were extremely puzzled by this because we hadn't changed any of the wiring. This forced us to step back and realize that we only had a couple of days to get a flying drone after weeks of trying to fit our incompatible pieces together. This is why we backtracked and created the simpler project with the Uno. However, we still think that our approach is close to working with the Mega with little more time.

Our goal is that this explanation of the hurdles we encountered is helpful to you if you are working on modifying Brokking's code. We also never got the chance to try coding any autonomous control features based on the GPS. This is something you will need to figure out after creating a working drone with a Mega. However, from some preliminary Google research it looks like implementing a Kalman filter may be the most stable and accurate way to determine position in flight. We suggest that you research a little about how this algorithm optimizes state estimations. Other than that, good luck and let us know if you get further than we were able to!