Open and Scalable Code For Drone
Open and Scalable Code For Drone
BACHELOR OF TECHNOLOGY
in
MECHANICAL AND AUTOMATION ENGINEERING
Submitted By
Shubham (06614803616)
This is to certify that the report entitled “Development of Scalable and Open Source Code For
Compact Aerial System” submitted by Shubham (06614803616), Shubham
Sharma(07014803616), Abhishek Sharma (35114803616),in partial fulfillment for the
award of Bachelor of Technology in Mechanical and Automation Engineering from
Maharaja Agrasen Institute of Technology, is a record of bona fide project work carried out
by them under my supervision and guidance.
To the best of my knowledge the result contained in this thesis have not been submitted in part or
full to any other university for the award of any other degree or diploma.
It gives us immense pleasure to express our deepest sense of gratitude and sincere thanks to
our highly respected and esteemed guide Ms. Surabhi Lata (Lecturer MAE), MAIT Rohini,
for their valuable guidance, encouragement and help for completing this work. Their useful
suggestions for this whole work and co-operative behaviour are sincerely acknowledged.
We deeply express our sincere thanks to our Head of Department Dr. V.N. Mathur for
encouraging and allowing us to present the project on the topic “DEVELOPMENT OF OPEN
SORCE AND SCALABLE AND OPEN SORCE CODE FOR COMPACT AERIAL
SYSTEM” at our department premises for the partial fulfilment of the requirements leading
to the award of B-Tech degree.
We are also highly thankful to our project internal evaluator and guide Dr. O.P Grover (Prof.
MAE), MAIT Rohini, whose invaluable guidance helped us understand the project better.
Lastly, we would like to express our deep apperception towards our classmates and our
indebtedness to our parents for providing us the moral support and encouragement.
SHUBHAM (06614803616)
In today’s world where technology is taking control over almost all walks of life, growth in
defence sector, growth in automobiles sector, growth in industrial sector which had led to sound
pollution, traffic jam and air pollution. Quadcopter is one of flying unit used to lift the object
from one place to another in lesser time or can be used for surveillance purpose, industrial
purpose. As the technology has matured and become more mainstream, a number of practical
and very interesting uses of Quadcopter technology have emerged.
Arduino is an open source electronic platform based on easy to use hardware and software.
Arduino boards are able to read inputs – Light on a sensor, a finger on a button, o a twitter
message – and turn it into an output – activating a motor, turning on an LED publishing
something online. You can tell your board what to do by sending a set of instruction to the
microcontroller on the board. To do so you use the Arduino programming language (based on
Wiring) and the Arduino software (IDE) based on processing.
At industry level applications, quadcopter is made using KK board module which comes with
preprogrammed KK board and balanced gyroscope module which is not economical for smaller
applications. It’s not a cost-effective method. Our objective is making the quadcopter
economical and efficient for small level applications this work is proposed, to design and
develop a quadcopter using Arduino Uno board instead of preprogrammed KK flight Controller
board. It has wide application like quadcopter mounted with camera and GPS tracker could be
used for surveillance of wide areas such as forest and coast guard applications etc.
This project wok includes learning, discussing, coding and conducting experiment for each and
every peripheral in in-depth and step by step manner and developing and efficient and effective
code which is open source and scalable i.e. flexible for any editing and updating by third party in
future for Arduino Uno completely from scratch using the hardware required in quadcopter.
CERTIFICATE
ACKNOWLEGMENT
ABSTRACT
TABLE OF CONTENT
LIST OF FIGURES
LIST OF TABLES
CHAPTER 1
INTRODUCTION
CHAPTER 2
FLIGHT DYNAMICS AND DEVELOPMENTS
3.4 CODES 20
CHAPTER 4
INTERFACE
CHAPTER 5
RESULTS AND FUTURE SCOPE
REFERENCES 47
List of Figures
List of Tables
b) ROLL (tilting left and right) is controlled by increasing speed on one motor and
lowering on the opposite one.
c) PITCH (moving up and down, similar to nodding) is controlled the same way as roll but
using the second set of motors. This may be confusing but roll and pitch are determined from
where the “front” of the drone is. To roll or pitch, one rotor’s thrust is decreased and the
opposite rotor’s thrust is increased by the same amount. This causes the quadcopter to tilt.
When the quadcopter tilts, the force vector is split into a horizontal component and a vertical
component. [1-2]
Various groups such as the military, engineers, researchers, and hobbyists have been
developing quadcopters to understand different technical areas. For example, quadcopters can
be used for reconnaissance and collecting data. This could range from searching for survival
victims in a disaster area to checking the state of electrical power lines. Some quadcopters in
production today can hold light payloads, such as food and medical supplies, and deliver them
to areas where normal planes can not reach [4]. Many amateur radio operators have designed
and built their own multi-copters. Universities, such as MIT, have been studying and doing
research for the quadcopter over the past couple of years [5]. This would be a great
opportunity for students of the University of Manitoba to join this area of study.
Arduino was born at the Ivrea Interaction Design Institute as an easy tool for fast prototyping,
aimed at students without a background in electronics and programming. As soon as it
reached a wider community, the Arduino board started changing to adapt to new needs and
challenges, differentiating its offer from simple 8-bit boards to products for IoT applications,
wearable, 3D printing, and embedded environments. All Arduino boards are completely
open-source, empowering users to build them independently and eventually adapt them to
their particular needs. The software too, is open-source, and it is growing through the
contributions of users worldwide.
There are many other microcontrollers and microcontroller platforms available for physical
computing. Parallax Basic Stamp, Netmedia's BX-24, Phidgets, MIT's Handyboard, and
many others offer similar functionality. All of these tools take the messy details of
microcontroller programming and wrap it up in an easy-to-use package. Arduino also
simplifies the process of working with microcontrollers, but it offers some advantage for
teachers, students, and interested amateurs over other systems:
Operating Voltage 5V
SRAM 2 KB
EEPROM 1 KB
STEP11: Working on program to synchronize the motors to make our device fly.
4
CHAPTER 2
FLIGHT DYNAMICS AND DEVELOPMENTS
2.1.1WORKING OF QUADCOPTER
A quadcopter is operated by varying spin RPM of its four rotors to control lift and torque.
The thrust is determined using altitude, pitch, and roll angles and is obtained from the ratio of
the angles. The thrust plays a key role in maneuvering, enables the user to perform flying
routine which includes aerial maneuvers. To conduct such maneuvers precise angle handling
is required. It serves as a solution to handle the copter with angular precision which illustrates
how the spin of four rotors is varied simultaneously to achieve angular orientation along with
takeoff, landing and hovering at an altitude. [1]
A UAV quadcopter is an unmanned aerial vehicle with four rotating rotors used for lift and
movement. It uses an electronic control system and electronic sensors to help stabilize itself.
Quadcopter parts have been decreasing in price over the past couple of years due to
technological advances. As a result more hobbyists, universities, and industries are taking
advantage of this opportunity to design and develop applications for the quadcopter.
2.1.2 FLIGHT CONTROL
A quadcopter consists of four motors evenly distributed along the quadcopter frame as can
be seen in figure 1. The circles represent the spinning rotors of the quadcopter and the arrows
represent the rotation direction. Motors one and three rotate in a clockwise direction using
pusher rotors. Motor two and four rotate in a counter-clockwise direction using puller rotors.
Each motor produces a thrust and torque about the center of the quadcopter. Due to the
opposite spinning directions of the motors, the net torque about the center of the quadcopter
is ideally zero, producing zero angular acceleration. This eliminates the need for yaw
5
stabilization. A vertical force is created by increasing the speed of all the motors by the same
amount of throttle. As the vertical forces overcome the gravitational forces of the earth, the
quadcopter begins to rise in altitude. Figure 1 shows the vertical movement of the quadcopter.
As above, the circles represent the spinning rotors, the larger arrows represent the direction
the rotors are spinning, and the black arrows represent the forces caused by the spinning
rotors. Pitch is provided by increasing (or decreasing) the speed of the front or rear motors.
This causes the quadcopter to turn along the x axis. The overall vertical thrust is the same as
hovering due to the left and right motors; hence only pitch angle acceleration is changed.
Figure 1 shows an example of pitch movement of a quadcopter. As the front motor slows
down, the forces created by the corresponding rotor are less then the forces created by the
back rotor. These forces are represented by the blue arrows. These forces cause the
quadcopter to tip forward and this movement is represented by the red arrow Roll is provided
by increasing (or decreasing) the speed of the left rotor speed and right motors. This causes
the quadcopter to turn along the y axis. The overall vertical thrust is the same as hovering due
to the front and back motors; hence only roll angle acceleration is changed. Figure 2.4 shows
an example of roll movement of a quadcopter. As the right motor slows down, the forces
created by the corresponding rotor are less then the forces created by the left rotor. These
forces are represented by the blue arrows. This causes the quadcopter to tip to the right and
this movement is represented by the red arrow. Yaw is provided by increasing (or decreasing)
the speed of the front and rear motors or by increasing (or decreasing) the speed of the left
and right motors. This causes the quadcopter to turn along its vertical axis in the direction of
the stronger spinning rotors. Figure 2 shows an
7
CHAPTER 3
OVERVIEW OF THE PROJECT
8
3.2 CIRCUIT DIAGRAM
a) ARDUINO microcontroller
b) MPU-6050 (3-axis Accelerometer & Gyroscope)
c) HMC-5883L magnetometer
d) BME-280 (temperature, pressure, humidity)
e) 4 no’s of BLDC motors and ESCS
f) GPS module
g) Node MCU ESP8266 (Wi-Fi module)
h) Connecting wires
9
Figure 3.3. Arduino UNO microcontroller
3-AXIS MAGNETOMETER(HMC5883L)
The HMC5883L is a triple-axis magnetometer compass, which uses I2C for communication.
This is 5 pin IC. Compass heading accuracy of 1° to 2°, provided by internal 12-bit ADC
(Analog-to-Digital Converter).
In our project, we have used the 3-axis magnetometer to help the quadcopter judge the
direction to where it is going
10
Figure 3.5. HMC5883L Magnetometer
11
Figure 3.7. Node MCU Esp8266 Wi-Fi module
Frame
The frame that made by our designing group is strong and durable. It uses a combination of
carbon fiber plates and aluminum arms for strength and durability. The frame is designed in
such a way that many different configurations could be used, supporting up to eight different
motors in an octocopter configuration. The design is also very modular, in a way that you
could easily add components to the frame by adding an extra carbon plate onto the
quadcopter. The arms are made of regular 5/8 inch hollow square aluminum bars and uses
common nuts and bolts to hold the frame together. Other than the carbon fiber plates,
everything can be found at a local hardware store. This allows easy accessible replacement
parts for replacement or maintenance
12
Electric Motors
The BP A2217-9 electric brushless motor. These motor are shown in figure . These motors
run at maximum efficiency at 15 amperes of current and can handle currents of up to 18
amperes for up to sixty seconds. The maximum revolutions per minute per volt is 950 kpv
and the maximum amount of power the motors can handle is 200 watts. These motors are
also relatively light, weighing about 73.4 grams.
There are two types of motors, brushless and brushed. A basic brushless motor has three
electromagnetic windings separated evenly on the stationary part of the motor, called a stator.
Permanent magnets are located on the rotating part of the motor, called a rotor. The rotor will
begin to rotate when two of the three windings are supplied with a voltage, creating a
magnetic field. The magnetic field created by the windings pushes and pull against the
magnetic field created by the magnets on the rotor. When the magnetic fields are aligned, two
different windings are driven and a new magnetic field is created causing the rotor to
continue to turn. A controller is used to determine the current rotor position relative to the
windings and drive the necessary windings in certain sequence to turn the rotor in the proper
direction. The rotor will turn in the opposite direction if the sequence is reversed.
A brushed motor works in a similar fashion. A brushed motor has the opposite orientation of
brushless motor. The electromagnetic windings are located on the rotor and the magnets are
located on the stator. Like a brushless motor, the rotor on a brushed motor turns due to the
attractive and repulsive forces of the two magnetic fields created by the windings and the
magnets. The main difference between these two motors is that a brushed motor uses a
mechanical switch to change the polarity of the windings to turn the rotor. A brushed motor is
more susceptible to wear and tear because it uses a mechanical mechanism to check and
change the polarity of its windings. It is also limited in speed due to the same reason [8].
13
Electronic Speed Controllers
The Hobbywing FlyFun brushless ESC rated at 30 amperes.These ESC can be seen in figure.
These ESC can push 30 amperes of current continuously, can push currents up to 40
amperes for ten seconds based on voltage output, and handle speeds up to 210,000 rotations
per minute (RPM). One ESC was found to be malfunctioning during testing and extra ESCs
were purchased. We will go into more details about this later in the document.
An electronic speed controller is an electrical circuit that controls the speed of an electric
motor and the direction a motor rotates. A motor turns because of the magnetic forces created
by the windings and the magnets within the motor.
For a brushless motor, the speed of the motor will depend on the frequency of the winding
drive sequence. On a basic brushless motor, there are three windings that are controlled using
pulse width modulated (PWM) signals. Two windings will be driven at a time to create the
necessary magnetic forces to turn the rotor. The greater the frequency sent to the motors, the
faster the rotor will turn due to the magnetic forces. The frequency of the signals is adjusted
by changing the pulse width of the signal. Smaller pulse widths will increase the frequency of
a PWM signal because more pulses can be sent to the windings in the same time duration, and
vice versa for large pulse widths. A brushed ESC works in the same manner but only two
control signals are used.
14
3.3 FLOW CHARTS OF CODES
Flow charts explains the program working any non-coder can understand the working of codes of
Arduino. The following flow charts explain the basic program like blinking of LED , DC motor and
brushless motor.
15
16
17
18
3.4 CODES
#include <Servo.h>
void setup() {
// Attach the ESC on pin 9
ESC.attach(9,1000,2000); // (pin, min pulse width, max pulse width in microseconds)
}
void loop() {
potValue = analogRead(A0); // reads the value of the potentiometer (value b/w 0 & 1023)
potValue = map(potValue, 0, 1023, 0, 180); // scale it to use it with the servo library
(value
b/w 0 &180)
ESC.write(potValue); // Send the signal to the ESC
}
19
3.4.2 PROGRAM TO CONTROL DC MOTORS
#define enA 9
#define in1 6
#define in2 7
#define button 4
int rotDirection =
0; int pressed =
false;
void setup() {
pinMode(enA,OUTPUT;
pinMode(in1,OUTPUT);
pinMode(in2,OUTPUT);
pinMode(button, INPUT); // Set initial rotation direction
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
}
void loop() {
int potValue = analogRead(A0); // Read potentiometer value
int pwmOutput = map(potValue, 0, 1023, 0 , 255); // Map the potentiometer value from 0
to 255
analogWrite(enA, pwmOutput); // Send PWM signal to L298N Enable pin
20
3.4.3 SIMPLE BLINKING LED
// the setup function runs once when you press reset or power the board
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage
level) delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
21
3.4.4 MULTIPLE LED IN SEQUENCE. (To demonstrate arrays)
int timer = 100; // The higher the number, the slower the timing.
int ledPins[] = { 2, 7, 4, 6, 5, 3}; // an array of pin numbers to which
LEDs are attached
int pinCount = 6; // the number of pins (i.e. the length of the array)
void setup() {
// the array elements are numbered from 0 to (pinCount - 1).
// use a for loop to initialize each pin as an output:
for (int thisPin = 0; thisPin < pinCount;
thisPin++) { pinMode(ledPins[thisPin],
OUTPUT);
}
}
void loop() {
// loop from the lowest pin to the highest:
22
for (int thisPin = 0; thisPin < pinCount; thisPin++) {
// turn the pin on:
digitalWrite(ledPins[thisPin],
HIGH); delay(timer);
// turn the pin off:
digitalWrite(ledPins[thisPin],
LOW);
23
CHAPTER 4
INTERFACE
Embedded System Interfacing: Design for the Internet-of-Things (IoT) and Cyber-Physical
Systems (CPS) takes a comprehensive approach to the interface between embedded systems
and software. It provides the principles needed to understand how digital and analog
interfaces work and how to design new interfaces for specific applications. The presentation
is self-contained and practical, with discussions based on real-world components. Design
examples are used throughout the book to illustrate important concepts. This book is a
complement to the author's Computers as Components, now in its fourth edition, which
concentrates on software running on the CPU, while Embedded System Interfacing explains
the hardware surrounding the CPU.
1. Small Size . Since embedded systems are application specific, the custom designed
system will have only necessary components and hence significantly smaller than a
regular computer.
2. Reduced cost. Obviously, since the system has less number of components as com-
pared to a computer.
3. Portability. Small size means portability. A lot of embedded systems we use run
on battery, and can be carried in a pocket. E.g ; calculator, digital watch etc.
4. Low power operation. Most embedded systems require very low power to operate,
thus making them ideal for medical applications.
24
5. Real time response. Embedded systems are also called real time systems, where
the response to external event has hard boundary for execution. Thus, they are bet-
ter for applications where response to an external event is critical. E.g: Deploying
airbags inside a car after collision.
#include<Wire.h>
#include
<EEPROM.h>
//Setup routine
void setup(){
pinMode(12, OUTPUT);
//Arduino (Atmega) pins default to inputs, so they don't need to be explicitly declared as
inputs
PCICR |= (1 << PCIE0); // set PCIE0 to enable PCMSK0 scan
PCMSK0 |= (1 << PCINT0); // set PCINT0 (digital input 8) to trigger an interrupt on state
change
PCMSK0 |= (1 << PCINT1); // set PCINT1 (digital input 9)to trigger an interrupt on state
change
PCMSK0 |= (1 << PCINT2); // set PCINT2 (digital input 10)to trigger an interrupt on state
change
25
PCMSK0 |= (1 << PCINT3); // set PCINT3 (digital input 11)to trigger an interrupt on state
change
Serial.println(F(""));
Serial.println(F("==================================================="));
Serial.println(F("System
check")); delay(1000);
Serial.println(F("Checking I2C clock speed."));
delay(1000);
#if F_CPU == 16000000L //If the clock speed is 16MHz include the next code line
when compiling
clockspeed_ok = 1; //Set clockspeed_ok to 1
#endif //End of if statement
if(error == 0){
Serial.println(F(""
));
Serial.println(F("==================================================="));
Serial.println(F("Transmitter setup"));
Serial.println(F("==================================================="));
delay(1000);
Serial.print(F("Checking for valid receiver signals."));
//Wait 10 seconds until all receiver inputs are valid
wait_for_receiver();
Serial.println(F(""));
}
//Quit the program in case of an
error if(error == 0){
delay(2000);
26
Serial.println(F("Place all sticks and subtrims in the center position within 10
seconds.")); for(int i = 9;i > 0;i--){
delay(1000);
Serial.print(i);
Serial.print(" ");
}
Serial.println(" ");
//Store the central stick positions
center_channel_1 =
receiver_input_channel_1;
center_channel_2 =
receiver_input_channel_2;
center_channel_3 =
receiver_input_channel_3;
center_channel_4 =
receiver_input_channel_4;
Serial.println(F(""));
Serial.println(F("Center positions
stored.")); Serial.print(F("Digital input
08 = "));
Serial.println(receiver_input_channel_1)
; Serial.print(F("Digital input 09 = "));
Serial.println(receiver_input_channel_2)
; Serial.print(F("Digital input 10 = "));
Serial.println(receiver_input_channel_3)
; Serial.print(F("Digital input 11 = "));
Serial.println(receiver_input_channel_4)
; Serial.println(F(""));
Serial.println(F(""));
}
if(error == 0){
Serial.println(F("Move the throttle stick to full throttle and back to center"));
//Check for throttle movement
check_receiver_inputs(1);
Serial.print(F("Throttle is connected to digital input
")); Serial.println((channel_3_assign &
0b00000111) + 7);
if(channel_3_assign & 0b10000000)Serial.println(F("Channel inverted =
yes")); else Serial.println(F("Channel inverted = no"));
wait_sticks_zero();
Serial.println(F(""));
Serial.println(F(""));
Serial.println(F("Move the roll stick to simulate left wing up and back to center"));
//Check for throttle movement
check_receiver_inputs(2);
Serial.print(F("Rollis connected to digital input"));
Serial.println((channel_1_assign & 0b00000111) +
7);
if(channel_1_assign & 0b10000000)Serial.println(F("Channel inverted =
yes")); else Serial.println(F("Channel inverted = no"));
27
wait_sticks_zero();
}
if(error == 0){
Serial.println(F(""));
Serial.println(F(""));
Serial.println(F("Move the pitch stick to simulate nose up and back to center"));
//Check for throttle movement
check_receiver_inputs(3);
Serial.print(F("Pitch is connected to digital input "));
Serial.println((channel_2_assign & 0b00000111) + 7);
if(channel_2_assign & 0b10000000)Serial.println(F("Channel inverted =
yes")); else Serial.println(F("Channel inverted = no"));
wait_sticks_zero();
}
if(error == 0){
Serial.println(F(""));
Serial.println(F(""));
Serial.println(F("Move the yaw stick to simulate nose right and back to center"));
//Check for throttle movement
check_receiver_inputs(4);
Serial.print(F("Yaw is connected to digital input
")); Serial.println((channel_4_assign &
0b00000111) + 7);
if(channel_4_assign & 0b10000000)Serial.println(F("Channel inverted =
yes")); else Serial.println(F("Channel inverted = no"));
wait_sticks_zero();
}
if(error == 0){
Serial.println(F(""));
Serial.println(F(""));
Serial.println(F("Gently move all the sticks simultaneously to their
extends")); Serial.println(F("When ready put the sticks back in their
center positions"));
//Register the min and max values of the receiver channels
register_min_max();
Serial.println(F(""));
Serial.println(F(""));
Serial.println(F("High, low and center values found during
setup")); Serial.print(F("Digital input 08 values:"));
Serial.print(low_channel_1);
Serial.print(F(" - "));
Serial.print(center_channel_1);
Serial.print(F(" - "));
Serial.println(high_channel_1);
Serial.print(F("Digital input 09
values:")); Serial.print(low_channel_2);
Serial.print(F(" - "));
Serial.print(center_channel_2);
Serial.print(F(" - "));
Serial.println(high_channel_2);
Serial.print(F("Digital input 10
28
values:")); Serial.print(low_channel_3);
Serial.print(F(" - "));
Serial.print(center_channel_3);
Serial.print(F(" - "));
Serial.println(high_channel_3);
Serial.print(F("Digital input 11
values:")); Serial.print(low_channel_4);
Serial.print(F(" - "));
Serial.print(center_channel_4);
Serial.print(F(" - "));
Serial.println(high_channel_4);
Serial.println(F("Move stick 'nose up' and back to center to continue"));
check_to_continue();
}
if(error == 0){
//What gyro is
connected
Serial.println(F(""));
Serial.println(F("==================================================="));
Serial.println(F("Gyro search"));
Serial.println(F("==================================================="));
delay(2000);
if(type == 0){
Serial.println(F("Searching for MPU-6050 on address
0x69/105")); delay(1000);
if(search_gyro(0x69, 0x75) == 0x68){
Serial.println(F("MPU-6050 found on address
0x69")); type = 1;
gyro_address = 0x69;
}
}
if(type == 0){
Serial.println(F("Searching for L3G4200D on address
0x68/104")); delay(1000);
if(search_gyro(0x68, 0x0F) == 0xD3){
Serial.println(F("L3G4200D found on address
0x68")); type = 2;
29
gyro_address = 0x68;
}
}
if(type == 0){
Serial.println(F("Searching for L3G4200D on address
0x69/105")); delay(1000);
if(search_gyro(0x69, 0x0F) == 0xD3){
Serial.println(F("L3G4200D found on address
0x69")); type = 2;
gyro_address = 0x69;
}
}
if(type == 0){
Serial.println(F("Searching for L3GD20H on address
0x6A/106")); delay(1000);
if(search_gyro(0x6A, 0x0F) == 0xD7){
Serial.println(F("L3GD20H found on address
0x6A")); type = 3;
gyro_address = 0x6A;
}
}
if(type == 0){
Serial.println(F("Searching for L3GD20H on address
0x6B/107")); delay(1000);
if(search_gyro(0x6B, 0x0F) == 0xD7){
Serial.println(F("L3GD20H found on address
0x6B")); type = 3;
gyro_address = 0x6B;
}
}
if(type == 0){
Serial.println(F("No gyro device found!!! (ERROR 3)"));
error = 1;
}
else{
delay(3000)
;
Serial.println(F(""));
Serial.println(F("==================================================="));
Serial.println(F("Gyro register settings"));
Serial.println(F("==================================================="));
start_gyro(); //Setup the gyro for further use
}
30
}
//If the gyro is found we can setup the correct gyro axes.
if(error == 0){
delay(3000);
Serial.println(F(""
));
Serial.println(F("==================================================="));
Serial.println(F("Gyro calibration"));
Serial.println(F("==================================================="));
Serial.println(F("Don't move the quadcopter!! Calibration starts in 3 seconds"));
delay(3000);
Serial.println(F("Calibrating the gyro, this will take +/- 8 seconds"));
Serial.print(F("Please wait"));
//Let's take multiple gyro data samples so we can determine the average gyro offset
(calibration).
for (cal_int = 0; cal_int < 2000 ; cal_int ++){ //Take 2000 readings for calibration.
if(cal_int % 100 == 0)Serial.print(F(".")); //Print dot to indicate calibration.
gyro_signalen(); //Read the gyro output.
gyro_roll_cal += gyro_roll; //Ad roll value to gyro_roll_cal.
gyro_pitch_cal += gyro_pitch; //Ad pitch value to gyro_pitch_cal.
gyro_yaw_cal += gyro_yaw; //Ad yaw value to gyro_yaw_cal.
delay(4); //Wait 3 milliseconds before the next loop.
}
//Now that we have 2000 measures, we need to devide by 2000 to get the average gyro
offset.
gyro_roll_cal /= 2000; //Divide the roll total by 2000.
gyro_pitch_cal /= 2000; //Divide the pitch total by 2000.
gyro_yaw_cal /= 2000; //Divide the yaw total by 2000.
Serial.println(F("==================================================="));
Serial.println(F("Gyroaxesconfiguration"));
Serial.println(F("==================================================="));
Serial.println(F("==================================================="));
Serial.println(F("LED test"));
Serial.println(F("==================================================="));
digitalWrite(12, HIGH);
Serial.println(F("The LED should now be lit"));
Serial.println(F("Move stick 'nose up' and back to center to continue"));
check_to_continue();
digitalWrite(12, LOW);
}
Serial.println(F(""));
if(error == 0){
Serial.println(F("==================================================="));
Serial.println(F("Final setup check"));
Serial.println(F("==================================================="));
delay(1000);
if(receiver_check_byte == 0b00001111){
Serial.println(F("Receiver channels
ok"));
}
else{
Serial.println(F("Receiver channel verification failed!!! (ERROR
6)")); error = 1;
}
delay(1000);
if(gyro_check_byte == 0b00000111){
Serial.println(F("Gyro axes ok"));
}
else{
Serial.println(F("Gyro exes verification failed!!! (ERROR
7)")); error = 1;
}
}
if(error == 0){
//If all is good, store the information in the EEPROM
Serial.println(F(""));
Serial.println(F("==================================================="));
Serial.println(F("Storing EEPROM information"));
Serial.println(F("==================================================="));
Serial.println(F("Writing
33
EEPROM")); delay(1000);
Serial.println(F("Done!"));
EEPROM.write(0,center_channel_1&0b11111111;
EEPROM.write(1, center_channel_1 >> 8);
EEPROM.write(2,center_channel_2&0b11111111;
EEPROM.write(3, center_channel_2 >> 8);
EEPROM.write(4,center_channel_3&0b11111111;
EEPROM.write(5, center_channel_3 >> 8);
EEPROM.write(6,center_channel_4&0b11111111;
EEPROM.write(7, center_channel_4 >> 8);
EEPROM.write(8,high_channel_1& 0b11111111);
EEPROM.write(9, high_channel_1 >> 8);
EEPROM.write(10,high_channel_2&0b11111111;
EEPROM.write(11, high_channel_2 >> 8);
EEPROM.write(12, high_channel_3 & 0b11111111);
EEPROM.write(13, high_channel_3 >> 8);
EEPROM.write(14, high_channel_4 & 0b11111111);
EEPROM.write(15, high_channel_4 >> 8);
EEPROM.write(16, low_channel_1 & 0b11111111);
EEPROM.write(17, low_channel_1 >> 8);
EEPROM.write(18, low_channel_2 & 0b11111111);
EEPROM.write(19, low_channel_2 >> 8);
EEPROM.write(20, low_channel_3 & 0b11111111);
EEPROM.write(21, low_channel_3 >> 8);
EEPROM.write(22, low_channel_4 & 0b11111111);
EEPROM.write(23, low_channel_4 >> 8);
EEPROM.write(24,channel_1_assign);
EEPROM.write(25,channel_2_assign);
EEPROM.write(26,channel_3_assign);
EEPROM.write(27,channel_4_assign);
EEPROM.write(28, roll_axis);
EEPROM.write(29, pitch_axis);
EEPROM.write(30, yaw_axis);
EEPROM.write(31, type);
EEPROM.write(32,gyro_addres;
//Write the EEPROM signature
EEPROM.write(33, 'J');
EEPROM.write(34, 'M');
EEPROM.write(35, 'B');
if(channel_1_assign != EEPROM.read(24))error = 1;
if(channel_2_assign != EEPROM.read(25))error = 1;
if(channel_3_assign != EEPROM.read(26))error = 1;
if(channel_4_assign != EEPROM.read(27))error = 1;
if(roll_axis != EEPROM.read(28))error = 1;
if(pitch_axis != EEPROM.read(29))error = 1;
if(yaw_axis != EEPROM.read(30))error = 1;
if(type != EEPROM.read(31))error = 1;
if(gyro_address != EEPROM.read(32))error
= 1;
if('J'!=EEPROM.read(33))error =1;
if('M'!=EEPROM.read(34))error=1
;if('B'!=EEPROM.read(35))error=1
;
if(error == 0){
Serial.println(F("Setup is finished."));
Serial.println(F("You can now calibrate the esc's and upload the YMFC-AL code."));
}
else{
Serial.println(F("The setup is aborted due to an error."));
Serial.println(F(""));
Serial.println(F(""));
}
while(1);
}
void start_gyro(){
//Setup the L3G4200D or L3GD20H
if(type == 2 || type == 3){
Wire.beginTransmission(address); //Start communication with the gyro
with the address found during search
Wire.write(0x20); //We want to write to register 1 (20 hex)
Wire.write(0x0F); //Set the register bits as 00001111 (Turn on
the gyro and enable all axis)
Wire.endTransmission(); //End the transmission with the gyro
}
//Setup the MPU-6050
if(type == 1){
}
}
voidgyro_signalen(){
if(type== 2 || type == 3){
Wire.beginTransmission(address); //Start communication with the gyro
Wire.write(168); //Start reading @ register 28h and auto
increment with every read
Wire.endTransmission(); //End the transmission
Wire.requestFrom(address, 6); //Request 6 bytes from the gyro
while(Wire.available() < 6); //Wait until the 6 bytes are received
lowByte = Wire.read(); //First received byte is the low part of the
angular data
highByte = Wire.read(); //Second received byte is the high part of
the angular data
gyro_roll = ((highByte<<8)|lowByte); //Multiply highByte by 256 (shift left
by 8) and ad lowByte
if(cal_int == 2000)gyro_roll -= gyro_roll_cal; //Only compensate after the
calibration
lowByte = Wire.read(); //First received byte is the low part of the
angular data
highByte = Wire.read(); //Second received byte is the high part of
the angular data
37
gyro_pitch = ((highByte<<8)|lowByte); //Multiply highByte by 256 (shift
left by 8) and ad lowByte
if(cal_int == 2000)gyro_pitch -= gyro_pitch_cal; //Only compensate after the
calibration
lowByte = Wire.read(); //First received byte is the low part of the
angular data
highByte = Wire.read(); //Second received byte is the high part of
the angular data
gyro_yaw = ((highByte<<8)|lowByte); //Multiply highByte by 256 (shift
left by 8) and ad lowByte
if(cal_int == 2000)gyro_yaw -= gyro_yaw_cal; //Only compensate after the
calibration
}
if(type == 1){
Wire.beginTransmission(address); //Start communication with the gyro
void check_to_continue(){
byte continue_byte = 0;
while(continue_byte ==
0){
if(channel_2_assign == 0b00000001 && receiver_input_channel_1 >
39
center_channel_1 + 150)continue_byte = 1;
if(channel_2_assign == 0b10000001 && receiver_input_channel_1 <
center_channel_1 - 150)continue_byte = 1;
if(channel_2_assign == 0b00000010 && receiver_input_channel_2 > center_channel_2 +
150)continue_byte = 1;
if(channel_2_assign == 0b10000010 && receiver_input_channel_2 <
center_channel_2 - 150)continue_byte = 1;
if(channel_2_assign == 0b00000011 && receiver_input_channel_3 > center_channel_3 +
150)continue_byte = 1;
if(channel_2_assign == 0b10000011 && receiver_input_channel_3 <
center_channel_3 - 150)continue_byte = 1;
if(channel_2_assign == 0b00000100 && receiver_input_channel_4 > center_channel_4 +
150)continue_byte = 1;
if(channel_2_assign == 0b10000100 && receiver_input_channel_4 <
center_channel_4 - 150)continue_byte = 1;
delay(100);
}
wait_sticks_zero();
}
//Register the min and max receiver values and exit when the sticks are back in the neutral
position
void
register_min_max(){
byte zero = 0;
low_channel_1 =
receiver_input_channel_1;
low_channel_2 =
receiver_input_channel_2;
low_channel_3 =
receiver_input_channel_3;
low_channel_4 =
receiver_input_channel_4;
while(receiver_input_channel_1 < center_channel_1 + 20 && receiver_input_channel_1 >
center_channel_1 - 20)delay(250);
Serial.println(F("Measuring
endpoints....")); while(zero < 15){
gyro_angle_pitch += gyro_pitch *
0.0000611; gyro_angle_yaw += gyro_yaw *
0.0000611;
}
if(trigger_axis == 0){
error = 1;
Serial.println(F("No angular motion is detected in the last 10 seconds!!! (ERROR 4)"));
}
else
if(movement == 1)roll_axis = trigger_axis;
if(movement == 2)pitch_axis = trigger_axis;
if(movement == 3)yaw_axis = trigger_axis;
}
//Channel 4=========================================
if(PINB & B00001000 ){ //Is input 11 high?
if(last_channel_4 == 0){ //Input 11 changed from 0 to 1
last_channel_4 = 1; //Remember current input state
timer_4 = current_time; //Set timer_4 to current_time
}
}
else if(last_channel_4 == 1){ //Input 11 is not high and changed from 1
to 0
last_channel_4 = 0; //Remember current input state
receiver_input_channel_4 = current_time - timer_4; //Channel 4 is current_time -
timer_4
}
}
//Intro subroutine
void intro(){
Serial.println(F("==================================================="));
delay(1500);
delay(500);
Serial.println(F(" "));
delay(500);
Serial.println(F("
Flight"))
; delay(500);
Serial.println(F("
Controller")
); delay(1000);
Serial.println(F(""));
Serial.println(F("Setup Program"));
Serial.println(F(""));
Serial.println(F("==================================================="));
delay(1500);
}
44
45
CHAPTER 5
RESULTS & FUTURE SCOPE
46
REFERENCES
[1] Quad Copter Flight Dynamics [INTERNATIONAL JOURNAL OF SCIENTIFIC &
TECHNOLOGY RESEARCH VOLUME 3, ISSUE 8, AUGUST 2014 by Mohd Khan]
[2] Design And Assembling Of A Low UAV [Umberto Papa1, Giuseppe Del Core2 Department
of Science and Technology, University of Naples "Parthenope"]
[3] Low Cost Microcontroller Based Hover Control Design Of A Quad Copter [Bernard Tat Meng
Leong, Sew Ming Low, Melanie Po-Leen Ooi, School of Engineering, Monash University, Sunway
Campus, Bandar Sunway, 46150 Selangor Darul Ehsan, Malaysia]
[4] Stability Control For Quadcopter With An Autonomous Flight System [ABDUL HALIM BIN
MOHD MUSTAFFA, Faculty of Electronic and Computer Engineering, University Teknikal Melaka
(UTeM)]
[5] Stabilization And Control Of Unmanned Quadcopter [Tomáš Jiinec Master of Science
Space Engineering - Space Master, Luleå University of Technology, Department of Computer
Science, Electrical and Space Engineering]
[6] Simple GUI Wireless Controller Of Quadcopter [Int'l J. of Communications, Network and System
Sciences, Vol.6 No.1(2013), Article ID:27464,8 pagesDOI:10.4236/ijcns.2013.61006 by Dirman
Hanafi1 , Mongkhun Qetkeaw1 , Rozaimi Ghazali1 , Mohd Nor Mohd Than1 , Wahyu Mulyo Utomo2 ,
Rosli Omar1 , University Tun Hussein Onn Malaysia]
[8] Algorithm Development And Testing Of Low Cost Waypoint Navigation System [IRACST –
Engineering Science and Technology: An International Journal (ESTIJ), ISSN: 2250-3498, Vol.3, No.2,
April 2013, by M.Rengarajan1, Dr.G.Anitha2, Division of Avionics Department of Aerospace
Engineering, M.I.T campus, Anna University Chennai]
[9] Design And Implementation Of Multitasking Flying Robot [Sahyadri R. Mane1, Prakash S.
Andhare2, Swapnali B. Gaikwad3 1,2,3Fabtech Technical Campus College of Engg. Sangola, Solapur,]
[11] Wireless Control Quadcopter With Stereo Camera [MONGKHUN QETKEAW A/L
VECHIAN, Faculty of Electrical and Electronics Engineering, University Tun Hussein Onn
Malaysia]
[12] Fertilizer Spraying Quadcopter Using Arduino UNO [ IJSTE - International Journal of
Science Technology & Engineering | Volume 3 | Issue 09 | March 2017]
[13] Design And Implementation Of A Real Time Wireless Quadcopter For Rescue
Operations [ Gordon Ononiwu1, Arinze Okoye2, James Onojo3, Nnaemeka Onuekwusi4 1, 2, 3, 4
(Department of Electrical and Electronic Engineering, Federal University of Technology Owerri,
Nigeria), American Journal of Engineering Research (AJER)]
[14] Quad Copter For Using Agricultural Surveillance [Advance in Electronic and Electric
Engineering, ISSN 2231-1297, Volume 3, Number 4 (2013), pp. 427-432, Parth N. Patel1, Malav A.
Patel2, Rahul
M. Faldu3and Yash R. Dave4, B.E. Mechatronics, Vallabh Vidyanagar, India]
[15] Research On The Use Of Drones In Precision Agriculture [George IPATE, Gheorghe
VOICU, Ion DINU]
47
[16] Use Of UAVS In USA [https://www.researchgate.net/publication/261493641, by
Eduardo I. Ortiz- Rivera, Ph.D Minds CREATE Research Team Leader, University of Puerto Rico-
Mayaguez, Dept. of Electrical and Computer Engineering & Angelina Estela, Carlos Romero,
Jesus A. Valentin, Department of Mechanical Engineering, Mayaguez, Puerto Rico]
[17] Quadcopter- Obstacle detection & Collision Avoidance [International Journal of
Engineering Trends and Technology (IJETT) – Volume 17 Number 2 – Nov 2014, Prathamesh
Salaskar1, Saee Paranjpe2, Jagdish Reddy3, Arish Shah4, Atharva College of Engineering,
University of Mumbai, India]
[18] Collision Avoidance Protocol For Package Delivering Quadcopter [Erick Camacho, Marco
Robaina, Alessandro Tasca, Pedro Cuberos, Ibrahim Tansel, Sabri Tosunoglu Florida International
University, Department of Mechanical and Materials Engineering 10555 West Flagler Street, Miami,
Florida]
[19] Towards The Development Of A Low Cost Airborne Sensing System To Monitor Dust
Particles After Blasting At Open Space [Miguel Alvarado, Felipe Gonzalez, Andrew Fletcher and
Ashray Doshi]
48