loading

Some time ago (over 8 months) I was thinking about what I can build. I wanted to make an interesting robot/device that will be challenge for me and will encourage me to learn new things. I thought about the lot of robots but a lot of them were posted on the internet. And i thought about making a drone completly by myself, including flight controller, pilot, program and frame design. This is by far the longest build i have made, it takes a lot of time and effort to make it but finaly after over 8 months it's ready and i am here to share it with you as completly open source project.

I just started my facebook fanpage!If you want to see what I am making, be up to date with my projects or need some help feel free to like it, thanks!

Here is link to video if you use an app

Info for begginers:

This project is not the simple one. You need some basic knwoledge of arduino programming, PCB's and electronics to make it. If you haven'y done anything like that before I advise you to start with something simpler like:

Arduino sensitive robot

DIY bike tachometer (speedometer)

Very Simple Robot for Beginners

But if you really want to make it, you should try, I am always here to help you.

My apel to you! :)

I am participate in contests right here on instructables. In one of them (microcontroller contest) there is macbook air as a grand prize. It could help me with calibrating PID for my drone because right now I haven't any laptop that I can go outside with so there is no way to calibrate it perfectly. I am also working on an app with my friend we want to publish it before holidays. We have a very very good idea for it and it can be very popular, I can't tell you what is it I can just tell you name of it - Socialize. We are finishing android version of this app. As you may know to make an iphone app you need t have apple computer. We haven't one and we haven't money for it :( So it will also help me with developing IOS version of our map that I will inform you about shortly. If you want to vote for my project you can do it by clicking vote! in upper right corner and then selecting contest in which you want vote for me. Thanks everyone! :D

Step 1: LUDWIK DRONE THE WINNER!!!!

For some reasons and because of my friend lukmar I named my drone Ludwik. And Ludwik took part in International robotic tournament in Rybnik in Poland (I am from Poland) and it won first place in freestyle category! I even print for this contest like this label with Ludwik dron :) Above is the photo from this contest.

Step 2: Why My Own Program, Frame, Pilot and PCB?

You can ask why do you wrote your own program for it? Why do you made custom 3D printed frame (see next steps to see why I failed with it)? And additionaly custom pilot and PCB's. Basically because I can :) I like making things on my own and learning how they works. Thanks to this type of thinking I learned a lot about quadcopters and how they works.

Code

The biggest problems I had with code for stabilizing it, it wasn't hard to write it but very hard to adjust and to get rid off some bugs. It's still not perfect but much closer to it and it works really good so far. When my code was ready I started to adjust PID regulators (here you can read something more about PID) and this was a terrible thing, I almost destroyed my room because of some really small bug in my code (for some reasons my code was decrementing int infinitely and when it reaches minimum value it goes to maximum value of int and my drone turned on motors 100% and hit wall and doors in my room). For a long time my PID regulator was adjusted very bad but every day I was closer to make it perfect. While this adjusting I broke my 3D printed frame 4 times :(

Something about 3D printed frame

At the beggining I thought that it can be very usefull to make 3d printed frame. It was really possible that I will broke it at least few times (I was right :)) but after 7 broken parts I decided to buy one, mainly because it is much stronger and rigid. I broke this frame during first flight with it :(

Pilot

Main reason is money. If you want to buy a pilot for drone you need to spend at least $50, thats quite a lot. So I build my own for like $20. And the good thing about it is that I can create as many channels as I want :)

PCB's

Because of my own code and my own pilot I have to make PCB's. I made 3 of them. The first one is power distributor for motors, second one is pilot and third one is of course flight controller. All of them use through hole componnents to make it easier to solder. In my final version I am not using power distribution board because my frame already have that.

Step 3: Quick Story

I want to write this quick story of building of this drone, if you don't wnat to read it just go to next step. I want to warn you that english is not my mother language and it's really common that there will be some mistakes, sorry for that.

I started building it in june 2016. Right now when I writing this it's March 2017 so it took me 9 months to make it. Mainly because of bad weather, rain, snow, windy days.

First thing that I bought was motors, ESC's and battery from amazon. I live in Poland theres no amazon :( So I asked my uncle to buy me those parts (thanks uncle). Then I designed my 3D printed frame and print out everything. Then I started prototyping I mount aruino UNO with a breadboard on my frame connect MPU-6050 (this is gyroscope and accelerometer) and the best thing my "controller" :) which was breadboard with potentiometer connected with 5 meters long cables to arduino uno on my quadcopter :D It looked pretty funny and it wasn't very safe but it gave my posibility to test my drone fast with out dealing with radio yet. I also create some kind of holder for my drone to test it at home without possibility of destroying something including me by drone. I also made some odd experiments with this drone fortunately my dad takes few photos of it so you can see it above :) (thanks dad). During those experiments I destroyed 2 li-po batteries (to be honest I don't know when and how). By testing it and flying in bad conditions or with bugs in my code I broke 3d printed frame 7 times. After 9 months of building, breaking, experimenting it is finally ready. But it's not a final version I still want to make some improvements, and I hope that you the makers will help me in it. I share all of those as open source so you can modify it, and do whatever you want (not for commercial use) remember to mention about my project somewhere.

I hope you enjoy this quick story. Right now we can start buliding a drone :D

Step 4: Parts

For this project we need a lot of parts, because it is actually a little bit complicated. Overall cost of them is about $200 not so much for a drone, but it's because we create a flight controler and pilot by ourselfs. Here is complete list with links to parts that I bought from different suppliers:

  • Motors - I just bought the cheapest one, that works easily for this kind of drone. You need 4 of them buy here: Gearbest
  • ESC's - depends on motors that you choose max current of ESC should be a little bit bigger than max current of motor. It must have BEC because flight controller is powered by it. We will also 4 of them. buy here: Gearbest
  • Battery - 3S (11.1V) Li-Po should be around 3000mAh to get 15 mins of flight time. Make sure that it can deliver enough current. buy here Gearbest
  • Frame - at the beggining it was 3D printed and in the feature it will be, but for now I used very popular F450 frame buy here: Gearbest
  • LiPo charger - you must charge lipo batteries with special charger with balancer. Remember to choose right power plug Gearbest
  • Propellers - can be different but this one works the best. I advise you to buy some more, they are easy to broke. They need to have a hole not thread. You choose some other color if you want. Gearbest
  • Battery protection/monitor - never connect battery to anything without it, I destroyed 2 Lipo's because I forgot about it. Gearbest

And here are parts for flight controller:

  • Atmega328 - I advise you to buy it in local shop
  • NRF24L01 - radio modul, we need it to create radio communication, remember to buy version with external antena because it has much bigger range Gearbest
  • MPU6050 - gyroscope and accelerometer in one module Gearbest
  • Some smaller parts:
    • capacitors 22pF (x2)
    • capacitor 10uF
    • resistor 4,7kOhm
    • 3,3V linear stabilizer
    • some goldpins (female and male)

The last thing is pilot:

  • NRF24L01 - radio modul, we need it to create radio communication, remember to buy version with external antena because it has much bigger range Gearbest
  • Atmega328 - I advise you to buy it in local shop
  • Joysticks - 2 of them
  • Some smaller parts:
    • capacitors 22pF (x2)
    • capacitor 10uF (x2)
    • resistor 4,7kOhm
    • 3,3V linear stabilizer
    • LED diode

Step 5: Prototyping

The first thing to do was protyping, to check how everything works and if circuits are good connected. I screwed up arduino UNO to drone frame and mounted mpu6050 in breadboard which was fixed to frame with double sided tape. "Pilot" which was equal to potentiometer in breadboard wired with 5m long cables to my drone. At this point I created the world's first wire drone :) After testing, in my wooden frame, outdoor tests and some changes in connections design I created eagle schematic and then PCB. Above you can see some photos of my drone with a lot of cables on the top.

On one of those photos you can see red cable with black tape on it, guess what is this :) it's some kind of kill switch which just cut off power for arduino board.

This frame for testing a drone is made out of wood just to hold it in place and let it rotate on one axis, thats all.

Step 6: Code Explonation

Flight controller

This code isn't as hard as you can think. It just use 3 PID algorithms for stabilizng it in 3 axis (x, y, z also cold pitch, yaw and roll), code for getting angles from mpu6050's DMP (digital motion processing), and also handle radio receiving and some basic math to calculate data received by radio. It stabilize itself at 100 times a second (100Hz) that's enaugh for this drone.

PID algorithms:

There are a lot of great explonations of how PID works, and because I not a good teatcher I woldn't try to explain how it works. I use those values for PID bcause after lot's of test I find them best one, but they still can be better, Kd is much to big. I am not the PID tune expert and I have never done it on any other drone then this. For different motors, propellers, frame this value can be different. If you will find better one send them to me and I will test it on my drone.

MPU6050:

This code is just copied from MPU6050 library. I wanted to write my own, faster library for it but I couldn't find any good datasheet of it and I was to lazy :) If there is ready library which works fine (but could be faster) why not to use it?

NRF24L01

Here are just few lines to receive array of 8 bit numbers from pilot and convert it to throttle and rotation on x, y and z axis. You can also add more values and using them turn on lights on drone or anything you like.

Pilot

Code for pilot is straight forward. Just reads joystick values and send them over NRF24L01 that's all, nothing complicated. Radio speed is reduced to increase range.

Both codes you can find below.

<p>#include "I2Cdev.h"<br>#include <servo.h>
#include <spi.h>
#include "RF24.h"
#include "MPU6050_6Axis_MotionApps20.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif
//we need this to see nrf24l01 configuration in serial
#include "printf.h"</spi.h></servo.h></p><p>//end of libraries ###############################################</p><p>MPU6050 mpu;</p><p>float x_rotation, y_rotation, z_rotation;
Servo motor1;
Servo motor2;
Servo motor3;
Servo motor4;
bool first_loop = true;
//radio
RF24 radio(9,10);
uint8_t data[6];
const uint64_t pipe = 0xE8E8F0F0E1LL;
long last_received;
int controll_number = 159;</p><p>//values = 5.2, 0.02, 1500
//variables for movement and positions ###########################################
//for my quadcopter this are the best settings for pid
float x_kp = 5, x_ki = 0.02, x_kd = 1100; //values for PID X axis
int max_pid = 300;
float x_p_out, x_i_out, x_d_out, x_output; //outputs for PID
float x_now, x_lasttime = 0, x_timechange;
float x_input, x_lastinput = 0, x_setpoint = 0;
float x_error, x_errorsum = 0, x_d_error, x_lasterror;</p><p>//values = 5.2, 0.02, 1500
float y_kp = 5, y_ki = 0.02, y_kd = 1100; //values for PID Y axis
float y_p_out, y_i_out, y_d_out, y_output; //outputs for PID
float y_now, y_lasttime = 0, y_timechange;
float y_input, y_lastinput = 0, y_setpoint = 0;
float y_error, y_errorsum = 0, y_d_error, y_lasterror;</p><p>float z_kp = 2, z_ki = 0, z_kd = 0; //values for PID Z axis
float z_p_out, z_i_out, z_d_out, z_output; //outputs for PID
float z_now, z_lasttime = 0, z_timechange;
float z_input, z_lastinput = 0, z_setpoint = 0;
float z_error, z_errorsum = 0, z_d_error, z_lasterror;</p><p>//set it to 0 and see on serial port what is the value for x and y rotation, use only if your flightcontroller board is not perfevtly leveled. If your board is perfectly leveled set it to 0
float x_level_error = 0;
float y_level_error = 0;</p><p>/*
 * 
 * 
 * JUNE 2016 - APRIL 2017
 * C by Nikodem Bartnik
 * nikodem.bartnik@gmail.com
 * nikodembartnik.pl
 * 
 * 
 * 
 */</p><p>#define INTERRUPT_PIN 2  // use pin 2 on Arduino Uno & most boards
int motor1_power;
int motor2_power;
int motor3_power;
int motor4_power;</p><p>float allmotors_power = 600;</p><p>// MPU control/status vars
bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer</p><p>// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container</p><p>VectorFloat gravity;    // [x, y, z]            gravity vector</p><p>float rotation[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector
int safe_lock = 1;</p><p>volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
    mpuInterrupt = true;
}</p><p>void setup() {
    // join I2C bus (I2Cdev library doesn't do this automatically)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif</p><p>printf_begin();</p><p>    Serial.begin(115200);</p><p>    Serial.println("Initializing I2C devices...");
    mpu.initialize();
    pinMode(INTERRUPT_PIN, INPUT);</p><p>    // verify connection
    Serial.println("Testing device connections...");
    Serial.println(mpu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
//    bmp.begin();  
    radio.begin();
    delay(1000);
    radio.setDataRate(RF24_250KBPS);
    radio.setPALevel(RF24_PA_MAX);</p><p>    radio.openReadingPipe(1,pipe);
    radio.startListening();
    
   </p><p>    // load and configure the DMP
    Serial.println("Initializing DMP...");
    devStatus = mpu.dmpInitialize();</p><p>    // gyro offsets here
    mpu.setXGyroOffset(87);
    mpu.setYGyroOffset(77);
    mpu.setZGyroOffset(110);
    mpu.setZAccelOffset(2287); 
    mpu.setYAccelOffset(-1283);
    mpu.setXAccelOffset(-3083);</p><p>    // make sure it worked (returns 0 if so)
    if (devStatus == 0) {</p><p>        Serial.println("Enabling DMP...");
        mpu.setDMPEnabled(true);</p><p>        attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();</p><p>      
        dmpReady = true;</p><p>        packetSize = mpu.dmpGetFIFOPacketSize();
    } else {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        Serial.print("DMP Initialization failed (code ");
        Serial.print(devStatus);
        Serial.println(")");
    }</p><p>    motor1.attach(5);
    motor2.attach(8);
    motor3.attach(7);
    motor4.attach(4);
    pinMode(A0, INPUT);
    pinMode(A1, INPUT);
    digitalWrite(A0, LOW);
    motor1.write(0);
    motor2.write(0);
    motor3.write(0);
    motor4.write(0);</p><p>radio.printDetails();
}</p><p>void loop() {</p><p>    if (radio.available()) {
    
    bool done = false;
    while (!done){
     
     done = radio.read(data, sizeof(data));</p><p>    // Serial.print("Controll number: ");
     //Serial.println(data[0]);
     
      if((millis()-last_received) < 3000){
        if(data[0] == controll_number){
          Serial.print("DATA1: ");
          Serial.println(data[1]);
          allmotors_power = map(data[1], 0, 255, 800, 1500);
          if(allmotors_power < 0){
            allmotors_power = 0;
          }</p><p>          
     //allmotors_power = map(data[1], 0, 255, 800, 1600);
     x_setpoint = data[3] - 20;
     y_setpoint = data[2] - 20;
     Serial.print("PID OUT X: ");
     Serial.print(x_rotation);
     Serial.print(" PID OUT Y: ");
     Serial.print(y_rotation);
     Serial.print("Z NOW: ");
     Serial.println(z_rotation);
     Serial.print(" TIME: ");
     Serial.println(millis());</p><p>Serial.print("MOTORS POWER: ");
Serial.println(allmotors_power);
  
     
        }
     }
     // Serial.println(data[1]);
      if(done == true){
      last_received = millis();
      }
  }   
 }</p><p> if((millis()-last_received) > 3000 && allmotors_power > 0){
    safe_lock = 0;
     }
 
    // if programming failed, don't try to do anything
   // if (!dmpReady) return;</p><p>   
    while (!mpuInterrupt && fifoCount < packetSize) {
     
    }</p><p>    // reset interrupt flag and get INT_STATUS byte
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();</p><p>    // get current FIFO count
    fifoCount = mpu.getFIFOCount();</p><p>    // check for overflow (this should never happen unless our code is too inefficient)
    if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
       </p><p>    // otherwise, check for DMP data ready interrupt (this should happen frequently)
    } else if (mpuIntStatus & 0x02) {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();</p><p>        // read a packet from FIFO
        mpu.getFIFOBytes(fifoBuffer, packetSize);
        
        // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount -= packetSize;</p><p>    if(safe_lock == 1){
   
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetYawPitchRoll(rotation, &q, &gravity);</p><p>          x_rotation = rotation[1] * 180/M_PI - x_level_error;
            y_rotation = rotation[2] * 180/M_PI - y_level_error;
            z_rotation = rotation[0] * 180/M_PI;</p><p>/*
          if(pressure_loop_number == 10){
           // Serial.print("Preasure: ");
            //Serial.println(bmp.readAltitude());
            pressure_loop_number = 0; 
            allmotors_power = 1000;
           }
            pressure_loop_number++;  
*/</p><p>           if(first_loop == true){
            z_setpoint = z_rotation;
          //  current_altitude = bmp.readAltitude();
            //set_altitude = current_altitude;
            first_loop = false;
           }
          
            
            
        motor1_power = allmotors_power;
        motor2_power = allmotors_power;
        motor3_power = allmotors_power;
        motor4_power = allmotors_power;
          if(allmotors_power > 1500){
               allmotors_power = 1500;
                
                
                }</p><p>                 
                 x_output = calculatePID(0, x_rotation);
                 y_output = calculatePID(1, y_rotation);
                 z_output = calculatePID(2, z_rotation);</p><p>                 motor1_power += x_output/2;
                 motor1_power += z_output;
                 motor4_power -= x_output/2;
                 motor4_power += z_output;</p><p>                 motor2_power -= y_output/2;
                 motor2_power -= z_output;
                 motor3_power += y_output/2;
                 motor3_power -= z_output;
                 
             
                motor1.writeMicroseconds(motor1_power);
                motor4.writeMicroseconds(motor4_power); 
                motor2.writeMicroseconds(motor2_power);
                motor3.writeMicroseconds(motor3_power); 
                mpu.resetFIFO();
               
     
    }else{
                motor1.write(0);
                motor2.write(0);
                motor3.write(0);
                motor4.write(0);
    }
}
}</p><p>   float calculatePID(int _axis, float _angel){</p><p>      // X AXIS
      if(_axis == 0){
                 x_now = millis();
                 x_timechange = x_now - x_lasttime;
                 x_error = x_setpoint - _angel;
                 x_p_out = (x_kp * x_error);
                
                 x_errorsum = (x_errorsum + x_error);
                 if(x_errorsum > 1023){
                  x_errorsum = 1023;
                 }
                 if(x_errorsum < -1023){
                  x_errorsum = -1023;
                 }
                 x_i_out = x_ki * x_errorsum;
                 x_d_error = (x_error - x_lasterror) / x_timechange;
                 x_d_out = x_kd * x_d_error;
                 x_lasterror = x_error;
                 x_output = x_p_out + x_i_out + x_d_out;
                 if(x_output > max_pid){
                  x_output = max_pid;
                 }else if(x_output < -(max_pid)){
                  x_output = -(max_pid);
                 }
                 x_lasttime = millis();
                 return x_output;
      }</p><p>      // Y AXIS
      else if(_axis == 1){
                 y_now = millis();
                 y_timechange = y_now - y_lasttime;
                 y_error = y_setpoint - _angel;
                 y_p_out = (y_kp * y_error);</p><p>                 y_errorsum = (y_errorsum + y_error) * y_timechange;
                 if(y_errorsum > 1023){
                  y_errorsum = 1023;
                 }
                 if(y_errorsum < -1023){
                  y_errorsum = -1023;
                 }
                 y_i_out = y_ki * y_errorsum;
                 y_d_error = (y_error - y_lasterror) / y_timechange;
                 y_d_out = y_kd * y_d_error;
                 y_lasterror = y_error;
                 y_output = y_p_out + y_i_out + y_d_out;
                 if(y_output > max_pid){
                  y_output = max_pid;
                 }else if(y_output < -(max_pid)){
                  y_output = -(max_pid);
                 }
                 y_lasttime = millis();
                 return y_output;</p><p>                 // ALTITUDE
     // } else if(_axis == 2){
      //           return (set_altitude - current_altitude) * 20;
      }else if(_axis == 2){
                 z_now = millis();
                 z_timechange = z_now - z_lasttime;
                 z_error = z_setpoint - _angel;
                 z_p_out = (z_kp * z_error);</p><p>                 z_errorsum = (z_errorsum + z_error) * z_timechange;
                 if(z_errorsum > 1023){
                  z_errorsum = 1023;
                 }
                 if(z_errorsum < -1023){
                  z_errorsum = -1023;
                 }
                 z_i_out = z_ki * z_errorsum;
                 z_d_error = (z_error - z_lasterror) / z_timechange;
                 z_d_out = z_kd * y_d_error;
                 z_lasterror = y_error;
                 z_output = z_p_out + z_i_out + z_d_out;
                 if(z_output > max_pid){
                  z_output = max_pid;
                 }else if(z_output < -(max_pid)){
                  z_output = -(max_pid);
                 }
                 z_lasttime = millis();
                 return z_output;</p><p>                 // ALTITUDE
     // } else if(_axis == 2){
      //           return (set_altitude - current_altitude) * 20;
      }else{
        return 0;
      }</p><p>      
      
    }</p>
<p>/*</p><p> * 
 * 
 * JUNE 2016 - APRIL 2017
 * C by Nikodem Bartnik
 * nikodem.bartnik@gmail.com
 * nikodembartnik.pl
 * 
 * 
 * 
 */</p><p>#include <spi.h><br>#include "RF24.h"</spi.h></p><p>#define MAX_TILT 20</p><p>RF24 radio(9,10);</p><p>int a = 0;
uint8_t data[6];
int controll_number = 159;
int safe_lock = 0;
int x_offset, y_offset;</p><p>const uint64_t pipe = 0xE8E8F0F0E1LL;</p><p>void setup(void){
  
  Serial.begin(57600);</p><p> pinMode(4, OUTPUT);
 pinMode(3, INPUT);
 pinMode(A0, INPUT);
 pinMode(A1, INPUT);
 pinMode(A2, INPUT);
 pinMode(A3, INPUT);
 digitalWrite(3, HIGH);
 digitalWrite(4, HIGH);</p><p>  radio.begin();</p><p>radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_MAX);</p><p>    radio.openWritingPipe(pipe);
  radio.printDetails();</p><p>}</p><p>void loop(void)
{
  if(!digitalRead(3)){
    Serial.print("LOW 1");
    delay(1000);
    if(!digitalRead(3)){
      Serial.print("LOW 2");
    delay(1000);
    if(!digitalRead(3)){
      Serial.print("LOW 3");
      if(safe_lock == 0){
        safe_lock = 1;
      }else{
        safe_lock = 0;
      }
    
  }
  }
  }</p><p>int power = map(analogRead(A2), 0, 1023, 0, 255);
int x = map(analogRead(A1), 0, 1023, 0, 255);
int y = map(analogRead(A0), 0, 1023, 0, 255);
int rotation = map(analogRead(A3), 0, 1023, 0, 255);</p><p>if(x > 150){
  x = map(x, 150, 255, 0, MAX_TILT);
}else if(x < 105){
  x = map(x, 105, 0, 0, -MAX_TILT);
}else{
  x = 0;
}</p><p>if(y > 150){
  y = map(y, 150, 255, 0, MAX_TILT);
}else if(y < 105){
  y = map(y, 105, 0, 0, -MAX_TILT);
}else{
  y = 0;
}</p><p>if(rotation > 150){
  rotation = map(rotation, 150, 255, 0, MAX_TILT);
}else if(rotation < 105){
  rotation = map(rotation, 105, 0, 0, -MAX_TILT);
}else{
  rotation = 0;
}</p><p>  data[0] = controll_number;
  data[1] = power;</p><p>  // + 10 because you can't send negative number
  data[2] = x + MAX_TILT;
  data[3] = y + MAX_TILT;
  data[4] = rotation + MAX_TILT;
  data[5] = safe_lock;</p><p>radio.write( data, sizeof(data) );</p><p> delay(8);
}</p>

Step 7: Flight Controller PCB (and Power Distribution)

Right there you can find all files including .brd, .sch and .pdf for printing. And some photos of how I made them. Traces are very small so the board is not so easy to make. There are not a lot to write about so just enjoy the photos and files :)

How to make PCB's

I also made a power distribution board and it was used on 3D printed version of my drone, but right now I am not using it since frame that I bought have power distribution board build in to the frame.

Step 8: Pilot

Quick story of pilot. The first version of it was potentiometer on a breadboard as I mentioned earlier. It was connected to drone with 5 meters long cables. Then I build real wireless pilot on breadboard with arduino pro mini, two joysticks and battery. Work's great but this mess with cables are so bad. So while I was waiting for my frame I decided to design and make PCB for it. And thats the final version, max size of PCB in free eagle version to make it more handy. Looks pretty good, works perfectly. I added right there 2 switches for eventual light switching or maybe even some kind of thrower :) Schematic, PCB and program for it you can find in previous steps.

Step 9: Failed 3D Printed Frame

This is my 3D printed frame for my drone it's bad, don't print it. I just put it right there to show you how I made it, how it looks like and how you shouldn't design a frame for a drone. Printing time all parts for this frame is about 13 hours. I broke 7 part of it and after that I decided to give up at this point with this frame and buy one. I prefered to focus on my program and then when I finish it completly I will design comletly new frame, that will be stronger and smaller (this one is actually a little to big).

To design all of those parts I used fusion360 in my opinion the best 3D designing software. You can check it out here. I also recommend you to watch fusion360's youtube channel there are a lot of great tutorials, updates and usefull tips.

I also broke down 2 Li-Po batteries :(

Step 10: Some Usefull 3D Prints

Because some parts that were 3D printed are usefull I put .stl files here if you like to print them out. There is just antena holder for flight controller (you need to drill new hole in PCB just don't drill through traces) and holder for PCB of flight controller. I put a small like sponge under this holder to limit vibrations and srcew it down with M3 screws.

Step 11: Assembly

There are some photos and quick explonation of how to assemble all parts of drone. First of all you have to assemble the frame, there are 4 arms and 2 main plates it's very simple. After that you can mount your brushless motor on frame. Use 4 short screws to mount them on the arms (screws can't be too long because they can damage colis of the motor). Then you can solder ESC to the motor. Remember that left front motor and rear right must be soldered in the same way. Right front and rear left must be connected in the same way but you have to swap 2 phases of motor. I mount ESC to frame with zip tie. Remember to tight propellers very strongly, it is very usefull to use tiny screwdriver for it.

Step 12: Testing and Upgrades

I spent most time of making it on this stage. It was endless code changing, testing, code changing testing and so on. Above you can see some photos of it. One time when I test stabilization and I added piece of code to decrement throttle continously to make it landing softly after radio disconnection (right now I know that it is impossible without barometer or GPS). I forgot to add in this code protection at some level to don't let the number infinitly down. And what happens when number go infinitly down? At some point in to goes from max minus to max plus and then my drone has turned their motors with full throttle it goes up with this frame hit my door and wall and fall. I was on the opposit side. It was so close to hit me. And that's the reason that I wear ski helmet during rest of tests :)

Step 13: First Really Successful Flight

There were a lot of problems during this build some of them because of my errors some of them no. One time I forgot to add minus on the y axis and my drone instead of stabilize itself, was doing exactly opposite thing. But after a lot of troubles, I achieved first succesful flight, 10 perfect seonds of flying :) just up and down but it was stable and that's what I wanted to have. Above you can see video from one of the firsts flights (with 3D printed frame) and this was the first time that I thought that maybe it will finaly work. And then winter came it was snowing, it was cold and wet. I spend most time at home doing other things than drone. I was skiing and drone was waiting for better weather. At February 2017 I started working on it again I changed a program a little bit and do more test. It was better and better every test.And after some time I achieved this what you can see right now. It's not perfect but it's very good and the most important thing it's mine! There are still things to do to make it better, the most important one is calibrating PID for roll and pitch but there is no way for me to do it right now, I haven't laptop, but I need one to go outside with it and with drone and calibrate it by changing PID constants slightly, uploading program, testing and repeat as long as it will hover perfectly. Because I haven't a laptop I can't do this :(

And here is my request to you

If you like my project and want to help me, vote for me in contests (in microcontroller contest the prize is macbook air which could help my with fine-tuning this project). Thanks!

Step 14: The Final Version (0.1) and What's Next

So as I said this is the (not) final version. For now I will finish this build (Last thing to do is PID calibrating). I just want to go for some other builds and learning new things. But if you want you can help me with this project, we can work together on it to make the best, the simplest arduino drone that anyone can make. If you have build my project send me some photos of it on ma mail (nikodem.bartnik@gmail.com) or in the comments bellow.

If you have any questions just ask in the comments, on my mail or on my new facebook fanpage! I am here to help you. You can also write what you think about this project or how to improve it.

Thanks for reading don't forget to follow me on instructables, on facebook and on youtube.

Have a nice day everyone!

Hi,How to decide Gyro and Accelerometer offsett?
<p>You have to lay it flat on the ground (perfectly leveled ground) and then values that you will se on serial port will be your offset.</p>
I got the data, thank you!
hii, please help me to sort out this problem.<br><br>I want to add some more features.<br>auto flight and then altitude hold at 1 mtr. After that it will rotate on its axis.<br>Please help me how to do that with programming.<br>I am a beginner and i don't how to program.<br>Please help me
<p>I admire your efforts. People however should note:</p><p>1. In the USA and in Europe this is almost certainly illegal to fly. There are strict rules about radio controlled models.</p><p>2. Hobby microcontrollers should not be used in mission critical situations - this is one, if this goes astray people could get hurt - that's the definition of mission critical.</p><p>3. Both in Europe and in the USA strict regulations have been put in place concerning flying drones, A big reason is because irresponsible people ignored fairly obvious safety issues resulting in authority getting very upset. I fly RC aircraft all the time in the UK and do not want my hobby to be regulated out of existence because of the actions of a few unthinking people.</p><p>I don't believe this quad will meet the USA or Europe regulations.</p><p>Nice work though.</p>
<p>So you mean the arduino (hobby microcontroller) is essentially illegal for use on Multirotors?</p>
<p>1. There are rules designed to offer some safety to people and property in the vicinity of flying objects, this is why all flying even model flying is controlled by the FAA.</p><p>2. For your own well being and people around you you should not fly unless insured.</p><p>3. I come from an Industrial computing background. For liability reasons we would not use a hobby, or unapproved microprocessor in a safety critical situation. IF something goes wrong you leave yourself open to massive and justified litigation.</p><p>Illegal depends. If anything goes wrong your insurer will probably disown you. Flying without suitable third party insurance is certainly illegal in the UK anyway *(although many do). This would make using the Arduino illegal.</p><p>I know there are lots of boards, controllers etc out there containing Arduino or other uncertified controllers, That's just the way the world is. It isn't illegal to make them. </p><p>AFAIK or can see there isn't anyway for a hobbyist or small producer to get the software and hardware certified for use in safety critical situations - My opinion.</p><p>MUCH electrical equipment that originates in China is also Illegal to use as received - In the UK anyway. but they still make and sell it.</p>
<p>It is always good to estimate the risks in flying, just like in any other form of traffic: privacy issues/general disturbance, safety threats to people/animals and also material damage.</p><p>Regulations do vary from country to country, even inside Europe. There is no EU wide regulation at the moment. In Finland we have very little obstacles for hobby flying. Keep it below 150 meters and obey the flight restriction zones (like military, airports). It is legal to fly even over densely populated areas.</p><p>If I was testing my own flight controller, I'd have the drone anchored somehow or have a redundant method of automatically shutting it down in case of out-of-control state. Some tests can be done wihhout propellers, moving the drone manually and observing the reactions. </p><p>Legislation is one way into looking at things, but regardless of it, the drone builders must try to keep it safe, though the development testing isn't standardized and controlled. When the developers and other flyers play it fair, it keeps the hobby in green light, so to say.</p><p>I'm actually waiting for (free) registration for all drones, but that could come with lots of technical problems. Firstly, what is the registration for? Does it include technical inspection or is it a tax or just an ID? How to register your DIY drone? Thinking along brings up these questions. Who monitors the registration or acts upon incidents with registered drones? At first I'd go with legal ID and a &quot;register plate&quot; so that if a registered drone is found after hitting, say, a car, the owner can be reached. What ever the future brongs, I'm afraid there will always be people who don't know or don't care, as well as malfunctioning gear. It is not that grim after all, people get killed on bicycles, and we cannot get helmets in the law.</p>
<p>I have implemented method to shut drone down after loosing connection or just turning off the transmitter so if my drone will do something wrong I can just shut down the remote and it will fall instantly.</p>
That can be good for testing, but I would not want that in finished product. Transmission could be disrupted by transmitter falling from your hands etc. Not nice if the drone shuts down. But I understand it is hard to implement something safe and sure. I'm thinking now about lakes. How to equip my drone to prevent it from sinking in case it goes to water :)
<p>I've flown RC since '89 and had my AMA card that entire time, so I appreciate your need to protect the hobby, however your facts are plain wrong. The FAA regulations (at least in the US) are based on what the drone/quad is doing (height, line of sight, range to other aircraft etc.) and not how and what it is made of. If you think the &quot;off the shelf&quot; drones are pre-qualified or any less flawed, then look up &quot;drone flyaway&quot; on YouTube. There is not a commercial drone available that hasn't fallen out of the sky. </p>
<p>Such regulations will be improved in Poland maybe in 5 years. So far, the principles of the model flying are regulated only as &quot;good practices&quot;</p>
<p>Sorry but I completely disagree with you. In my opinion this type of thinking slows down technological progress. There are so many senseless rules that restrict people's creativity. So many laws that don't let us making, testing or just having fun with things that are not bad at all. So many laws that stoped small companies from producing and seilling products. I think that it is pretty sad. But this is just my opinion.</p><p>You sholud check out this video: <a href="https://www.youtube.com/watch?v=jG7dSXcfVqE&t">https://www.youtube.com/watch?v=jG7dSXcfVqE&amp;t</a></p><p>It shows very good what I think about those type of rules.</p><p>Thanks for comment!</p>
<p>It wouldn't be difficult to make it fit the regulations either. The transmitter isn't the issue. The biggest issue I see is that the drone defaults to a hover. The majority of commercially available drones default to landing and turning off when they lose signal. Fly it in permitted areas only, at permitted altitudes, and change the code to a kill-code.</p>
<p>Your code is excellent. Can i have your permission to adapt it to a gesture controlled quadcopter project im working on?</p>
<p>As long as you will mention me and my project in your project you can use it, no problem. Thanks!</p>
<p>Hye,can you help me? How to settle this part:</p><p><strong>Wire.setClock(400000); // 400kHz I2C clock.</strong></p><p>I cant compile this code. </p>
<p>Are you sure you downloaded the .zip and not just copy and paste program from here? Check if you selected arduino UNO as board.</p>
<p>I'm sure.I download the .zip and selected arduino UNO as board and still cant compile.</p>
<p>Exactly what RF library are you using? I downloaded one that looked plausible, but I get compiler errors in Arduino IDE which clearly signify I'm not using the correct one. I thought I'd start by making sure I could get the software going!</p>
<p>I used this one:</p><p>https://github.com/maniacbug/RF24</p>
<p>Thank you. Now both sketches compile for me w/ Arduino IDE 1.6.13. On to the fun part&hellip;</p>
<p>You're welcome, good luck!</p>
Great Instructables,thank's for shareing your creativity.
<p>Thanks!</p>
Great instructable, if you don't win this robot competition, then the judges need to have a rethink. Well done ??
Thanks!
<p>Awesome that you did the entire drone and radios!!!</p>
<p>Ignore the trolls they are innovation killers.</p>
<p>Thanks! I agree with you :)</p>
Great project. I will start to build this. Just one thing whats the range of that
Thanks, range is about 400 m
Great story. Thanks. Barry, Canada<br>
<p>WOW!!! Great job, I may just have to have a go at this one myself, thanks for all the great info. :)</p>
You are welcome, thanks!
<p>Awesome project!! Congratulations!! =D</p>
Thank you! :D
Hello sir can I use flysky remote 6channel and use your same code
Nope, you have to modify my code to get it work with normal RC controller
<p>Głos oddany - znakomity projekt, spędziłem na czytaniu cały poranek. Gratuluję!</p>
Dzięki bardzo!
<p>SUPER ZARĄBISTE :D <br>dzięki temu projektowi czuję się o 6 lat młodszy :D<br></p><p>Gratuluję Ci zapału, wykonania i entuzjazmu. Naprawdę super projekt. </p><p>Przy<br> okazji wyważyłeś od dawna otwarte drzwi :D ale nie szkodzi, benefity z <br>tego tytułu płyną wprost do ciebie (wiedza :D). Zważywszy na tw&oacute;j wiek, <br>naprawde jestem pod wrazeniem :) <br><br>Nie wiem czy znasz, ale <br>MultiWii, kod jest w arduino, poszukaj na githubie (jeśli wiesz o co <br>kaman to poprostu nie zwracaj uwagi na ten komentarz :D )</p>
dzięki, o multiwii wiem ale ten kod jest tak rozbudowany i zawiły że dla początkujących może być nie do ogarnięcia no i co za zabawa była by z wykorzystania czyjegoś kodu. Do tego jak sam piszesz zdobyta wiedza jest najważniejsza
Nie no jasne :D Multi-Wii to bardzo duży i mocno rozwinięty kod obejmujący mn&oacute;stwo rozwiązań sprzętowych i dodatk&oacute;w :) <br><br>Zdecydowanie rozumiem twoje podejście do tematu i dlatego całość tak bardzo mi się podoba :) szczerze gratuluję Ci tego projektu bo na prawdę jest czego :)
Dzięki! :)
Super. Sprobuje zbudowac wedlug Twojego projektu. Dzieki.
Dzięki
<p>As the person who built this, are there any tips you have? Are there better places to mount components?</p>
All the tips are in this instructable
Amazing work! I've been sitting ducks with my Arduino mega(Atmega 2560) , HC-SR-04 &amp; MPU-6050 and considering building a quadcopter controller with them. Your project is a great motivation for me and will help me in creating one for myself. Thanks for sharing! Love what you've done.

About This Instructable

46,895views

690favorites

License:

Bio: Hi, my name is Nikodem. I live in Poland, I'm 17 years old. I like to program and create robots, devices and things. In ... More »
More by Nikus:Live Instructables Followers Counter Arduino Drone | Quadcopter (3D Printed) Cheap 3D scanner 
Add instructable to: