arduino based Drone Quadricopter
It’s a tiny quadrotor helicopter!
Update Feb 25 2012: Warning, I may have discovered a bug inside the CadSoft EAGLE 6.1.0 software that may make the PCB look slightly different. My design files are meant for 5.11 so use that instead. You have been warned.
arduino based Drone Quadricopter
Main Features:
- X mode flying
- MPU-6000 gyro & accelerometer sensor for flight stabilization
- USB battery recharging on the transmitter, the copter plugs into the transmitter to recharge
- When the copter plugs into the transmitter, the user can synchronize to a random radio frequency
- Controlled using a Wii Classic Controller, which plugs into the transmitter
- Running a modified MultiWii firmware, which is open source, written with Arduino and Processing
Dimension Specs:
- Square center body is 1.5″ by 1.5″
- Propellers are about 45mm in diameter
- Diagonal motor to motor distance is 110mm
- Motors are supposedly “X-Twin” spare motors, they come with the propellers
Electrical Specs:
- Flight battery is a single Li-poly cell, 3.7V, 350mAH, 20C
- Controller battery is a single Li-ion cell, 3.7V, 1000mAH
- Uses ATmega128RFA1 microcontroller for both copter and transmitter
- This particular ATmega has a built-in 2.4GHz transceiver, 16 possible channels, 250kbit/s or 2mbit/s max depending on the standard being used.
Design Highlights:
- The “arms” and “body” are connected by locking slots, making them easy to build and repair
- Motors slide right into the arm
- Two layer 1.6mm thick FR4 PCB used (this is the default for a lot of PCB manufactures), the components are all on a single side (easy to assemble)
- All open source project, schematics + PCB + code all available. Heavy use of Arduino and Zigduino involved.
This is actually the 2nd such tiny quadrotor helicopter I’ve built. The first one worked well and I’m extremely proud of it, but it did have several flaws, enough flaws to justify a remake. This Instructable documents “version 2”, but you may see pictures of “version 1” in some places.
Step 0 Come up with puntastic name
Pico… Copter… You get the idea. This project was originally named “PalmQuad” since it’s small enough to fit in your palm, so if you might see some mention of this name in the code or pictures.
I originally finished building “version 1” in November, and wrote the Instructable in November. Then I went on vacation for a few weeks, and also school just started. Now it is February and I just finished “version 2”, but since I’ve already written the majority of the Instructable, I have some bits of “version 1” text that I’ll just cross out like this, and then update it with the changes in “version 2”.
All project files are available to download in this instructable “step”. It contains files for “version 1” only for reference purposes, please only use “version 2” files. Although I really recommend you only take my concepts and design everything from scratch yourself instead, just so there’s absolutely no mysteries in your project.
If you are wondering about the lack of a flight video, see step 6 for an explanation.
Oh and I noticed that “AdBlock” stops Instructables from showing you all my pictures, so please turn it off.
http://www.instructables.com/files/orig/FIK/7WVZ/GYQES7LN/FIK7WVZGYQES7LN.zip
arduino based Drone Quadricopter
Step 1: Version 1’s Build Log
This instructable will focus on building version 2 due to the flaws in version 1, but I have a lot of pictures taken during the construction of version 1, I’m putting them all in this step. I think it’s a good idea to show people my other techniques so everybody can learn from both the benefits and mistakes.
Version 1 is soldered using the reflow soldering method (see my other instructable: http://www.instructables.com/id/Hack-a-Toaster-Oven-for-Reflow-Soldering/), version 2 was not due to time constraints and l didn’t bring my oven to school. I managed to solder the QFN chips with a heatgun.
In version 1, the flyback diode for each motor was mounted onto the arms, but in version 2, the flyback diodes are in the main quadcopter body PCB instead.
In version 1, the propellers required a drilling before they fit onto the motor. The motors in version 2 comes with the propellers pre-attached so the drilling is no longer necessary. However, please read step 6 to see why you should use the motors from version 1 instead.
Step 2: Design
I’m not a stranger to quadrotor helicopters, see http://www.instructables.com/id/RC-Quadrotor-Helicopter/ and learn about the basics of quadcopters.
I decided on a X mode frame instead of + mode frame mainly because I had a general idea of how the PCB was going to be laid out. The sensor axis and motor spin directions are shown in the image above.
When designing something, it’s nice to have some references to compare against. To get a sense of how big I should make Picopter, how heavy it can be, what sized motor I should use, and what sized propeller I should use, I studied the Crazyflie project. From it, I knew I could buy spare motors for the Walkera X-Wing and spare propellers for the Silverlit X-Twin. Actually, when I started to work on “version 2”, I was not able to buy any more Walkera X-Wing motors, so I got X-Twin motors instead, which are smaller but come with a housing and propellers already attached.
The rough dimensions are based mainly on one of the rules of thumb of quadcopter design, please see the diagram.
I know I need sensors to stabilize the quadcopter. I’ve already used the ITG-3200 and BMA180 combination before, and I knew it would be compatible with the MultiWii code or AeroQuad code that I can use. I also knew that InvenSense is coming out with the MPU-60×0 which is a single chip with both gyroscope and accelerometer and it is footprint-compatible with the ITG-3200.
“Version 2” was designed after the MPU-60×0 was available, thus the footprint for the BMA180 was removed.
For human remote control, traditionally, people just buy hobby RC radios, but this isn’t an option because the receiver module would be too heavy.
I knew I wanted a microcontroller with a built-in radio. This means better performance since there will not be any communication between a dedicated radio chip and the microcontroller. It also saves money by saving PCB space and part count. I knew I had a few options, such as the ATmega128RFA1, or ez430, or maybe the Wixel. I generally prefer AVRs and I already knew what software I can easily port to the ATmega128RFA1, so it was chosen.
For the control input, since I’m using my own microcontroller. I could choose to build a gamepad or joystick from scratch but that would have been more time consuming and difficult. I can also use an existing gamepad. I know I need two joysticks minimum. I have plenty of experience with PlayStation and Wii controllers already. I know I can connect a Wii Classic Controller to my circuit really easily because I know I can design the PCB such that it connects directly to the controller. If I picked the PlayStation controller, I would need to either dissect the cable or buy a special connector.
Step 3: Circuit Design
The software I used is CadSoft EAGLE 5.11.0 which is a schematic and PCB editor, EAGLE provides a free version for download so anybody can use it. Right now they are actually distributing version 6 but my files are for 5.11, just so you are aware. A lot of custom components had to be created within EAGLE, and if you need them for other projects, EAGLE should have a script called “export library”, so use that to extract my custom components if you ever need to.
The quadcopter needs to be light so we can only use a small battery. The battery must be rechargable and can provide enough current for the four motors. So a Li-poly cell is selected. Knowing the rough size I’m aiming for already, I went to Hobby King and picked out a small cell that is rated 350mAH and 20C.
Now I know I’m working with 3.7 volts. The ATmega128RFA1 is designed to be battery powered directly, but my sensors are not. I need 3.3 volts, so I need a 3.3V voltage regulator. Since the input voltage will be 3.7 volts, this regulator needs to be a low-dropout regulator.
A really basic power supply circuit is designed, inspired by example schematics from various datasheets. Higher voltage goes in, regulated voltage comes out…
Lithium batteries should not be over-discharged so battery monitoring is required. The ATmega128RFA1 has a battery monitor feature so that’s taken care of already, no extra components required for battery monitoring.
I keep a bunch of MCP73831T lithium battery charging ICs around for any quick designs that require a lithium battery. They are tiny and easy to use. The battery charging circuit is designed using the examples provided in the datasheet of the MCP73831T.
The motor control circuitry is simple. The N-channel MOSFET acts as a switch (low side, which is friendlier for microcontroller controls). There are pull down resistors on the gate to prevent accidental activation, and series resistors to prevent the gate capacitance to draw too much current from the microcontroller during switching. There is a “flywheel” diode for each motor since they are inductive loads, so the diode is a fast switching Schottky diode that dissipates any stored reverse voltage during switching. The MOSFET itself has to be able to handle the amount of current required but also needs to be small, I chose one that can handle 1.15A and in SOT23 packaging.
The brains of the circuit are the two ATmega128RFA1 microcontrollers. They need a 16 MHz clock source for two main reasons: the radio transceiver requires it, MultiWii and AeroQuad code are designed for it. So there’s a 16 MHz crystal for each microcontroller, and load capacitors for the crystals. I also know I need at least MOSI, MISO, SCK, and RESET signals to be connected to an AVR programmer later so I can program the microcontroller. The serial port signals are also connected so I can debug and use the computer’s graphical configuration and monitoring utilities. The power pins are properly decoupled with capacitors. The radio circuitry consists of a BALUN to match the 100 ohm balanced output of the microcontroller to a unbalanced 50 ohm impedance antenna. The circuit is mainly derived from the datasheet’s example circuit, and Zigduino’s schematic.
The PWM pins are connected to the motor control circuits so the microcontroller can control the speed of the motors. I added some LEDs. The sensors and Wii Classic Controller all connect to an I2C bus. (in “version 1”, I omitted pull-up resistors on the I2C bus, apparently the ATmega128RFA1’s internal pull-up resistors didn’t work, so “version 2” has these resistors added).
The sensor circuitry is also derived from their perspective datasheets, and looking at SparkFun’s breakout board designs (because AeroQuad uses those breakout boards).
In “version 2”, I improved the transmitter design by adding a FT232R chip, this added a USB virtual serial port, which works with the MultiWii and AeroQuad graphical utilities.
Step 4: PCB Design
Most components are 0603 sized, which I can assemble by hand. I could also use 0402 sized components but I don’t think I really need to since space isn’t actually running out yet.
I decided on a X mode design, and I thought a 1.5 inch by 1.5 inch square main PCB would be a suitable size. This is because the size of the propellers dictated the motor-to-motor distance, and I thought this main PCB size would be big enough for the components and be small enough to not restrict airflow.
I had the option of designing the “arms” of the quadcopter into the main PCB directly but I didn’t think that would be strong enough without making the arms too wide. If they are too wide, then they are not aerodynamic. So I decided the make the arms as separate pieces which would attach to the corners of the “body” PCB using slots. Solder is used to make the connection solid, and also conduct the electrical current for the motors.
The motor arms are milled by the PCB manufacture, so I had to provide the outline. The motors had to be purchased first, then I measured the dimensions of the motors myself so I can design the arms correctly.
The motor control circuitry are placed near the corners, this is just a minor detail and made routing easier for me.
The antenna for the transmitter will be a RP-SMA connector on the edge of the PCB, which will be connected to a 2.4 GHz duck antenna, just like the ones on Wifi routers. I don’t care about weight on the transmitter since it’s not flying, so I might as well get a good performing antenna.
The antenna for the quadcopter itself is a lightweight and tiny chip antenna, placed near the edge and without any copper planes under and around it.
The radio circuit has to be really close to the microcontroller. 1.6 mm thick FR4 PCB is not the greatest for making traces with good impedance (we want 50 ohms), but the power lost from impedance mismatch is negligible if the trace length is much shorter than 1/4th of the signal’s wave length. I still tried to make sure the balanced traces are equal length and thick to match the impedance better.
When you design capacitors into your schematic, remember that they need to be physically close to the component they are meant for. The capacitors for the radio circuitry are also designed for high frequency with low ESR.
The crystal also needs to be close to the microcontroller.
There is a small power switch for the transmitter, and a shunt block jumper acts as a switch for the quadcopter.
The battery connectors are polarized JST connectors so you can’t plug them in backwards.
The connector for the Wii Classic Controller is designed right into the PCB. 1.6 mm thick PCB is perfect for this job.
The reason why I designed the transmitter PCB and quadcopter PCB into one solid piece is because I thought it’ll be easier and cheaper to assemble. This turned out to be a horrible idea. “Version 2” was designed as two separate pieces.
Some mounting holes are always nice. #4-40 is a good sized screw for this job. Keep the area clear around the holes because you’ll need to put nuts there. I planned on making a plastic case out of sheets of plastic, which will attach to these holes.
Once the design is finished, use EAGLE’s CAM processor to run the “.cam” file as a job, which should generate Gerber files that you can send to a PCB manufacture. Remember to double check your Gerber files using a Gerber file preview tool. Also print out 1:1 scale copies of your design so you can check the footprints and dimensions. Make sure you pay attention to the text size as well.
I wanted to do circuit assembly using a solder paste stencil and reflow soldering so I also have to pay attention to the solder paste layer in my design. “Version 1” was completely assembled using a solder paste stencil and reflow soldering oven, “version 2” was assembled using a heat gun and traditional soldering iron (no time to get another stencil made).
Step 5: Electronics Assembly
Here’s a bill-of-materials for the quadcopter:
Qty | Sch Ref | Name | Value | Rating | Package | Mfg | Mfg Part# |
---|---|---|---|---|---|---|---|
1 | Y1 | Antenna, Chip | Antenna Factor | ANT-2.45-CHP-T | |||
1 | B1 | BALUN | 2.4 GHz, 100 ohm balanced to 50 ohm unbalanced | 0805 | Johanson | 2450BL15B100E | |
1 | BAT | Battery Connector | JST-PH | Vertical | JST | B2B-PH-K-S(LF)(SN) | |
1 | Battery Wire | JST-PH | SparkFun | PRT-08670 | |||
2 | C11, C12 | Cap, Ceramic | 22p | 6V or greater, +/- 5%, high frequency | 0603 | Kemet | CBR06C220JAGAC |
2 | C14, C15 | Cap, Ceramic | 10p | 6V or greater, +/- 10% | 0603 | Kemet | CBR06C100JAGAC |
1 | C13 | Cap, Ceramic | 0.47p | 6V or greater, +/- 5%, high frequency | 0603 | TDK | C1608C0G1H0R5C |
1 | C2 | Cap, Ceramic | 470p | 6V or greater, +/- 10% | 0603 | TDK | C1608X7R1H471K |
2 | C9, C10 | Cap, Ceramic | 1u | 6V or greater, +/- 10% | 0603 | Yageo | CC0603ZRY5V7BB105 |
1 | C16 | Cap, Ceramic | 2n2 | 6V or greater, +/- 10% | 0603 | Kemet | C0603C222K5RACTU |
1 | C18 | Cap, Ceramic | 10n | 6V or greater, +/- 10% | 0603 | Yageo | CC0603KRX7R8BB103 |
7 | C4, C5, C6, C7, C8, C17, C19 | Cap, Ceramic | 100n | 6V or greater, +/- 10% | 0603 | Yageo | CC0603ZRY5V9BB104 |
1 | C1 | Cap, Tantalum | 150u | 6V or greater, +/- 10% | 1210 | Nichicon | F930J157KBA |
1 | C3 | Cap, Tantalum | 10u | 6V or greater, +/- 10% | 1210 | AVX | TAJB106M006RNJ |
1 | JP1 | Female Header | 2×5 | 0.1″ pitch | Sullins Connector Solutions | PPPC052LFBN-RC | |
1 | Q1 | Crystal | 16MHz | +/- 10PPM, 10pF | 5.00mm x 3.20mm | Abracon | ABM3B-16.000MHZ-10-1-U-T |
4 | D1, D2, D3, D4 | Diode, Schottky | MINIMELF, SOD-123, DO-214AC | Micro Commercial | MBR0540 | ||
1 | U2 | IMU | MPU-60×0 | InvenSens | MPU-6050 | ||
1 | IC1 | LDO V-Reg | 3.3V | 250mA or greater | SOT23-5 | Microchip | MCP1824T-3302E/OT |
1 | LED1 | LED | OSRAM | LSG T676-P7Q7-1-0+N7P7-24-0-20-R18-ZB | |||
1 | BAT | Li-polymer Battery | 350mAH | 20C | Zippy | Z350S20C | |
1 | SW | Male Header | 2×1 | 0.1″ pitch | TE Connectivity | 3-644456-2 | |
1 | U1 | Microcontroller | ATmega128RFA1 | QFN | Atmel | ATMEGA128RFA1-ZU | |
4 | Q2, Q3, Q4, Q5 | MOSFET | N-Channel | 1A, low VGS | SOT23-3 | Vishay | SI2318DS-T1-E3 or SI2316BDS-T1-GE3 |
4 | Motor | Walkera X-Wing Motor | |||||
4 | Propeller | Silverlit X-Twin Propeller | |||||
4 | R2, R4, R6, R8 | Resistor, Chip | 220R | 0.1W or greater, +/- 10% | 0603 | Panasonic | ERJ-3GEYJ221V |
5 | R1, R3, R5, R7, R14 | Resistor, Chip | 10K | 0.1W or greater, +/- 10% | 0603 | Yageo | RC0603JR-0710KL |
2 | R9, R10 | Resistor, Chip | 1K | 0.1W or greater, +/- 10% | 0603 | Yageo | RC0603JR-071KL |
2 | R12, R13 | Resistor, Chip | 4K7 | 0.1W or greater, +/- 10% | 0603 | Yageo | RC0603JR-074K7L |
1 | R11 | Resistor, Chip | 2K | 0.1W or greater, +/- 10% | 0603 | Yageo | RC0603JR-072KL |
1 | SW | Shunt Block | 2×1 | Sullins Connector Solutions | QPC02SXGN-RC |
For the transmitter:
Qty | Sch Ref | Name | Value | Rating | Package | Mfg | Mfg Part# |
---|---|---|---|---|---|---|---|
1 | B1 | BALUN | 2.4 GHz, 100 ohm balanced to 50 ohm unbalanced | 0805 | Johanson | 2450BL15B100E | |
1 | BAT | Battery Connector | JST-PH | 90 Deg | JST | S2B-PH-K-S(LF)(SN) | |
2 | C16, C17 | Cap, Ceramic | 22p | 6V or greater, +/- 5%, high frequency | 0603 | Kemet | CBR06C220JAGAC |
2 | C18, C19 | Cap, Ceramic | 10p | 6V or greater, +/- 10% | 0603 | Kemet | CBR06C100JAGAC |
1 | C2 | Cap, Ceramic | 470p | 6V or greater, +/- 10% | 0603 | TDK | C1608X7R1H471K |
2 | C14, C15 | Cap, Ceramic | 1u | 6V or greater, +/- 10% | 0603 | Yageo | CC0603ZRY5V7BB105 |
7 | C7, C8, C9, C10, C11, C12, C13 | Cap, Ceramic | 100n | 6V or greater, +/- 10% | 0603 | Yageo | CC0603ZRY5V9BB104 |
1 | C3 | Cap, Tantalum | 150u | 6V or greater, +/- 10% | 1210 | Nichicon | F930J157KBA |
1 | C1 | Cap, Tantalum | 10u | 6V or greater, +/- 10% | 1210 | AVX | TAJB106M006RNJ |
3 | C4, C5, C6 | Cap, Tantalum | 4u7 | 6V or greater, +/- 10% | 1210 | AVX | TAJB475K020RNJ |
1 | Q1 | Crystal | 16MHz | +/- 10PPM, 10pF | 5.00mm x 3.20mm | Abracon | ABM3B-16.000MHZ-10-1-U-T |
1 | JP1 | Male Header | 2×5 | 0.1″ pitch | FCI | 67997-410HLF | |
1 | IC1 | LDO V-Reg | 3.3V | 250mA or greater | SOT23-5 | Microchip | MCP1824T-3302E/OT |
2 | LED1, LED2 | LED | OSRAM | LSG T676-P7Q7-1-0+N7P7-24-0-20-R18-ZB | |||
2 | IC2, IC3 | Li Battery Charger IC | Microchip | MCP73831T-2ACI/OT | |||
1 | BAT | Li-polymer Battery | 1000mAH | Seeed Studio | POW101C1M | ||
1 | U1 | Microcontroller | ATmega128RFA1 | QFN | Atmel | ATMEGA128RFA1-ZU | |
4 | R1, R2, R7, R8 | Resistor, Chip | 1K | 0.1W or greater, +/- 10% | 0603 | Yageo | RC0603JR-071KL |
5 | R3, R4, R5, R6, R9 | Resistor, Chip | 4K7 | 0.1W or greater, +/- 10% | 0603 | Yageo | RC0603JR-074K7L |
1 | Y1 | RP-SMA Antenna | RP-SMA | Roving Networks | RN-SMA4-RP | ||
1 | Y1 | RP-SMA Connector | Linx | CONREVSMA003.062 | |||
1 | SPDT Switch | C&K | OS102011MA1QS1 | ||||
1 | USB | USB Connector | Mini-B | On Shore | USB-M26FTR | ||
1 | U2 | USB-to-Serial | FT232RL | SOIC | FTDI | FT232RL | |
1 | Wiimote Extension | Wii Classic Controller | Nintendo |
A lot of the above components can be substituted, but you better know what you are doing. Most of the time, I just filter out the parameters I need, and pick the cheapest part.
I used my reflow soldering toaster oven to do the soldering, see http://www.instructables.com/id/Hack-a-Toaster-Oven-for-Reflow-Soldering/ , follow that to learn how I solder the components. Some of them are QFN chips which are very hard to solder with a traditional soldering iron.
“Version 1” was assembled with the reflow method. “Version 2” was soldered by placing a tiny amount of solder paste on the pads, then placing the component over the pads, then heating it with a heat gun. After that, flux is applied and all joints are “neatened up” using a soldering iron.
Feel free to actually have stencils made from my PCB files if you want to try the complete reflow soldering method, see my other Instructable on reflow soldering to learn how.
When soldering JST connectors to your batteries, making sure you watch your polarities. I used sticky-back velcro strips to stick the battery onto the PCB.
Use flux cleaner to clean up the circuit after you are done.
SMD soldering is easy! See my demonstration video
(this video is mostly a joke, in case you don’t understand)
Step 6: Motors and Propellers
The arms are designed so the X-Twin motors slide right in snugly. So slide them in and glue them down with super glue.
I’ll be honest, the Silverlit X-Twin motors are not powerful enough to lift-off. So you should use Walkera X-Wing motors combined with Silverlit X-Twin propellers instead.
(note: this is why I was not able to film the quadcopter flying, I am very sorry about that. I absolutely assure you that Walkera X-Wing motors does have more than enough power. However, one of the motors on my “version 1” quadcopter broke, so I was not able to “transplant” the motor to “version 2”. I am ordering another set of motors, but I am out of time, out of money, and midterm exams are next week)
Note added Feb 23 2012: It’ll be a month before the Walkera X-Wing motors will be available for me to buy again.
The PCB arm design is provided, to assemble it, use bare wire to wrap a cage around each motor to secure it to the arm. This should be done as tightly as possible, it helps if you use a tool (like a vice, or ask a friend to help) to keep tension on the wire.
To make sure the motors spin in the correct direction, follow my diagram when wiring the motors. The counter clockwise motors have red-blue wires, and the clockwise motors have white-black wires. Solder the wires to the arm like I did.
And double check that the direction that the air being blown is downwards. This step is obvious.
Attach the arms to the main quadcopter body PCB and solder the joints.
The shaft diameter of the Walkera X-Wing motors is almost exactly 1.01mm, so you need to get a drill bit that is slightly smaller, and drill into the Silverlit X-Twin propellers so that they will fit on the shaft.
Pictures of the Silverlit X-Twin motors are also included just for historical purposes.
Side note: the free spinning average current draw of the Silverlit X-Twin motors is about 0.5A each
Step 7: Transmitter Case
I made a quick case for the transmitter using 2mm thick clear polycarbonate (you can buy this at Home Depot’s window section, hence why I always keep some in stock at home).
It’s cut into the same shape as the PCB using a band saw. Holes are drilled in the matching locations for #4-40 screws.
Notice that in the pictures, I’ve cut both pieces with a trapezoid at the end to protect the connector. Also for one of the pieces, there’s a trapezoid near the Wiimote Extension connector to prevent plugging in the Wii Classic Controller up-side-down.
I got some #4-40 screws and nuts, use them to stack and secure the plastic pieces like I did. Use washers to space things apart so the Wiimote extension cable fits.
Now you can grab it with your hand without worrying about breaking anything on the circuit, but it’s not water or debris proof.
Note: version 1 required 3 pieces of plastic, but version 2 requires 2 pieces. This is because the larger PCB for version 2 allows the battery to fit in without getting in the way of the Wiimote extension connector.
Also another mistake in version 1 is that the aluminium capacitors were too tall and did not allow the plastic sheets to fit. Version 2 corrected this by using tantalum capacitors.
Step 8: Testing
When I attempt a project like this, I can’t just go straight into loading in the final code in and hope it works. There’s a lot of hardware testing involved first. I provided you with the finished firmware so everything should already work. But if something doesn’t work, go through checks:
- All voltages are correct, measure using a voltmeter
- Battery charger works, the LED should light up if the battery is charging
- Bootloader works
- Serial port works, do a “Hello World” test
- LEDs work, blink them
- Radio transceiver, I verified this using a loop-back test
- Motor control, tested using a tiny bit of code that output PWM
- Sensors work, print their data to serial terminal
A lot of the software testing was done with two Zigduinos, which is an Arduino derivative that uses the ATmega128RFA1. It is convenient to use for testing because of the supporting hardware (built in FT232RL, and 5V protection circuitry). Mainly I coded the radio functions on this platform, while using a logic analyzer to judge various timings. This was key to debugging by telling me if an event that I expected to happen actually occured at the appropriate time, such as the RX or TX begin or end interrupts. If I suspected something wrong with the radio my own PCB, then I would test the same code on the Zigduino in this fashion.
Step 9: Programming
Please understand how to work with AVR microcontrollers first. You should know how to compile a project from command line and how to use AVRDUDE. Also keep in mind I am using Arduino 0023, do not attempt to use Arduino 1.0 because my instructions here won’t work and my code won’t compile without some changes.
Although I can use an AVR programmer to load code into the microcontrollers, the way I designed the PCB makes it slightly inconvenient. Using a serial port bootloader is easier for this job. So I will use an AVR programmer just once to get the bootloader flashed into the microcontroller first, and use the bootloader the rest of the time.
The AVR programmer must support 3.3V circuits. My USBtinyISP is capable of this, but I needed to supply the 3.3V into it in order for it to know to use 3.3V.
Although the transmitter uses a 2X5 male header connector, YOU MUST NOT PLUG IN THE ISP TO IT DIRECTLY, because the pin mapping does not match. Connect the ISP to this header using wires instead, while following the pin labels carefully. (The adapter I used is from SparkFun, but you can make your own really easily)
First thing to do is to program the fuse bits of the transmitter microcontroller, which tells it to use the 16 MHz crystal, to run the bootloader on reset, and how big the bootloader is.
- lfuse = 0xF7
- hfuse = 0xD8
The bootloader is derived from the Arduino bootloader, I’m using a modified version of the Zigduino port of the Arduino bootloader. Flash the bootloader atmegaboot_picopter.hex file into the transmitter microcontroller.
Note: You may encounter a verification error while trying to flash the bootloader, this appears to be caused by a bug in AVRDUDE where nothing is read back (I was unable to even obtain a basic memory dump) for the ATmega128RFA1 (I don’t know if this applies to any other chip). Ignore this error unless you are sure that the bootloader is malfunctioning.
At this point, make sure you’ve plugged in the transmitter circuit to your computer via USB, and have powered it on. Install the drivers if you need to. Remember the name of the serial port that it shows up as.
The bootloader is activated by placing a jumper between GND and SER<, and then powering on the transmitter circuit. Once activated, the red LED should blink 3 times and green LED will stay on. The green LED will also indicate busy status by blinking really fast (technically it is toggling once per byte).
Before you open up Arduino, you need to add the following entries into Arduino’s “board.txt”:
picopter_station.name=picopter_station
picopter_station.upload.protocol=stk500v1
picopter_station.upload.maximum_size=126976
picopter_station.upload.speed=38400
picopter_station.bootloader.low_fuses=0xF7
picopter_station.bootloader.high_fuses=0xD8
picopter_station.bootloader.extended_fuses=0xF4
picopter_station.bootloader.path=picopter_boot
picopter_station.bootloader.file=atmegaboot_picopter.hex
picopter_station.bootloader.unlock_bits=0x3F
picopter_station.bootloader.lock_bits=0x0F
picopter_station.build.mcu=atmega128rfa1
picopter_station.build.f_cpu=16000000L
picopter_station.build.core=picopter_core
picopter_flier.name=picopter_flier
picopter_flier.upload.protocol=stk500v1
picopter_flier.upload.maximum_size=126976
picopter_flier.upload.speed=115200
picopter_flier.bootloader.low_fuses=0xF7
picopter_flier.bootloader.high_fuses=0xD9
picopter_flier.bootloader.extended_fuses=0xF4
picopter_flier.bootloader.unlock_bits=0x3F
picopter_flier.bootloader.lock_bits=0x0F
picopter_flier.build.mcu=atmega128rfa1
picopter_flier.build.f_cpu=16000000L
picopter_flier.build.core=picopter_core
Copy the core files inside “picopter_core” into where you install Arduino cores. Copy the bootloader files inside “picopter_boot” into where you install Arduino bootloaders. Copy the libraries “PicopterWiiClassicCtrler” and “PicopterRadio” into where you install Arduino libraries. Copy the sketches “PicopterTransmitter” and “Multiwii_Picopter” into your Arduino sketch folder.
Also since Arduino is built using an outdated version of AVR GCC, it will not support ATmega128RFA1 properly, I had to overwrite the contents of the folder called “tools” with the contents from an up-to-date version of AVR GCC (obtained from MHV AVR Tools).
Open Arduino, open the “PicopterTransmitter” sketch, select the board to be “picopter_station”, and select the right serial port. Activate the bootloader on the transmitter, then compile and upload the sketch.
The transmitter firmware has a neat feature: if you do not connect the Wii Classic Controller when you turn it on, it will go into ISP mode (indicated by really fast alternating red-green LED flashing, also flashes when busy), where it becomes another AVR programmer (protocol is stk500v1, baud rate is 115200). So now, connect the quadcopter circuit to the transmitter circuit. Using the command line and AVRDUDE, set the fuses of the quadcopter microcontroller to be:
- lfuse = 0xF7
- hfuse = 0xD9
Open the “MultiWii_Picopter” sketch, select the board to be “picopter_flier”, and compile & upload the sketch. You have just programmed the quadcopter firmware using the transmitter.
Note: You might get a verification error while trying to upload firmware to the quadcopter using the Arduino IDE, if you do, then use AVRDUDE in command line to force a chip erase (using the “-e” option) and then try again. This is because Arduino forces the “-D” option while uploading.
Step 10: Firmware
The core files are derived from Zigduino’s core files, which are mostly just minor additions to the original Arduino core files for use with the ATmega128RFA1. I made some modifications regarding the activation of the 2nd UART on the ATmega128RFA1.
During the planning stages of this project, I purchased two Zigduinos as a test platform for code involving the radio transceivers of the ATmega128RFA1. I decided I needed a high performance radio code, with maximal data rate, minimal latency, and minimal overhead. I chose to dig into uracoli, which is a free and open source library that supports many radio transceivers including the ATmega128RFA1, and developed the ZigduinoRadio library for Arduino. Then from there, I increased the performance even further and developed the PicopterRadio library specifically for this project.
PicopterRadio is designed to quickly replace traditional RC signal inputs. Instead of having a microcontroller read pulse widths using pins, PicopterRadio delivers data that represents what would have been measured directly in a digital fashion. This makes it faster and more accurate.
The ATmega128RFA1 also has a built-in random number generator (not psuedo random, this is true random good enough for cryptography) which I used to allow a random frequency to be generated and used by both the quadcopter and transmitter. The user connects these two pieces together and press a button, a frequency will be randomly selected and both units will switch to the new random frequency.
There are 16 available frequencies possible on the ATmega128RFA1 but I found some of them to be unreliable, at least in my house (with Wifi and cordless phones everywhere). So I’ve limited the number down to the few that I know works.
PicopterWiiClassicCtrler is a library I wrote to read the Wii Classic Controller using twi.c and twi.h (originally from the “Wire” Arduino library). It features detecting disconnections and automatic calibration.
My other quadcopter used AeroQuad flight software, which is free and open source, written with Arduino. I tried to port that code to the ATmega128RFA1. When I finished and decided to test it using the configurator, I had some wonky results. Tried fixing it, didn’t have much luck. I then tried to port over MultiWii’s code, which is also free and open source and Arduino, except it’s more C style, instead of AeroQuad’s C++ OOP style. The port is surprisingly successful. The GUI utility for MultiWii is written in Processing.org so it’s just Java. while AeroQuads GUI utility is a huge LabView application. MultiWii is superiour in terms of how the software is written, but I heard AeroQuad’s code might be better in terms of how stable the quadcopter flies But in the end, I’m using MultiWii because my port is working.
I customized MultiWii’s code, mainly to add in my libraries, and to change some functions to using buttons instead of joystick action combinations. The orientation of the sensors does not match what the code expected, so I had to make a small edit that changed the orientation. The PWM output’s range was not designed for MOSFET controlled DC motors so I had to make a small math adjustment for the PWM duty cycle.
“Version 2” added a MPU-6000, which is relatively new on the market, I had to add in some custom code for this sensor myself, where as the ITG-3200 and BMA180 was already supported in the original MultiWii code. The MPU-60×0 chip is very similar to the ITG-3200, so most of the initialization parameters stayed the same.
I also cut out a lot of irrelevant code so it’s easier for me to read. MultiWii supports a lot of difference sensors and input methods, I deleted the stuff that is not what I am using.
Because MultiWii is written in a much more efficient way than AeroQuad, I was able to make the quadcopter wirelessly configurable by redirecting serial port data to the radio instead. So the user can plug in the transmitter to the computer instead of plugging in the quadcopter itself.
The bootloader is adapted from the original Arduino bootloader. The “ISP mode” is implemented by modifying the “ArduinoISP” sketch.
Step 11: Tuning
Tuning the flight characteristics is done using MultiWii’s GUI. The transmitter is connected to the FTDI USB to serial converter using the adapter I mentioned earlier. “Version 2” has the FT232R chip (by FTDI) built into the circuit so just plug the transmitter’s USB port into a computer.
To run the GUI, use Processing (my version is 1.5.1) to open “MultiWiiConf_Picopter” and run it. You probably need to install a library called “controlP5” first, so go download that and install it.
You can also read http://www.instructables.com/id/RC-Quadrotor-Helicopter/step28 but note that the configurator is completely different and the numbers have different units, however, the same principles apply
I turned up the P values and made the roll and pitch joysticks less sensitive. You’ll need to fool around a bit with this to suit your own needs. Turn up the yaw P value a lot because the propellers are extremely lightweight.
Run the calibration of the accelerometers on a flat surface. You can also press the “X” button on the controller to perform calibration. The LEDs will blink when you do this.
Fool around with the sensor graph to make sure your sensor orientation is correct.
Check that the motor output makes sense by flying it while holding it in your hand. The quadcopter should try to resist you physically rotating it, and respond to joystick commands correctly. (Note that testing this way is quite dangerous if it was a larger quadcopter, but this one is tiny, the propeller can probably only make small scratches, however, wear safety goggles!)
If anything oscillates, you probably have a P or I constant set too high. Turning down P constant or I constant can fix this, or turn up the D constant.
Step 12: Flying
The shunt block acts as a power switch for the quadcopter, insert the block to turn it on.
If you are using my source code, then follow the diagram to see what buttons do what.
There really isn’t anything else to say. Have fun flying.
LEDs will blink repeatedly forever if a catastrophic error occurs in the code, or if battery is too low. Turn everything off and recharge the battery by plugging in the USB cable. The quadcopter plugs into the transmitter to recharge (the USB cable must be in during this).
If you think the quadcopter can’t receive data from the transmitter, plug the quadcopter into the transmitter and press the sync button on the controller. The LEDs should blink on both circuits and the radio frequency should have changed to another one, hopefully one that works.
Here’s a table of buttons and their function:
Bit Idx | Button | Function |
10 | Plus (+) | Arm Quadcopter (Turn On) |
12 | Minus (-) | Disarm Quadcopter (Turn Off) |
3 | X | Recalibrate Sensors |
9 | Right Top Trigger (R) | Turn Off Accelerometer (Acrobatic Mode) |
2 | Right Bottom Trigger (ZR) | Turn On Accelerometer (Stable Mode) |
4 | A | Synchronize RF Channel |
5 | Y | Recalibrate Joysticks |
7 | Left Bottom Trigger (ZL) | Hold to Trim Accelerometer |
0 14 1 15 |
D-Pad | Trim Accelerometer |
Step 13: Final Thoughts
Final Thoughts, and all my mistakes
The new MPU-6000 features “Digital Motion Processing” which basically means my AVR microcontroller would not need to perform as much flight calculations. The MPU-60×0 chip itself contains some sort of microprocessor internally and it executes code (that is bootloaded on power-on) that does this calculation for me in parallel. This code is provided by InvenSense (as far as I know) in binary form. Right now, I’m not actually using the DMP, utilizing this DMP is my next step. Hopefully it performs well enough when I’m done. But note that the current code only uses the raw data from the sensors directly without any DMP processing.
I would not design the PCB as one piece again (version 1). It makes assembly only slightly faster. I originally wanted them to snap apart, but that turned out to be a bad idea because of the delicate sensor chips. Band-sawing them apart makes a lot of dust. It’s not worth the money I saved in the end. So cut the PCB apart before you solder!
I put the USB connector too close to the left in “version 1”, I didn’t realize it would be in the motors way. “Version 2” fixed this
The electrolytic capacitor on the transmitter PCB was slightly too tall in “version 1”, this is fixed in “version 2”.
I assembled all the motor-arm assemblies identically in “version 1”. This is actually a mistake since this made the quadcopter asymmetrical, causing it to want to yaw. You should assemble them in a fashion such that the quadcopter is still symmetrical once the arms have been attached.
To correct for the yawing, I simply rotated some of the motors to blow air in the opposite direction.
In “version 1”, the connector outline for the Wii Classic Controller was about 1 or 2 mm too far in, so it would work but the locking hooks can’t latch. This is fixed in “version 2″, where the connector footprint is near perfect.
The entire quadcopter is incredibly strong and ridged. I am a terrible pilot and this entire project is a gigantic wild experiment so I crashed a ton, but everything survives!
The antenna makes a huge difference, a 4″ router antenna (RN-SMA4-RP) performed noticeably better than a stubby 1” antenna (RN-SMA-S-RP, yes, it is still supposed to be designed for 2.4 GHz).
I added a lanyard to the transmitter to make it easier to use and carry around.
I had no idea whether or not the motors and propellers I buy would have been strong enough. The only clues I had were other people’s projects, but I didn’t have any real specification data, dimensions, performance measurements, or anything like that. I just paid for the parts, design around them after taking some dimensions myself, and hope it works in the end.
There appears to be a command to the MPU-6000 that disables the I2C interface. Funny story: I copied code for the MPU-6000 from another project that used SPI instead of I2C, and did not remove that particular command. The MPU-6000, after initialization, stopped responding to its own address on the I2C bus and caused me to suspect a bad sensor… In a panic, I used a heat gun to remove the chip (and melting a nearby JST connector housing). Then I realized my stupid mistake after replacing it with a new chip and did an I2C address scan.
Funny thing about the low battery detection… The battery voltage would appear fine, but if the battery is drained and all four motors energize, the internal resistance of the battery combined with the sudden massive current draw might actually cause the voltage to drop so low such that the microcontroller resets. This sort of makes the low battery detection feature useless on the quadcopter circuit.