You are on page 1of 90

KWAME NKRUMAH UNIVERSITY OF SCIENCE AND TECHNOLOGY

KUMASI, GHANA

COLLEGE OF ENGINEERING

DEPARTMENT OF MECHANICAL ENGINEERING

PROGRAM: BSc. AEROSPACE ENGINEERING

YEAR: 2022/2023

PROJECT REPORT:

REDESIGN AND IMPLEMENTATION OF A QUADCOPTER FLIGHT CONTROL

SYSTEM WITH GPS TRACKING.

1
GROUP MEMBERS INDEX NO SIGNATURE

YORKE GEORGE K. 8343919 ……………….

HLORBU ROBERT KWAKU 8341519 ……………….

ANIM JEFFERSON KWAME OFEI 8339719 ….……………

NAPOGBONG GILBERT 8342419 ……………….

AFEDZIE JOANA 8338519 ……………….

BOATENG NANA ADWOA YEBOAH 8340719 ……………….

ADDAE ROBERT 8338219 ……………….

………………………………………. DATE: 21st AUGUST, 2023


DR. A. AGYEI-AGYEMANG
(SUPERVISOR)

2
DECLARATION

We hereby declare that this project report titled "Redesign and Implementation of the Flight

Control System of a Quadcopter" is based on our final year project work completed during our

studies under the supervision of Dr. A. Anthony Agyeman. elsewhere. We assert that our

research produced the statements made and the conclusions reached. Any external sources of

information used in this report have been duly cited and acknowledged. The contributions of

other individuals or organizations to this project have also been appropriately recognized. We

take full responsibility for the accuracy, completeness, and originality of the content presented

in this report. In instances where the work of others has been used or referred to, it has been

done so with proper attribution and in compliance with intellectual property rights.

3
ABSTRACT

This project focuses on the improvement and advancement of the flight control system for an

unmanned quadcopter, building upon the groundwork laid by the previous year group. The

primary objectives of this study were to achieve stable flight and implement an efficient GPS

tracking system to enhance the quadcopter's capabilities. The initial flight control system faced

challenges with instability during test flights, and the GPS tracking system remained

unimplemented. To address these issues, a comprehensive approach was undertaken, including

fine-tuning the flight control codes using PID (Proportional-Integral-Derivative) tuning

techniques, conducting thorough calibrations, and making necessary component changes.

Through a series of iterative improvements and rigorous test flights, we successfully achieved

stable flight and optimized the quadcopter's overall performance. Additionally, we developed

custom software for a ground station to implement GPS tracking, enabling real-time location

monitoring of the quadcopter. The successful implementation of these improvements

showcases the significance of building upon prior research to enhance unmanned aerial

vehicle technology, with potential applications in diverse industries such as surveillance,

mapping, and disaster response.

4
ACKNOWLEDGEMENT

We would like to take this opportunity to express our profound gratitude to all the individuals

who have supported and contributed to the successful completion of our project.

We begin by acknowledging the Almighty God for His blessings, guidance, and unwavering

support throughout this project. His divine presence has been a constant source of strength and

inspiration for us as a team.

We would like to extend our heartfelt appreciation to our project supervisor, Dr. A. Anthony

Agyeman, for his time, guidance, mentorship, and supervision in this project.

We are also immensely thankful to all the individuals who contributed financially to this

project, especially our parents/guardians. Their unwavering belief in our academic pursuits

and their generous financial support have made this project successful.

Furthermore, we extend our appreciation to Mr. Ernest Adomako for his assistance and

cooperation during the experimentation phase. His technical expertise and willingness to lend

a helping hand have been invaluable to the project's progress.

Lastly, we want to express our gratitude to to our predecessors who worked on this project

before us. Their efforts and contributions laid the foundation for our work and provided

valuable insights that guided our approach.

Thank you for believing in us and for making this project a reality.

5
Table of Contents

DECLARATION...........................................................................................................................
ACKNOWLEDGEMENT............................................................................................................
LIST OF FIGURES.......................................................................................................................
LIST OF TABLES.........................................................................................................................
LIST OF ABBREVIATIONS AND ACRONYMS...................................................................10
CHAPTER ONE..........................................................................................................................11
INTRODUCTION....................................................................................................................11
1.0 DESCRIPTION OF A QUADCOPTER...................................................................11
1.1 PROBLEM STATEMENT......................................................................................12
1.2 AIM................................................................................................................................12
1.3 OBJECTIVES...............................................................................................................12
1.4 ESSENCE OF THE PROJECT...................................................................................12
1.5 A SUMMARY OF THE METHODS TO BE USED:..................................................13
1.6 SUGGESTED SOLUTIONS FOR IDENTIFIED PROBLEMS................................14
CHAPTER TWO.........................................................................................................................15
2.0 LITERATURE REVIEW..............................................................................................15
2.1 DISCUSSION ON SIMILAR PROJECTS..................................................................19
2.2 UNDERSTANDING OF EMBEDDED SYSTEMS.....................................................20
2.3 IMPLEMENTING ARDUINO PROGRAMMING......................................................23
2.4 HOW A FLIGHT CONTROLLER WORKS................................................................24
2.5 QUADCOPTER STABILITY AND CONTROL...........................................................25
2.6 GPS TRACKING...........................................................................................................29
2.7 CONCLUSION..............................................................................................................30
CHAPTER THREE.....................................................................................................................31
METHODOLOGY...................................................................................................................31
3.0 INTRODUCTION..........................................................................................................31
3.1 PLANNING...................................................................................................................31
3.2 IMPLEMENTATION....................................................................................................34
3.3 TESTING AND CHECKING........................................................................................34
3.4 ANALYSIS AND CONCLUSION................................................................................35
CHAPTER FOUR.......................................................................................................................37
DETAILED DESIGN AND RESULTS..................................................................................37

6
4.0 COMPONENTS DESCRIPTION................................................................................37
4.1 ARDUINO LIBRARIES USED FOR CODING THE FLIGHT CONTROLLER
SYTEM.....................................................................................................................................46
4.2 ARDUINO FLIGHT CONTROLLER DESIGN CONCEPT.......................................49
4.3 THE GPS SYSTEM DESIGN CONCEPT.................................................................53
4.4 OTHER IMAGES FROM PROJRCT WORK..........................................................57
CHAPTER FIVE.........................................................................................................................62
CONCLUSION.........................................................................................................................62
REFERENCES............................................................................................................................63
APPENDIX A (FLIGHT CONTROLLER CODES)...............................................................66
APPENDIX B (GPS CODES).....................................................................................................82
APPENDIX C (LIST OF ITEMS ORDERED).........................................................................89

7
LIST OF FIGURES

Figure 2.1 A drone with an embedded system of electronic components.....................................17


Figure 2.2 A typical outline of a quadcopter with its essential components,
respectively……………………………………………………………………………….…...19
Figure 2.3 A simplified block diagram of a system with a P.I.D. controller………….............23
Figure 4.1 Arduino UNO Pinout, Specifications, Board Layout, and Pin Description……….39
Figure 4.2 Pin Out Diagram for MPU- 6050 with a 4.0 x 4.0 x 0.9 mm QFN………………..40
Figure 4.3 MPU-6050 with its typical operation circuits……………………………………..41
Figure 4.4 Arduino Nano schematic diagram…………………………………………………42
Figure 4.5 Neo-6m V2 GPS module…………………………………………………………..43
Figure 4.6 NRF24L01+ PA LNA Wireless Transceiver Module with External Antenna…….44
Figure 4.7 R/C Transmitter and Receiver……………………………………………………..46
Figure 4.8 final design of the flight controller system with GPS tracking……………………46
Figure 4.9 An image of some purchased components………………………………………...47
Figure 1.10 The schematic of the flight controller system……………………………………53
Figure 4.11 An image of the quadcopter with its flight controller after a flight test at Paa Joe
Stadium………………………………………………………………………………………..53
Figure 4.12 Schematic diagram of the GPS tracking system………………………………….55
Figure 4.13 Pictorial diagram of the GPS tracking system wired onboard the quadcopter…...55
Figure 4.14 Pictorial diagram of the GPS Ground Station……………………………………56
Figure 4.15 Images of the GPS application interface indicating our location………………...57
Figure 4.16 An image of the GPS System…………………………………………………….58
Figure 4.17 An image of sensor orientation test………………………………………………59
Figure 4.18 An image of circuit test…………………………………………………………..59
Figure 4.19 An image of components assembling and setup…………………………………60
Figure 4.20 Images of calibration……………………………………………………………..60
Figure 4.21 Images of developed quadcopter…………………………………………………61
Figure 4.22 Images of quadcopter
troubleshooting………………………………………………………………………………..61
Figure 4.23 Images of flight tests……………………………………………………………..62

8
LIST OF TABLES

Table 2.1 Summary of the effects of increasing different parameters to the system...................23
Table 4.1 Technical specifications of some components used in the study…………………...37
Table 4.2 Description of the pins……………………………………………………………...41
Table 4.3 Technical specifications of the Transmission module……………………………...43

9
LIST OF ABBREVIATIONS AND ACRONYMS

 UAV – Unmanned Air Vehicle.

 GCS - Ground Control Systems.

 ESC – Electronic Speed Controller.

 GPS - Global Positioning System.

 CPU - Central Processing Unit.

 RAM – Random Access Memory.

 DSP - Digital Signal Processors.

 ASIC - Application Specific Integrated Circuits.

 FPGA - Field-Programmable Gate Arrays.

 USB - Universal Serial Bus.

 API - Application Programming Interface.

 LED - Light Emitting Diode.

 IDE - Integrated Development Environment.

 IMU - Inertial Measurement Unit.

 AI - Artificial Intelligence.

 PID - Proportional-Integral-Derivative.

 PCB - Printed Circuit Board.

 EEPROM - Electrically Erasable Programmable Read-Only Memory.

10
CHAPTER ONE

INTRODUCTION

1.0 DESCRIPTION OF A QUADCOPTER


A quadcopter is a helicopter with four(4) rotors, two of which rotate in a clockwise direction

and the other two in a counterclockwise direction. Each rotor produces torque and lift. In

Unmanned Aerial Vehicle (UAV) research, quadcopters have gained much popularity.

Electric motors drive quadcopters and the direction in which the propellers spin is determined

by the direction of the motor's rotation. Control systems and sensors provide stabilization of

quadcopters' flight. Because of how the center of gravity and aerodynamic center are arranged,

they are more stable than helicopters, with the positioning of four propellers.

The quadcopter typically consists primarily of seven sections: Four motors, four electronic

speed controllers (E.S.C.), four propellers, an R.C. transmitter and receiver, a battery, a flight

controller, and the frame. A quadcopter's main structure, or skeleton, is the frame to which the

other parts will be attached. The quadcopter can fly because the motors drive the propellers.

For the motors to function effectively, the E.S.C. is a device that interprets flight controller

signals to determine the speed and direction of the motor. By spinning and creating an airflow,

the propellers give the drone lift. An R.C. transmitter-and-receiver is a wireless electronic

device that uses radio signals to transmit and receive signals. The battery optimally balances

the drone's performance and flight time. The quadcopter's brain is the flight controller. It

serves as a user interface for incorporating human input into the drone's flight pattern. It is a

small circuit board of varying complexity that directs the speed of each motor in response to

input.

11
1.1 PROBLEM STATEMENT
The Mechanical Engineering Department lacks a good Aerial Vehicle for Surveillance.

The Department’s quadcopter assigned to the team is unstable, and its Global

Positioning System(G.P.S.) is not functioning properly. The sensors onboard the

assigned quadcopter lacks good tuning.

Upon further examination of the previous work we identified that the deisgned flight

controller was not stable due to the lack of extensive PID tuning resulting in noise and

vibration on the mount affecting the sensor operations. Also, the GPS antenna was not

properly installed and connected to the GPS module.

1.2 AIM
This project aims to redesign and implement a flight control system using an Arduino

microcontroller with G.P.S. tracking.

1.3 OBJECTIVES
The specific objectives of the study are to:

1. Design the setup for the flight controller components of the quadcopter.

2. Develop Arduino program codes to run the flight controller on the quadcopter.

3. Develop a G.P.S. tracking system using an Arduino microcontroller

4. Test by flying the remote-controlled quadcopter.

1.4 ESSENCE OF THE PROJECT


Waypoint G.P.S. Navigation allows a drone to fly on its own with its flying destination

or points, preplanned and configured into the drone remote control navigational

software.

12
This gives the drone directions for where to fly, how high to fly, what speed to fly at,

and whether or not to hover at each waypoint. It is a drone's route and destination

planner.

Latitude, longitude, elevation, and compass direction may frequently be obtained from a

single device using a G.P.S. module that integrates a magnetometer and G.P.S. receiver.

For waypoint navigation and many other autonomous flight modes, G.P.S. is a crucial

prerequisite.

The suitable areas of a place can be surveyed using Waypoint G.P.S. navigation. The

pilot on the ground focuses on controlling the camera to shoot aerial pictures or videos

while the drone can fly directly to each designated destination. Additionally, the drone

travels the shortest distance to each waypoint to conserve battery life and video

recording.

Even more cutting-edge waypoint technology will be crucial for developing drones for

package delivery. Hiring a pilot for each drone that delivers packages would be

expensive. However, if drones are pre-configured to deliver packages with their target

waypoints, they can travel directly to the destination and then to the next place using the

quickest route.

Drone applications would be severely constrained without G.P.S. These intelligent

gadgets enable augmented reality games and capture stunning aerial photographs.

1.5 A SUMMARY OF THE METHODS TO BE USED:


• Literature review - Before beginning the project, previous projects related to ours will

be examined to learn both beneficial information and defects.

• The previously constructed drone was put through a flight test before being examined

to determine what modifications and enhancements were required.

13
• Concept generation, design, and evaluation - Several conceptual designs were created

and ranked according to pertinent performance.

• Development of the flight control system - A suitable flight controller and all

necessary avionics parts were selected. A flight controller with open-source firmware

was employed to enable capabilities like a return to home, remote telemetry, and

autonomous flight.

1.6 SUGGESTED SOLUTIONS FOR IDENTIFIED PROBLEMS.


1. Purchase and reassemble of new components.

2. Check the hardware including the motors, propellers ESC.

3. Perform basic tuning which involves adjusting the PID values fro roll, pitch, and

yawn to achieve stability.

4. Perfrom advanced tuning which includes notch filtering, feedforward control.

5. Test after each tuning adjustment an iterate settings until stability is achieved.

14
CHAPTER TWO

2.0 LITERATURE REVIEW

2.01 EARLY DEVELOPMENTS

The earliest invention of the quadcopter dates back to 1907 when Louis Breguet invented and

flew the first quadrotor helicopter. The drones were then used mainly by the U.S. army for

military purposes. The literal introduction of the quadcopter was in this century when

advances in electronics allowed the production of low-cost, lightweight flight controllers

capable of flying a UAV. Furthermore, several sensors were incorporated into the flight

controller to increase the stability of the quadcopter. These sensors were the accelerometer,

gyroscope, and magnetometer. This resulted in the popularity of quadcopters for small UAVs.

With their smaller dimension and maneuverability, the quadcopters were used for indoor and

outdoor applications. But in the preliminary phases, these quadcopters lacked essential

stability and controllability. Thus, new designs were incorporated into the quadcopters using

more stable sensors. These sensors increased the strength and allowed it to hover at a

predefined altitude. At this stage, the microcontrollers used were complex, and flight control

was also difficult due to errors from the controller output in basic stability and controllability.

2.02 SUBSEQUENT DEVELOPMENT

The addition of sophisticated and reliable sensors contributed to the drone's increased hovering

stability. The P.I.D. controller design, which uses a microcontroller, was used to regulate

hovering. This increased the need for drones in agriculture to monitor crops in a particular area

(Leong et al., 2012). However, the drones were still not advanced enough to carry out specific

duties. Future developments could have been possible.

15
Thus, to increase the drones' productivity in their missions, scientists included a few additional

sensors such as tilt sensors, infrared sensors, etc. The infrared sensor distinguishes the object

of interest from other objects based on differences in body radiation, while the tilt sensor

tracks the drone's pitch (Mustaffa, 2012). The drones were still less effective since it was

difficult to control them remotely, and they lacked sensors to track their whereabouts as they

flew. Later, scientists installed a Global Positioning System(G.P.S.) module that determined

the location of the area in which it was flying and transmitted that information to the remote

controller. WiFi, rather than conventional radio waves, is currently being used to connect the

quadcopter and remote controller. As a result, the controller's range was multiplied and could

now be remotely controlled. At this point, the quadcopter might fly a predetermined path

stored in the controller's memory (Mustaffa, 2012; Jiinec, 2011). Low wind speeds made it

comfortable to fly the drones inside. But because of the strong wind flow outside, it was

subject to aerodynamic drag forces. The sensors utilized lost stability since they couldn't

withstand the outdoor wind forces, and the drone eventually drifted away in the direction of

the wind flow (Jiinec, 2011). The sensors were improved in order to stabilize the flying.

However, the used outdated microcontrollers were incompatible with the sophisticated

sensors. As a result, in the last ten years, new microcontrollers have been developed that

supply the necessary output to the sensors and stabilize flight. The Arduino microcontroller is

the one that has been used the most up to this point since it is so simple to use and program

(Hanafi et al.,2013; Picas, 2014).

16
2.03 RECENT DEVELOPMENTS

Several advancements have been achieved in the field of quadcopters over the last decade as

they have evolved in design as well as in-flight controllability. This is due to the fact that

better microcontrollers are being used along with better sensors attached. The introduction of

the BME 280 (temperature, pressure as well as altitude) sensor along with the gyroscope

helped the drone in altitude hold control predetermined by the microcontroller. At this stage,

the G.U.I. at the remote station was improved to give the user a nice flight experience. The

drones proved useful in the military in remote package delivery missions. With the passage of

time, Arduino became a popular microcontroller for making drones because of its flexibility in

programming. Besides that, additional sensors like a camera; and ultrasonic sensors can be

attached to the drones. This helped the drones in calculating the distance from the ground,

which previously were unable to achieve. This revolutionary addition increased its popularity

several times. The drones could now be used in waypoint navigation systems. The coordinates

of the waypoints for predetermined flights are fed to the microcontroller. An algorithm is used

to calculate the distance between the present G.P.S. position to the first waypoint and the

heading angle of the present position with respect to the geographical north. In this process,

succeeding waypoints are calculated, and the quadrotor altitude control is done by the

controller-generated pulse width modulated (P.W.M.) signal, which can be used for security

surveillance, fire suppression, and for terrain mapping (Rengarajan & Anitha, 2013; Mane et

al., 2017). Also, similar other models are made using FY90 microcontrollers and are used in

coast guard surveillance and rescue missions ( Mahen et al., 2014). Infrared sensors attached

to the drones could search for live targets in rescue missions (Qetkeaw & Vechian, 2012). The

other demand for these drones is in the field of agriculture, where it is used for crop

17
surveillance, fertilizer spraying, and in precision agriculture. The infrared sensor attached to

the drones could identify healthy crops from infected ones. These drones reduced human

efforts and increased the monitoring quality of the crops (Emmanuel et al., 2017; Ononiwu et

al., 2016; Patel et al., 2013; Ipate et al., 2015). Another field where it can be useful is during

natural calamities to warn people of the situation and inform them about the safety measures

to be taken by incorporating microphone-enabled heat sensors with a camera for

reconnaissance. Here, for this additional security purposes, we need several components like a

microphone, pistol with immobilizing darts, heat-resistant frame, small medical devices, mini-

size quadcopter, and recognition devices (Ortiz-Rivera et al., 2012). The developments with

these drones are plenty. Previously, drones could follow a predetermined path. But the drone

was vulnerable to collisions. Lately, quadcopters are being designed which have the

technology of obstacle detection and collision avoidance. The quadcopters use a number of

ultrasonic sensors in coordination to detect objects around them and avoid them by using

simple algorithms. The signals from the sensors are controlled by an Arduino microcontroller.

Here, the signals from the sensors are integrated to give a collision avoidance display on the

remote controller, which can be used to control the quadcopter precisely. But then again, the

quadcopter could not provide the location to where it was traveling. This was eliminated when

a G.P.S. module was introduced in the system, which allows the quadcopter to fly between

two coordinates, avoiding a collision. This development found applications in package-

delivering systems and thus avoided collisions on the way (Salaskar et al., 2014; Camacho et

al., 2015). Latest developments have been made where the quadcopters are being controlled by

voice commands of the user or by simple hand gestures. These developments are still in the

initial stages but are soon to become a reality (Amar, 2016; Gaur et al., 2015). Others are

being controlled by voice commands of the user or by simple hand gestures. These

developments are still in the initial stages but are soon to become a reality (Amar, 2016; Gaur

18
et al., 2015). The designed system is based on programming the quadcopter using an Arduino

Uno R3 microcontroller. Also, there are several sensors embedded with the microcontroller for

atmospheric condition monitoring and finding its altitude, as well as magnetometer and gyro

cum accelerometer sensors for finding out the exact position of a quadcopter. The sensors are

connected to a WiFi-based microcontroller Integrated Circuit (I.C.) such that it will

automatically transmit the sensor details as and when required. So, remote monitoring is easily

achievable. The developed system is designed keeping in mind that the circuitry becomes less

complex and the cost remains low. Also, there will be a one-touch return button designed such

that it may return to its base location by pressing a single button. So, the quadcopter can never

be lost. This type of system can find its application for remote real-time atmospheric condition

monitoring of several areas specifically for crop production and irrigation without installing

the sensors at each and every location (Ghosh et al., 2018). Also, if a camera is installed, then

it can be used for surveillance applications.

2.1 DISCUSSION ON SIMILAR PROJECTS


An entire design concept for a flight controller is provided on the project hub of the official

Arduino website with the default code. Similar initiatives in the past have been successful. The

majority of them have posted their designs on numerous websites.Do It Yourself (D.I.Y.)

Electronic Lovers, Instructables, and droneLab are a few of them. The sensor used to identify

the quadcopters' orientation is the one thing that remains constant across all of these designs.

An Arduino Nano can be used, according to the Arduino community. The Nano can perform

tasks that other Arduino microcontrollers can. Our design makes use of an Arduino Uno,

19
which is frequently utilized in several projects across the globe. There is no specific

justification for this. The designer will choose one of the two based on their personal tastes.

With the addition of G.P.S., quadcopters have advanced to the point where they can now be

tracked, navigate using predefined paths, and return to their launch location in the case that

communication between the drone and the controller is lost.

Typically, G.P.S. is fitted, and other functions that fully utilize its capabilities are found on

medium-sized drones like the DJI Phantom or Parrot Bebop. The addition of G.P.S. has

changed how quadcopters travel, making it safer to use and simpler to find them. The

quadcopter's location's coordinates are provided via the project's G.P.S. system. Similar

projects feature more sophisticated systems with autopilot capabilities.

2.2 UNDERSTANDING OF EMBEDDED SYSTEMS


An embedded system is a hardware and software combination based on a microprocessor or

microcontroller and intended to carry out specific tasks within a broader mechanical or

electrical system. It is managed via instructions that are pre-programmed. A microcontroller is

an Integrated Circuit (I.C.) device that controls other components of an electronic system,

often through memory, peripherals, and a microprocessor unit (M.P.U.). These gadgets are

designed for embedded applications that need both computing power and quick, accurate

communication with electronic, digital, or analog parts. Microcontrollers are frequently

utilized in products and equipment that are automatically controlled because they may be built

for and used in embedded systems. As previously said, this functionality is produced by

combining a digital processor and memory with additional hardware that is specially made to

facilitate communication between the microcontroller and other parts. A central processing

unit (CPU), memory (volatile and nonvolatile), peripherals, and support circuitry make up a

20
microcontroller. Arduino Nano and Uno were used as the microcontrollers in the flight

controller design.

The Central Processing Unit (CPU):

The Central Processing Unit (CPU) carries out mathematical operations, controls data flow,

and produces control signals in line with the programmer's set of instructions. The designer

cannot see the incredibly intricate circuitry needed for CPU functioning.

Memory:

The program for the microcontroller—a list of machine-language instructions that specify to

the Central Processing Unit (CPU) what to do—is stored in nonvolatile memory. Instead of

nonvolatile memory, it is frequently referred to as "Flash," which denotes a particular type of

nonvolatile data storage. Temporary data is stored in volatile memory, often known as

Random Access Memory (RAM). When the power to the microcontroller is removed, data in

the RAM is lost.

Peripherals:

Hardware components known as peripherals enable a microcontroller to communicate with an

external system. Data converters, clock generation, timing, analog signal processing,

input/output, and serial communication are some of the hardware components that make up

this group.

Support Circuitry:

Because their main role is not to operate, monitor, or connect with external components,

microcontrollers integrate a range of functional blocks that cannot be categorized as

peripherals. Nevertheless, they are crucial for supporting the device's internal operations,

streamlining implementation, and enhancing the development process.

21
• Debugging circuitry enables firmware performance optimization by enabling the designer to

watch the microcontroller as it executes instructions.

• An essential component of microcontroller functionality is Interrupts. Interrupts are

hardware-based events that are either internal or external and trigger the processor to respond

by carrying out a particular set of instructions.

• Although the primary function of a microcontroller's internal oscillator is often to provide a

clock signal for the CPU and peripherals, a clock-generation module might be regarded as a

peripheral if it is designed to provide signals that will be used outside the device.

When a single microcontroller is included in a group of connected CPUs, peripherals, and

networks, it becomes more complicated. Depending on the task for which it is created, an

embedded system's complexity varies greatly.

Microcontrollers, Digital Signal Processors, Application Specific Integrated Circuits, Field-

Programmable Gate Arrays, Graphics Processing Unit Technology, and gate arrays are used to

control embedded systems. These processing systems have integrated parts for handling

mechanical and/or electrical interfaces.

Firmware for embedded systems, also known as software for the embedded system, is stored

in read-only memory or flash memory chips and operates with constrained computer hardware

resources because it is designed to carry out just particular functions.

Different types of microprocessors and controllers are used in Arduino board designs. The

boards have a variety of extension boards (called "shields"), breadboards (for prototyping),

and other circuits that can be interfaced to the sets of digital and analog input/output (I/O) pins

on the boards. The boards have serial communications interfaces, some of which support USB

(Universal Serial Bus), which are also used to load programs. The C and C++ programming

languages, as well as a common Application Programming Interface (API) often known as the

22
Arduino language, can be used to program microcontrollers. Figures 2.1 shows a drone with

an embedded system of electronic components.

Figure 2.2 A drone with an embedded system

of electronic components

2.3 IMPLEMENTING ARDUINO PROGRAMMING


Arduino is a free and open-source hardware and software prototyping platform. An Arduino

board can receive inputs, such as light on a sensor or pressure on a button, and convert them

into outputs such as starting a motor or turning on a light-emitting diode (L.E.D.). The

Arduino Boards can be used to carry out the desired activities after being programmed using

the Arduino Integrated Development Environment (IDE).

Each quadcopter can typically move in three different directions: roll, yaw, and pitch. The

thrust that each rotor generates governs each of these actions. In order to release the necessary

23
power for flight and to which rotor at any given time, the controller must be programmed at

some time.

Every quadcopter comes equipped with a microcontroller board, in this example, the Arduino

board, which has sensors on it. The motors are controlled by this board and the components

that were selected. The components chosen depend on how autonomous the quadcopter should

be. In order for the quadcopter to be able to recognize and avoid objects that are in the course

of a flight, one may alternatively use only a few simple components, such as the gyroscope, or

a variety of other, more sophisticated sensors, such as the barometer, a G.P.S. module, or even

a sonar module.

You may see with your own eyes and examine the log of sensor data utilized for each

acceleration and angular change in direction to determine a quadcopter's maneuvering stability

coordinates on three axes. The frame and certain components are already attached to the

building because this is a continuation of a project started by our forebears. With a pre-

programmed flight controller, the quadcopter was put through a variety of flying test

sequences and showed success in the air.

2.4 HOW A FLIGHT CONTROLLER WORKS


The primary control mechanism in a quadcopter is a flight controller. It is a compact circuit

board with a range of complexity that includes Arduino Uno, Nano, Mega, G.P.S., a compass,

and an Inertial Measurement Unit (IMU).

In a quadcopter, the flight controller precisely regulates the four motors' rotational speeds at

the same time to maintain the aircraft's balance while in flight. The remote control's radio

transmitter in the remote sends radio signals to the drone's receiver when the pedal stick is

24
depressed. Input signals from the receiver are processed by the flight controller, which then

generates commands to control each motor's revolution per minute(rpm) speed. The electronic

speed controller is provided in this order to adjust the motors in accordance with the desired

movement of the quadcopter Gyroscopes are used by the flight controller to detect its

orientation, while barometers are used to maintain altitude automatically in order to aid in

computations.

Figure 2.2 depicts the general shape of a quadcopter and its constituent parts.

Figure 2.2
3.2 A typical outline of a quadcopter with its essential components, respectively

2.5 QUADCOPTER STABILITY AND CONTROL

Different controller types are employed in ordinary tasks, lab work, and industry. On/off,

Proportional-Integral-Differential (P.I.D.), fuzzy logic, and neural are a few of the often

employed controllers. The latter two are rather more complicated and make use of Artificial

25
Intelligence (A.I.) ideas. It is also possible to distinguish between "feedforward" and

"feedback" controllers. The feedback controller functions by providing an observed result that

modifies the processing value of the subsequent step, whereas the feedforward controller

provides a result based on the anticipation of the subsequent step. Proportional Integral and

Derivative is referred to as P.I.D. The P.I.D. algorithm-based feedback control system is the

sole focus of this project.

(a) PID CONTROL


PID control is a combination of proportional (linear part), integral, and differential control that

is widely used in the robotics and automation industry. The first evolution of the P.I.D.

controller was developed in 1911 by Elmer Sperry. However, it was not until 1933 that the

Taylor Instrumental Company (T.I.C.) introduced the first pneumatic controller with a fully

tunable proportional control. A few years later, control engineers eliminated the steady state

error found in proportional controllers by resetting the point to some artificial value as long as

the error was not zero. This resetting integrated the error and became known as the

Proportional-Integral controller. Then, in 1940, T.I.C. developed the first P.I.D. pneumatic

controller with a derivative action, which reduced overshooting issues. However, it was not

until 1942, when Ziegler and Nichols' tuning rules were introduced, that engineers were able

to find and set the appropriate parameters of P.I.D. controllers. By the mid-1950s, automatic

P.I.D. controllers were widely adopted for industrial use.

Not until 1942, when Ziegler and Nichols tuning rules were introduced, that engineers were

able to find and set the appropriate parameters of P.I.D. controllers. By the mid-1950s,

automatic P.I.D. controllers were widely adopted for industrial use (O.E., 1996).

The P.I.D. control algorithm has been considered and implemented to control the hover

altitude of the quadcopter. The P.I.D. algorithm is popularly used mainly because:

26
 It has a simple structure

 It provides good performance

 It can be tuned even if the specific model of the controlled plant or system is not

available

 The final element is crucial because it was challenging to obtain an accurate

mathematical model of the quadcopter. When a measured output is compared to a

desired set point, a P.I.D. controller calculates the error or difference between the two

and makes adjustments to the system control inputs to reduce the computed error.

Three control parameters, P – Proportional, I – Integral, and D – Derivative, make up

the majority of the P.I.D. algorithm.

The error and an adjustable factor are the only components of the proportional term

(P). The algorithm can reduce the difference between the actual and desired values by

adjusting the factor. This indicates that when the error is at its peak, the proportionate

term has the biggest impact. The impact of the actual value approaching the desired

value of the proportionate term begins to decrease. The proportional term's drawback is

that when used as the only governing mechanism, it produces a steady-state

inaccuracy. Because of the way proportional control operates, the steady-state error is a

by-product; if the error is eliminated, the signal produced will likewise be eliminated.

As a result, although the actual value eventually comes near the intended number, it

never does.

The accumulated inaccuracy over time as the drone progresses to the intended state is taken

into account by the integral term (I). The integral term has a factor that the controller

continuously adjusts as the drone flies, much like the proportional term does. The integral term

considers the accumulated error, which can be either negative or positive. This translates to a

27
decreasing impact of the integral term as the actual value fluctuates between negative and

positive error margins. The integral term resolves the steady-state error issue by delaying the

initial attempt at zeroing out the correction. This indicates that as the actual value approaches

the target value, the controller continues to operate. It is noted that the integral term doesn't

actually become zero until after many oscillations.

While this feature addresses one issue, it also raises a new one because the quadcopter can

take a very long time to stabilize as it is continually exceeding the desired number.

The derivative term (D) responds to the error's rate of progression. The differential term takes

into account how quickly the inaccuracy in the signal changes over time. As the actual value

becomes closer to the desired value, the differential term decreases the rate of correction the

controller applies. As a result, the rate of approach to the intended value is slowed down,

which reduces the overshoot that results. The differential term aids a controller in achieving

the intended value faster by resolving a limitation brought on by the integral term.

Figure 2.3 depicts a condensed block diagram of a system having a P.I.D. controller. The

results of altering these parameters in the system are also summarized in Table 2.1.

The equation below gives the discrete-time P.I.D. algorithm's mathematical expression.
k
de
. u ( k ) =K P e ( k ) + K i ∑ e (i)+ K p ( ) …………………Equation 2.1
i=0 dt

u (k) = PID control variable

Kp = proportional gain

e (i) = error value taken care of by the integral

e (k) = error value taken care of by the proportional

Ki = integral gain

de = change in error value

dt = change in time

28
Table 2.1 Summary of the effects of increasing different parameters to the system

Closed Loop Response Rise Time Overshoot Settling Time Steady-State Error Stability
Increasing K p Decrease Increase Small Increase Decrease Degrade
Increasing K i Small Decrease Increase Increase Large Decrease Degrade
Increasing K d Small Decrease Decrease Decrease Minor Change Improve

Figure 2.3 A simplified block diagram of a system with a P.I.D controller

2.6 GPS TRACKING


At the height of the Cold War in the 1960s, G.P.S. tracking was initially developed for

military and intelligence applications. The global positioning system (G.P.S.), which took its

cue from the Soviet spacecraft Sputnik in 1957, consists of a network of satellites circling the

earth at fixed positions above the planet and beaming signals down to everyone on earth using

a G.P.S. tracking device.

In order to operate a drone, navigation is crucial. Consequently, a concept known as Waypoint

G.P.S. Navigation was used. Waypoints are coordinate sets that specify a location in actual

space. Waypoints are becoming more abstract and frequently have no evident connection to

any distinguishing characteristics of the outside world. These waypoints are used to define

navigational invisible routing pathways. The pilot can customize this to tell the drone where to

29
fly, at what height, and at what speed. It may be described as a drone route and destination

planner.

Latitude, longitude, elevation, and compass direction may frequently be obtained from a single

device using a G.P.S. module that integrates a magnetometer and G.P.S. receiver. For

waypoint navigation and many other autonomous flight modes, G.P.S. is a crucial prerequisite.

The right areas of a place can be surveyed using Waypoint G.P.S. navigation. The pilot on the

ground focuses on operating the camera to take aerial pictures or videos, while a drone can be

pre-configured to fly directly to each designated destination. Additionally, the drone travels

the quickest path to each waypoint to conserve power and video recording.

2.7 CONCLUSION
The purpose of the literature study was to provide the reader with a comprehensive overview

of the numerous processes that come together to form the project, as well as a description and

various developments.

30
CHAPTER THREE

METHODOLOGY

3.0 INTRODUCTION
The goal of this project is to create a GPS-tracking flight control system for quadcopters. The

project’s initial step was to determine whether Arduino could operate and stabilize a

quadcopter. Analogous endeavors were looked into. The approaches that were employed to

accomplish the project’s goals will be thoroughly explained in this chapter. Four important

phases were taken in order to evaluate this project: planning, implementing, testing and

analysis.

3.1 PLANNING
Planning must be done correctly in order to identify all the data and requirements, including

hardware and software. Data gathering and hardware and software requirements are the two

key components of the planning phase. To visualize the design in simpler formats, the project

required discovering and learning how to utilize the Arduino IDE, proteus, and a few graphic

design programs. This article has provided a quick explanation of planning.

(a) COMPONENT SELECTION

For a quadcopter to stay in the air, certain conditions must be met. These include:

 Altitude: The flight controller system measures the altitude of the quadcopter

using a barometer, which senses the changes in air pressure, The barometer

helps the flight controller maintain a stable altitude during flight.

31
 Airspeed: Some flight controller systems measure airspeed using a pitot tube.

The pitot tube senses the difference in air pressure between the front and back

of the tube, which is used to calculate airspeed.

 Wind speed and direction: Some flight controller systems measure wind speed and

direction using a anemometer. Wind speed and direction are important to consider

when controlling the quadcopter’s position and speed during flight.

 Temperature and humidity: Some flight controllers systems measure temperature and

humidity using sensors. Temperature and humidity can affect the quadcopter’s flight

characteristics and should be taken into account during flight

 Attitude and orientation; The flight controller system measures the quadcopter’s

attitude and orientation using sensors such as accelerometers and gyroscopes. This data

can is used to maintain stability and control the quadcopter’s movement during flight.

 GPS data: The flight controller system uses GPS data to determine the quadcopter’s

position and altitude. This information is used to maintain stability and control the

quadcopter’s movement during autonomous flight modes.

The necessary components was chosen based on the quadcopter flight-related parameters.

Without the transfer of data to and from the quadcopter, control and stability of the device

would not be possible. The necessary component must allow quick and simple data transfer,

which is necessary for the quadcopter to respond quickly. The project’s plan was influenced

by these parameters.

(b) HARDWARE REQUIREMENTS

32
The hardware that is listed in this part was all purchased, proved to be useful, and was

required for the project. How quickly the components are bought will determine when the

project will be finished. All of these are taken into account in the project plan.

 Adriuno Uno R3

 5000mAh lipo battery

 Spark 9Dof

 Neo 6m GPS module

 MPL 3115/2 Barometer pressure/altitude/temperature sensor

 Jumper wires

 Pin headers

 Arduino Nano

 MPU-6050 attitude sensor compass accelerator Gyro Module

 Resistors (1.5k, 1k, 330 ohms)

 1 A Diode 1N4001

(c) FUNCTIONAL REQUIREMENTS

There are two fundamental needs for the project. These are to perform sustained flight and

GPS location transmission to a base station. The following specifications for the

components must be met:

• The components must be able to communicate with the microcontroller and receive

signals from it.

• Accurate measurement of a quantity is a requirement for components to ensure the

quadcopter's smooth operation.

(d) SOFTWARE REQUIREMENTS

Whether a circuit is formed using wires on a porous board or a printed circuit board

33
(PCB), the software needed to design it relies on the circuit's architecture. Using Proteus

software, the circuit's schematic diagram was created. The Arduino IDE is by far the best-

integrated development environment since it is straightforward and ready to use in any

Arduino-based design. It was utilized as an interpreter for C++ programming language

codes. Lastly, using graphic design software like Illustrator, it was simple to create the

building block diagrams to illustrate the design.

(e) DATA COLLECTION AND RESEARCH STRATEGY

In any field of study, data collecting is a necessary step. At this point, the project's

resources and requirements, literature reviews, etc. were prepared. All of the necessary

information was acquired from journals. books. and research papers located online and in

libraries. The emphasis in the first few weeks of the semester was on learning the basics

of the project. The extensive resources available on the internet were mostly used for this

Other professionals who worked on related projects were found after carefully reviewing

and analyzing every component of the project. This provided the team with detailed

information on what was necessary to complete the project successfully and paved the

path for choosing the right components. Overall, extreme precautions were made to make

sure that every component was purchased in time for the project's early start.

3.2 IMPLEMENTATION
All of the planning phase's procedures or stages had been implemented by this point. To verify

the correct operation of sensors and other components, all purchased components were

calibrated, and the telemetry of the quadcopter was checked and tested. The microcontroller

was created and programmed with the necessary programming codes for controlling the

34
quadcopter. Programmed scripts were also used to create the quadcopter's GPS system.

Outcomes of the aforementioned scripts were acquired following system testing and analysis.

3.3 TESTING AND CHECKING


After the installation of the various components on quadcopter were finished, the entirey of

the circuit's track was examined. This task was making sure that the circuit will function

properly. The multimeter was the device used to check the continuity and various electrical

properties of each circuit track before soldering. While testing, it warns the user of a failed

continuity by employing a buzzer multimeter. Furthermore, vibrations could result in

significant PID code problems, therefore dampening of sensors is crucial once all connections

have been verified. Each element has undergone testing. The principal tests performed consist

of:

1. Motor Testing

2. Sensor and Orientation Tests

3. GPS tracking test

The quadcopter also needed to go through a series of flight tests to verify if the dampening

of the main sensors was done correctly. Calibration is the most crucial factor that guarantees

the success of the test.

CALIBRATION

The inertial measurement unit's (IMU) gyro or compass needed to be calibrated before the

drone was first flown outside. This entails comparing the measurement produced by the

sensors to a known measurement, which is standard. The flight controller, IMU, and gyro

stabilization are crucial for the quadcopter to fly successfully. At the starting position, the

pilot's commands are based on the standard established by the sensors' measurements on the

35
ground. Performance significantly changes when the quadcopter is calibrated at the

appropriate time. Calibration should be performed if there are any anomalies following any

crashing.

3.4 ANALYSIS AND CONCLUSION


The two points of interest were examined during the analysis stage, which served as the last

step in our methodology. Initially, it was dependent on the operation and output of the flight

controller system. Finding the results based on the test flight and making modifications as

necessary constituted the second point of consideration.

36
CHAPTER FOUR

DETAILED DESIGN AND RESULTS

The project encompasses two distinct systems, each serving a specific purpose:

 The Arduino flight control system

 The GPS system.

4.0 COMPONENTS DESCRIPTION

ARDUINO UNO

Arduino Uno is a microcontroller board based on the ATmega328P (datasheet). It has 14

digital input/output pins (of which 6 can be used as PWM outputs), 6 analog inputs, a 16 MHz

ceramic resonator, a USB connection, a power jack, an ICSP header and a reset button. Figure

4.1 shows an Arduino UNO Pinout, Specifications, Board Layout, and Pin Description. Table

4.1 gives the technical specifications of some components used in the study.

Table 4.1 Technical specifications of some components used in the study

37
Microcontroller ATmega328P

Operating Voltage 5V

Input Voltage (recommended) 7-12V

Input Voltage (limit) 6-20V

Digital I/O Pins 14 (of which 6 provide PWM output)

PWM Digital I/O Pins 6

Analog Input Pins 6

DC Current per I/O Pin 20 Ma

DC Current for 3.3V Pin 50 mA

Flash Memory 32 KB (ATmega328P) of which 0.5 KB used by bootloader

SRAM 2 KB (ATmega328P)

EEPROM 1 KB (ATmega328P)

Clock Speed 16 MHz

LED_BUILTIN 13

Length 68.6 mm

Width 53.4 mm

Weight 25 g

Figure 4.1 Arduino UNO Pinout, Specifications, Board Layout, and Pin Description

MPU 6050

MPU-6050 is an integrated 6-axis motion-processing component. Compared with the multi-

component solution, it eliminates the problem of axis difference when combining the

gyroscope and accelerator and reduces a lot of packaging space. MPU-6050 integrates a 3-axis

gyroscope, a 3-axis accelerometer, and includes a digital motion processor, which processes

38
complex 6-axis MotionFusion algorithms. The device can access external magnetometers or

other sensors through an auxiliary master I²C bus, allowing the devices to gather a full set of

sensor data without intervention from the system processor. The devices are offered in a 4 mm

x 4 mm x 0.9 mm QFN package.

The MPU-6050 incorporates InvenSense’s MotionFusion and run-time calibration firmware

that enables manufacturers to eliminate the costly and complex selection, qualification, and

system level integration of discrete devices in motion-enabled products, guaranteeing that

sensor fusion algorithms and calibration procedures deliver optimal performance for

consumers.

For precision tracking of both fast and slow motions, the parts feature a user-programmable

gyro full-scale range of ±250, ±500, ±1000, and ±2000 °/sec (dps), and a user-programmable

accelerometer full-scale range of ±2g, ±4g, ±8g, and ±16g.

Additional features include an embedded temperature sensor and an on-chip oscillator with

±1% variation over the operating temperature range. MPU-6050 can work under different

voltages, and the VCC supply voltage value is 3.3V or 5.0V.

Below is Figure 4.2, which shows a Pin Out Diagram for MPU- 6050 with a 4.0 x 4.0 x 0.9

mm QFN whilst Figure 4.3 shows an MPU-6050 with its typical operation circuits.

Figure 4.2 Pin Out Diagram for MPU- 6050 with a 4.0 x 4.0 x 0.9 mm QFN

39
Figure 4.3 MPU-6050 with its typical operation circuits

ARDUINO NANO

The Arduino Nano is a small, complete microcontroller, and breadboard-friendly board based

on the ATmega328, which processes all instructions and swiftly carries out all mathematical

and logical operations. It lacks only a DC power jack and works with a Mini-B USB cable

instead of a standard one. It is part of the GPS System. The Arduino Nano operates with a very

small voltage of 5V. It has 14 digital input-output pins of which six provides Pulse Width

Modulator (PWM) output along with eight analog input pins.

It has 32 kB of flash memory, which helps in easy storage of data and efficient processing of

signals. Essential features, which make the board very efficient, are its lightweight and small

dimensions.

One convenient feature is that, it is relatively easier to program in C/Java language

overcoming the complexity of assembly level coding. Arduino Nano comes with a very useful

serial library software, which enables easy serial communication on any of the digital pins of

Arduino Nano. Figure 4.4 shows an Arduino Nano schematic diagram.

40
Figure 4.4 Arduino

NEO-6M V2 GPS MODULE

The NEO-6M V2 is a GPS (Global Positioning System) module and is used for navigation.

The module simply checks its location on earth and provides output data, which is longitude

and latitude of its position. The module has four output pins and the function of each pin will

be discussed. The powering of module and communication interface is done through these

four pins. Figure 4.5 shows a Neo-6m V2 GPS module. Table 4.2 gives the description of the

pins.

Table 4.2 Description of the pins


Pin Name Description

VCC Positive power pin

RX UART receive pin

TX UART transmit pin

41
GND Ground

Features and Electrical Characteristics of the GPS module

 Standalone GPS receiver

 Anti-jamming technology

 UART Interface at the output pins (Can use SPI, I2C and USB by soldering pins to the

chip core)

 Under 1 second time-to-first fix for hot and aided starts

 Receiver type: 50 Channels - GPS L1 frequency - SBAS (WAAS, EGNOS, MSAS,

GAGAN)

 Time-To-First fix: For Cold Start 32s, For Warm Start 23s, For Hot Start <1s

o Maximum navigation update rate: 5 Hz

o Default baud rate: 9600 bps

o EEPROM with battery backup

o Sensitivity: -160 dBm

o Supply voltage: 3.6 V

o Maximum DC current at any output: 10 mA

o Operation limits: Gravity-4g, Altitude-50000 m, Velocity-500 m/s

o Operating temperature range: -40 ºC TO 85 °C

42
Figure 4.5 Neo-6m V2 GPS module

NRF24L01 WIRELESS DATA TRANSMISSION MODULE

The NRF24L01+ transceiver module is designed to operate in 2.4 GHz worldwide ISM

(industrial, scientific and medical) frequency band and uses GFSK (Gaussian Frequency Shift

Keying) modulation for data transmission. The data transfer rate can be one of 250kbps,

1Mbps and 2Mbps. This module would be employed for telemetry purposes. Figure 4.6 shows

an NRF24L01+ PA LNA Wireless Transceiver Module with External Antenna. Table 4.3

shows the technical specifications of the Transmission module.

Table 4.3 Technical specifications of the Transmission module


Frequency Range 2.4 GHz ISM Band

Maximum Air Data Rate 2 Mb/s

Modulation Format GFSK

Max. Output Power 0 dBm

Operating Supply Voltage 1.9 V to 3.6 V

Max. Operating Current 13.5mA

Min. Current (Standby Mode) 26µA

Logic Inputs 5V Tolerant

Communication Range 800+ m (line of sight)

43
Figure 4.6 NRF24L01+ PA LNA Wireless Transceiver Module with External Antenna

RADIO CONTROLLED(R/C) TRANSMITTER AND RECEIVER

Radio transmitters use radio signals to remotely control quadcopters in a wireless manner. The

commands given by transmitter are received by a radio receiver via a flight controller. The

number of channels in the transmitter determine the actions that can be controlled by the pilot.

A minimum of four channels are needed to control a quadcopter (which includes pitch, roll,

throttle, and yaw).

The stick control on radio transmitter is known as gimbal. The RC receiver used, operates on

2.4 GHz of radio frequency (unless you do not have any specific need for a different

frequency). A typical transmitter has about 4 to 6 channels with at least four of them being

proportional, which means the controlled surfaces or devices will move proportionally to the

movements of the control sticks. Additional channels may function like a switch, which could

actuate retractable landing gears, airbrakes and lamps.

Figure 4.7 shows an R/C Transmitter and Receiver.

Figure 4.8 shows the final design of the flight controller system with GPS tracking.

Figure 4.9 shows an image of some purchased components.

44
Figure 4.7 R/C Transmitter and Receiver

Figure 4.8 final design of the flight controller system with GPS tracking

45
Figure 4.9 An image of some purchased components.

4.1 ARDUINO LIBRARIES USED FOR CODING THE FLIGHT

CONTROLLER SYTEM

WIRE.h LIBRARY

This library enables communication with the gyroscope.

EEPROM.h LIBRARY

This library enables storage of information onto the EEPROM (electrically erasable

programmable read-only memory) which is a type of non-volatile memory used in computers,

integrated in microcontrollers for smart cards and remote keyless systems.

46
NRF24L01 LIBRARY

This library was created to simplify the use of the widely available nrf24l01+ radio module

with the PIC32 microcontroller. It provides a relatively short set of functions that allow the

user to take advantage of all the major functionality of the nrf24l01+ without needing to worry

about the hardware of the radio.

TINYGPS++ LIBRARY

For the Arduino GPS tracker, the GY-NEO6MV2 GPS module was used. To use the GPS

module with the Arduino, the GPS library must be downloaded. The GPS library used for the

aforementioned GPS module is TinyGPS++. TinyGPS++ is a new Arduino library for parsing

NMEA (National Marine Electronics Association) data streams provided by GPS modules.

This library provides compact and easy-to-use methods for extracting position, date, time,

altitude, speed, and course from consumer GPS devices. The new library can extract arbitrary

data from any of the myriad NMEA sentences out there, even proprietary ones.

Adding the TinyGPS++ Library to the Arduino Libraries

The TinyGPS++ library was downloaded from the http://arduiniana.org/libraries/tinygpsplus/.

The library was then added to the Arduino libraries by following the steps below:

1. Download the zip folder from the site mentioned above.

2. Open the zip folder and move the TinyGps++ folder to the desktop.

3. Rename the folder TinyGPSPlus_master.

4. Open the Arduino IDE.

5. Go to file and select preferences.

6. Copy the sketchbook location and then close the IDE.

47
7. Open any folder on your computer and then paste the sketchbook location there.

8. All the Arduino libraries will be displayed. Select libraries.

9. Drag the TinyGPSPlus_master folder from the desktop to the libraries.

10. Open the Arduino IDE, go to sketch, select include library. It will be added to the

library.

SOFTWARE SERIAL LIBRARY

The software serial library was also used in writing the code for the GPS tracker. The Arduino

hardware has built-in support for serial communication on pins 0 and 1 (which also goes to the

computer via the USB connection). The native serial support happens via a piece of hardware

(built into the chip) called a UART (universal asynchronous receiver-transmitter). This

hardware allows the Atmega chip to receive serial communication even while working on

other tasks, as long as there’s room in the 64byte serial buffer.

The SoftwareSerial library has been developed to allow serial communication on other digital

pins of the Arduino, using software to replicate the functionality (hence the name

"SoftwareSerial"). It is possible to have multiple software serial ports with speeds up to

115200 bps. A parameter enables inverted signaling for devices which require that protocol.

Limitations

The library has the following known limitations:

 If multiple software serial ports are used, only one can receive data at a time.

48
 Not all pins on the Mega and Mega 2560 support change interrupts, so only the

following can be used for RX: 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63),

A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69).

 Not all pins on the Leonardo and Micro support change interrupts, so only the

following can be used for RX: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).

 On Arduino or Genuino 101 the current maximum RX speed is 57600bps

 On Arduino or Genuino 101 RX doesn't work on Pin 13

If as project requires simultaneous data flows, see Paul Stoffregen’s AltSoftSerial

library. AltSoftSerial overcomes a number of other issues with the core SoftwareSerial, but

has its own limitations. Figure 4.13 shows a setup of the Arduino Neo 6M GPS model with the

Arduino Nano before transmission whilst Figure 4.14 shows the data (latitude, longitude and

altitude) from the Arduino Neo 6M GPS module in sync with the Arduino Nano during

calibration and testing

4.2 ARDUINO FLIGHT CONTROLLER DESIGN CONCEPT

DESCRIPTION

The flight controller runs on the Arduino Uno. This is responsible for calculating the

quadcopter’s current angle, and stabilize it from there. Additionally, it takes the remote

controller's input so that the pilot can control the quadcopter. This is done via the receiver

located on the quadcopter.

49
The Electronic speed controllers and receiver channels are connected to the Arduino Uno via

digital pins for transfer of signals. The Uno is supplied with power tapped from the battery

through the sensor shield for voltage regulation. The Esc signal connectors are all grounded

via the receiver. The inertial measurement unit (sensors) are connected to the Arduino Uno. It

helps the quadcopter determine orientation.

Here are the Schematic connections for the flight controller board:

ARDUINO UNO Connections:

 D4-D7 << ESC SIGNAL

 D8-D11 << RECEIVER CHANNELS

 Vin << RECEIVER POWER CH5

 GND << RECEIVER GND CH5

ESC Connections:

 D4 << ESC 1 SIGNAL PIN (Right front)

 D5 << ESC 4 SIGNAL PIN (Right Rear)

 D6 << ESC 2 SIGNAL PIN (Left Rear)

 D7 << ESC 3 SIGNAL PIN (Left Front)

RECEIVER Connections:

 D8 << CH1 (PITCH)

 D9 << CH2 (ROLL)

 D10 << CH3 (THROTTLE)

 D11 << CH4 (YAW)

 POWER << POWER BATTERY

50
 GND << GND BATTERY

IMU (MPU 6050) Connections:

 SDA MPU << SDA UNO (A4)

 SCL MPU << SCL UNO (A5)

 5V << Vin/VCC (UNO)

 GND << GND (UNO)

RADIO COMMUNICATION PROTOCOLS

Radio communication protocols can split into two groups:

 TX Protocols between Radio Transmitter and Radio Receiver.

 RX Protocols between Radio Receiver and Flight Controller

In a systematic procedure of what should occur for the flight controller to achieve its function,

the following occurs:

1. The R/C transmitter bonded to the receiver communicates with the quadcopter by

giving a command.

2. The receiver communicates with the flight controller system by sending a signal.

3. The MPU provides the control with real-time orientation of the quadcopter.

4. The PID controller, which is the Arduino Uno, compares the set point signals values

received and actual signal values to obtain error.

5. The error is used to adjust motor speeds in order to obtain the required maneuver

demanded by the pilot.

6. This goes for all commands received by the flight controller.

The components were synchronized to provide data for the operation and control of the

quadcopter (QUAD 4). These components were calibrated on ground and programmed in the

Arduino IDE to build the flight control system, which is the brain of the quadcopter. The flight

51
controller controls the stability and movement of the QUAD4. Figure 4.1 shows the schematic

of the flight controller system and Figure 4.2 shows an image of the quadcopter with its flight

controller after a flight test at PAA JOE STADIUM.

52
Figure 4.11 An image of the quadcopter with its flight controller after a flight test at Paa

Joe Stadium

4.3 THE GPS SYSTEM DESIGN CONCEPT

The GPS system consists of components such as the GPS module, the NRF transmitter,

Arduino Nano and the ground station. The ground station is made up of the laptop, Arduino

Uno and the receiver. The GPS data is transferred through the Nano then through the NRF

53
transmitter. The data is received by the receiver at the ground station. The location of the

quadcopter is then displayed on the laptop.

These are schematic connections for the GPS system:

ARDUINO NANO Connections:

 D6 << TXD (GPS)

 D5 << RXD (GPS)

 5V<< Vcc (GPS)

 GND << GND (GPS)

 3V3<< Vcc (NRF)

 GND << GND (NRF)

 D8 << CSN (NRF)

 D7 << CE (NRF)

 D11 << MOSI (NRF)

 D12 <MISO (NRF)

 D13 << SCK (NRF)

RADIO COMMUNICATION PROTOCOLS

Radio communication protocols can be split into two groups:

 TX and RX Protocols between NRF Transmitter and Receiver in the ground station.

 TXD and RXD Protocols between GPS module and Arduino Nano.

54
Figure 4.12 shows the schematic diagram of the GPS tracking system whilst Figure 4.13

shows pictorial diagram of the GPS tracking system wired onboard the quadcopter.

Figure 4.12 Schematic diagram of the GPS tracking system

Figure 4.13 Pictorial diagram of the GPS tracking system wired onboard the quadcopter

55
GROUND STATION

ARDUINO UNO Connections:

 3.3V<< Vcc (NRF)

 GND << GND (NRF)

 D8 << CSN (NRF)

 D7 << CE (NRF)

 D11 << MOSI (NRF)

 D12 <<MISO (NRF)

 D13 << SCK (NRF)

Figure 4.14 Pictorial diagram of the GPS Ground Station

GPS APPLICATION

The GPS application is an intergral part of the project. It is an application that will show

important parameters about our quadcopter. The GPS application indicates the following

parameters, longitude, latitude, altitude, HDOP, VDOP, status and more. These parameters

show the location of our quadcopter and the status of the quadcopter and the GPS application

itself. The pictures below indicates the User Interface of the GPS application. Figure 4.15

56
shows images of the GPS application interface indicating our location. Figure 4.16 shows an

image of the GPS System.

Figure 4.15 Images of the GPS application interface indicating our location.

57
Figure 4.16 An image of the GPS System

4.4OTHER IMAGES FROM PROJRCT WORK.

Figure 4.17 shows an image of sensor orientation test.


Figure 4.18 shows am image of circuit test.
Figure 4.19 shows an image of components assembling and setup.
Figure 4.20 shows images of calibration.
Figure 4.21 shows an image of developed quadcopter.
Figure 4.22 shows images of quadcopter troubleshooting.
Figure 4.23 shows images of flight tests.

58
Figure 4.17 An image of sensor orientation test.

Figure 4.18 An image of circuit test.

59
Figure 4.19 An image of components assembling and setup.

Figure 4.20 Images of calibration.

60
Figure 4.21 Images of developed quadcopter

Figure 4.22 Images of quadcopter troubleshooting.

61
Figure 4.23 Images of flight tests.

62
CHAPTER FIVE

CONCLUSION

This project represents a successful endeavor in achieving the aims set forth at

its inception. Our primary objectives were to improve upon the flight control

system of the unmanned quadcopter and implement a reliable GPS tracking

system. Through dedicated efforts, continuous improvement, and rigorous

testing, we have accomplished both goals with resounding success. The

quadcopter now exhibits stable flight, overcoming previous challenges, and the

integrated GPS tracking system provides real-time location monitoring during its

operations.

63
REFERENCES
Amar, P.F. (2016) "Building A Hands Free Quadcopter," Project Report, Degree On

Engineering Of Audiovisual Systems, Department Of Information And Communication

Technologies, Polytechnic School U.P.F.

Camacho, E., Robaina,M., Tasca, A., Cuberos, P., Tansel, I. & Tosunoglu, S. (2015)

"Collision Avoidance Protocol For Package Delivering Quadcopter," Proc. of Florida

Conference on Recent Advances in Robotics.

Emmanuel, A.A., Pranavan, M., Vickram, V. & Girirajkumar, S.M. (2017) "Fertilizer

Spraying Quadcopter using Arduino U.N.O.," International Journal of Science Technology &

Engineering, Volume 3.

Gaur, V., Mishra, A., Aquil, M., Thapa, H., & Verma, R.K. (2015) "Gesture Controlled

Quadcopter," ESSENCE-International Journal for Environmental Rehabilitation and

Conservation Volume VI: No. 2.

Ghosh, A., Mitra, R., Mohalanobish, S., De, S., Bhattacharjee, S. & Bardhan, S. (2018)

"Wireless Irrigation System", Proc. 2018 IEEE International Conference on Recent Innovation

In Electrical Electronics & Communication Engineering ICRIEECE(Accepted and Presented).

Hanafi, D., Qetkeaw, M., Ghazali, R., Than, M.N.M., Utomo,W.M. & Omar, R. (2013)

"Simple G.U.I. Wireless Controller Of Quadcopter," International Journal of Communications,

Network and System Sciences, Vol.6 No.1(2013), Article ID:27464,

DOI:10.4236/ijcns.2013.61006.

Ipate, G., Voicu, G. & Dinu,I. (2015) "Research On The Use Of Drones In Precision

Agriculture," U.P.B. Sci. Bull., Series D, Vol. 77, Iss. 4, ISSN 1454-2358.

64
Jiinec,T. (2011) "Stabilization and control of unmanned quadcopter," Master's Thesis, Dept. of

Cybernetics, Faculty of Electrical Engineering, Czech Technical University, Prague.

Leong, B.T.M., Low, S.M. & Po-L. Ooi, M. (2012) "Low-Cost Microcontroller-based Hover

Control Design of a Quadcopter," International Symposium on Robotics and Intelligent

Sensors.

Mahen, M.A., Naik, A.S., Chethana, H.D. & Shashank, A.C. (2014) "Design And

Development Of Amphibious Quadcopter," International Journal of Mechanical And

Production Engineering, ISSN: 2320-2092, Volume- 2, Issue- 7.

Mane, S.R., Andhare, P.S. & Gaikwad, S.B. (2017) "Design And Implementation Of

Multitasking Flying Robot," IJATES, Vol. No. 5, Issue No. 4.

Mustaffa, A.H.B.M. (2012) "Stability Control For Quadcopter With An Autonomous Flight

System," BIEEH Report, University Teknikal Melaka (UTeM).

OMEGA Engineering(O.E.). (1996) What Is A PID Temperature Controller? [Online]

Available from: https://www.omega.com/en-us/resources/pid-controllers [Accessed 1st April

2023].

Ononiwu, G., Okoye, A., Onojo, J. & Onuekwusi, N. (2016) "Design And Implementation Of

A Real Time Wireless Quadcopter For Rescue Operations," American Journal of Engineering

Research (AJER), e-ISSN: 2320-0847 p-ISSN : 2320-0936 Volume-5, Issue-9, pp-130-138.

Ortiz-Rivera, E.I., Estela, A., Romero, C. & Valentin, J.A. (2012) "The use of UAVS in

U.S.A.'S security by an engineering education approach," Proc. of IEEE Conference on

Technologies for Homeland Security (H.S.T.).

Patel, P.N., Patel, M.A., Faldu, R.M. & Dave, Y.R. (2013) "Quad Copter For Using

Agricultural Surveillance," Advance in Electronic and Electric Engineering, ISSN 2231-1297,

Volume 3, Number 4 (2013), pp. 427-432.

65
Picas, C.C. (2014) "An Android-Based Arduino-Governed Unmanned Quadcopter Platform,"

Thesis, University of Catalunya, Barcelona.

Qetkeaw, M. & Vechian, A.L. (2012) "Wireless Control Quadcopter With Stereo Camera,"

M.E. Thesis, Faculty of Electrical and Electronics Engineering, University Tun Hussein Onn

Malaysia.

Rengarajan, M. & Anitha, G. (2013) "Algorithm Dvelopment And Testing Of Low-Cost

Waypoint Navigation System," [IRACST – Engineering Science and Technology: An

International Journal (ESTIJ), ISSN: 2250-3498, Vol.3, No.2.

Salaskar, P., Paranjpe, S., Reddy, J. & Shah, A. "QuadcopterObstacle detection & Collision

Avoidance," International Journal of Engineering Trends and Technology (IJETT) – Volume

17 Number 2.

66
APPENDIX A (FLIGHT CONTROLLER CODES)

///////////////////////////////////////////////////////////////////////////////////////
//Safety note
///////////////////////////////////////////////////////////////////////////////////////
//Always remove the propellers and stay away from the motors unless you
//are 100% certain of what you are doing.
///////////////////////////////////////////////////////////////////////////////////////

#include <Wire.h> //Include the Wire.h library so we can communicate with


the gyro.
#include <EEPROM.h> //Include the EEPROM.h library so we can store
information onto the EEPROM

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//PID gain and limit settings
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float pid_p_gain_roll = 1.3; //Gain setting for the roll P-controller
float pid_i_gain_roll = 0.04; //Gain setting for the roll I-controller
float pid_d_gain_roll = 18.0; //Gain setting for the roll D-controller
int pid_max_roll = 400; //Maximum output of the PID-controller (+/-)

float pid_p_gain_pitch = pid_p_gain_roll; //Gain setting for the pitch P-controller.


float pid_i_gain_pitch = pid_i_gain_roll; //Gain setting for the pitch I-controller.
float pid_d_gain_pitch = pid_d_gain_roll; //Gain setting for the pitch D-controller.
int pid_max_pitch = pid_max_roll; //Maximum output of the PID-controller (+/-)

float pid_p_gain_yaw = 4.0; //Gain setting for the pitch P-controller. //4.0
float pid_i_gain_yaw = 0.02; //Gain setting for the pitch I-controller. //0.02
float pid_d_gain_yaw = 0.0; //Gain setting for the pitch D-controller.
int pid_max_yaw = 400; //Maximum output of the PID-controller (+/-)

boolean auto_level = false; //Auto level on (true) or off (false)

float maxInput=10;
float minInput=-10;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Declaring global variables
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
byte last_channel_1, last_channel_2, last_channel_3, last_channel_4;
byte eeprom_data[36];
byte highByte, lowByte;
volatile int receiver_input_channel_1, receiver_input_channel_2, receiver_input_channel_3,
receiver_input_channel_4;

67
int counter_channel_1, counter_channel_2, counter_channel_3, counter_channel_4,
loop_counter;
int esc_1, esc_2, esc_3, esc_4;
int throttle, battery_voltage;
int cal_int, start, gyro_address;
int receiver_input[5];
int temperature;
int acc_axis[4], gyro_axis[4];
float roll_level_adjust, pitch_level_adjust;

long acc_x, acc_y, acc_z, acc_total_vector;


unsigned long timer_channel_1, timer_channel_2, timer_channel_3, timer_channel_4,
esc_timer, esc_loop_timer;
unsigned long timer_1, timer_2, timer_3, timer_4, current_time;
unsigned long loop_timer;
double gyro_pitch, gyro_roll, gyro_yaw;
double gyro_axis_cal[4];
float pid_error_temp;
float pid_i_mem_roll, pid_roll_setpoint, gyro_roll_input, pid_output_roll,
pid_last_roll_d_error;
float pid_i_mem_pitch, pid_pitch_setpoint, gyro_pitch_input, pid_output_pitch,
pid_last_pitch_d_error;
float pid_i_mem_yaw, pid_yaw_setpoint, gyro_yaw_input, pid_output_yaw,
pid_last_yaw_d_error;
float angle_roll_acc, angle_pitch_acc, angle_pitch, angle_roll;
boolean gyro_angles_set;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Setup routine
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup(){
Serial.begin(57600);
//Copy the EEPROM data for fast access data.
for(start = 0; start <= 35; start++)eeprom_data[start] = EEPROM.read(start);
start = 0; //Set start back to zero.
gyro_address = eeprom_data[32]; //Store the gyro address in the
variable.

Wire.begin(); //Start the I2C as master.

TWBR = 12; //Set the I2C clock speed to 400kHz.

//Arduino (Atmega) pins default to inputs, so they don't need to be explicitly declared as
inputs.
DDRD |= B11110000; //Configure digital poort 4, 5, 6 and
7 as output.
DDRB |= B00110000; //Configure digital poort 12 and 13
as output.

68
//Use the led on the Arduino for startup indication.
digitalWrite(12,HIGH); //Turn on the warning led.

//Check the EEPROM signature to make sure that the setup program is executed.
while(eeprom_data[33] != 'J' || eeprom_data[34] != 'M' || eeprom_data[35] != 'B')delay(10);

//The flight controller needs the MPU-6050 with gyro and accelerometer
//If setup is completed without MPU-6050 stop the flight controller program
if(eeprom_data[31] == 2 || eeprom_data[31] == 3)delay(10);

set_gyro_registers(); //Set the specific gyro registers.

for (cal_int = 0; cal_int < 1250 ; cal_int ++){ //Wait 5 seconds before
continuing.
PORTD |= B11110000; //Set digital poort 4, 5, 6 and 7
high.
delayMicroseconds(1000); //Wait 1000us.
PORTD &= B00001111; //Set digital poort 4, 5, 6 and 7
low.
delayMicroseconds(3000); //Wait 3000us.
}

//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 % 15 == 0)digitalWrite(12, !digitalRead(12)); //Change the led status to
indicate calibration.
gyro_signalen(); //Read the gyro output.
gyro_axis_cal[1] += gyro_axis[1]; //Ad roll value to gyro_roll_cal.
gyro_axis_cal[2] += gyro_axis[2]; //Ad pitch value to
gyro_pitch_cal.
gyro_axis_cal[3] += gyro_axis[3]; //Ad yaw value to gyro_yaw_cal.
//We don't want the esc's to be beeping annoyingly. So let's give them a 1000us puls while
calibrating the gyro.
PORTD |= B11110000; //Set digital poort 4, 5, 6 and 7
high.
delayMicroseconds(1000); //Wait 1000us.
PORTD &= B00001111; //Set digital poort 4, 5, 6 and 7
low.
delay(3); //Wait 3 milliseconds before the next loop.
}
//Now that we have 2000 measures, we need to divide by 2000 to get the average gyro offset.
gyro_axis_cal[1] /= 2000; //Divide the roll total by 2000.
gyro_axis_cal[2] /= 2000; //Divide the pitch total by 2000.
gyro_axis_cal[3] /= 2000; //Divide the yaw total by 2000.

PCICR |= (1 << PCIE0); //Set PCIE0 to enable PCMSK0


scan.

69
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.
PCMSK0 |= (1 << PCINT3); //Set PCINT3 (digital input 11)to
trigger an interrupt on state change.

//Wait until the receiver is active and the throtle is set to the lower position.
while(receiver_input_channel_3 < 990 || receiver_input_channel_3 > 1020 ||
receiver_input_channel_4 < 1400){
receiver_input_channel_3 = convert_receiver_channel(3); //Convert the actual
receiver signals for throttle to the standard 1000 - 2000us
receiver_input_channel_4 = convert_receiver_channel(4); //Convert the actual
receiver signals for yaw to the standard 1000 - 2000us
start ++; //While waiting increment start whith every
loop.
//We don't want the esc's to be beeping annoyingly. So let's give them a 1000us puls while
waiting for the receiver inputs.
PORTD |= B11110000; //Set digital poort 4, 5, 6 and 7
high.
delayMicroseconds(1000); //Wait 1000us.
PORTD &= B00001111; //Set digital poort 4, 5, 6 and 7
low.
delay(3); //Wait 3 milliseconds before the next loop.
if(start == 125){ //Every 125 loops (500ms).
digitalWrite(12, !digitalRead(12)); //Change the led status.
start = 0; //Start again at 0.
}
}
start = 0; //Set start back to 0.

//Load the battery voltage to the battery_voltage variable.


//65 is the voltage compensation for the diode.
//12.6V equals ~5V @ Analog 0.
//12.6V equals 1023 analogRead(0).
//1260 / 1023 = 1.2317.
//The variable battery_voltage holds 1050 if the battery voltage is 10.5V.
battery_voltage = (analogRead(0) + 65) * 1.2317;

loop_timer = micros(); //Set the timer for the next loop.

//When everything is done, turn off the led.


digitalWrite(12,LOW); //Turn off the warning led.
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Main program loop
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

70
void loop(){

//65.5 = 1 deg/sec (check the datasheet of the MPU-6050 for more information).
gyro_roll_input = (gyro_roll_input * 0.7) + ((gyro_roll / 65.5) * 0.3); //Gyro pid input is
deg/sec.
gyro_pitch_input = (gyro_pitch_input * 0.7) + ((gyro_pitch / 65.5) * 0.3);//Gyro pid input is
deg/sec.
gyro_yaw_input = (gyro_yaw_input * 0.7) + ((gyro_yaw / 65.5) * 0.3); //Gyro pid input is
deg/sec.

////////////////////////////////////////////////////////////////////////////////////////////////////
//This is the added IMU code from the videos:
//https://youtu.be/4BoIE8YQwM8
//https://youtu.be/j-kE0AMEWy4
////////////////////////////////////////////////////////////////////////////////////////////////////

//Gyro angle calculations


//0.0000611 = 1 / (250Hz / 65.5)
angle_pitch += gyro_pitch * 0.0000611; //Calculate the traveled pitch
angle and add this to the angle_pitch variable.
angle_roll += gyro_roll * 0.0000611; //Calculate the traveled roll
angle and add this to the angle_roll variable.

//0.000001066 = 0.0000611 * (3.142(PI) / 180degr) The Arduino sin function is in radians


angle_pitch -= angle_roll * sin(gyro_yaw * 0.000001066); //If the IMU has yawed
transfer the roll angle to the pitch angel.
angle_roll += angle_pitch * sin(gyro_yaw * 0.000001066); //If the IMU has
yawed transfer the pitch angle to the roll angel.

//Accelerometer angle calculations


acc_total_vector = sqrt((acc_x*acc_x)+(acc_y*acc_y)+(acc_z*acc_z)); //Calculate the
total accelerometer vector.

if(abs(acc_y) < acc_total_vector){ //Prevent the asin function to


produce a NaN
angle_pitch_acc = asin((float)acc_y/acc_total_vector)* 57.296; //Calculate the pitch
angle.
}
if(abs(acc_x) < acc_total_vector){ //Prevent the asin function to
produce a NaN
angle_roll_acc = asin((float)acc_x/acc_total_vector)* -57.296; //Calculate the roll
angle.
}

//Place the MPU-6050 spirit level and note the values in the following two lines for
calibration.
angle_pitch_acc -= 0.0; //Accelerometer calibration value for
pitch.

71
angle_roll_acc -= 0.0; //Accelerometer calibration value for
roll.

angle_pitch = angle_pitch * 0.9996 + angle_pitch_acc * 0.0004; //Correct the drift of


the gyro pitch angle with the accelerometer pitch angle.
angle_roll = angle_roll * 0.9996 + angle_roll_acc * 0.0004; //Correct the drift of the
gyro roll angle with the accelerometer roll angle.

pitch_level_adjust = angle_pitch * 15; //Calculate the pitch angle


correction
roll_level_adjust = angle_roll * 15; //Calculate the roll angle
correction

if(!auto_level){ //If the quadcopter is not in auto-level


mode
pitch_level_adjust = 0; //Set the pitch angle correction to zero.
roll_level_adjust = 0; //Set the roll angle correcion to zero.
}

//For starting the motors: throttle low and yaw left (step 1).
if(receiver_input_channel_3 < 1050 && receiver_input_channel_4 < 1050)start = 1;
//When yaw stick is back in the center position start the motors (step 2).
if(start == 1 && receiver_input_channel_3 < 1050 && receiver_input_channel_4 > 1450){
start = 2;

angle_pitch = angle_pitch_acc; //Set the gyro pitch angle equal to


the accelerometer pitch angle when the quadcopter is started.
angle_roll = angle_roll_acc; //Set the gyro roll angle equal to the
accelerometer roll angle when the quadcopter is started.
gyro_angles_set = true; //Set the IMU started flag.

//Reset the PID controllers for a bumpless start.


pid_i_mem_roll = 0;
pid_last_roll_d_error = 0;
pid_i_mem_pitch = 0;
pid_last_pitch_d_error = 0;
pid_i_mem_yaw = 0;
pid_last_yaw_d_error = 0;
}
//Stopping the motors: throttle low and yaw right.
if(start == 2 && receiver_input_channel_3 < 1050 && receiver_input_channel_4 >
1950)start = 0;

//The PID set point in degrees per second is determined by the roll receiver input.
//In the case of deviding by 3 the max roll rate is aprox 164 degrees per second ( (500-8)/3 =
164d/s ).
pid_roll_setpoint = 0;
//We need a little dead band of 16us for better results.

72
if(receiver_input_channel_1 > 1508)pid_roll_setpoint = receiver_input_channel_1 - 1508;
else if(receiver_input_channel_1 < 1492)pid_roll_setpoint = receiver_input_channel_1 -
1492;

pid_roll_setpoint -= roll_level_adjust; //Subtract the angle correction


from the standardized receiver roll input value.
pid_roll_setpoint /= 3.0;
Serial.print("Roll ");
Serial.print(pid_roll_setpoint);//Divide the setpoint for the PID roll controller by 3 to get
angles in degrees.
pid_roll_setpoint=rangeControl(pid_roll_setpoint);

//The PID set point in degrees per second is determined by the pitch receiver input.
//In the case of deviding by 3 the max pitch rate is aprox 164 degrees per second ( (500-8)/3
= 164d/s ).
pid_pitch_setpoint = 0;
//We need a little dead band of 16us for better results.
if(receiver_input_channel_2 > 1508)pid_pitch_setpoint = receiver_input_channel_2 - 1508;
else if(receiver_input_channel_2 < 1492)pid_pitch_setpoint = receiver_input_channel_2 -
1492;

pid_pitch_setpoint -= pitch_level_adjust; //Subtract the angle correction


from the standardized receiver pitch input value.
pid_pitch_setpoint /= 3.0;
Serial.print("Pitch ");
Serial.print(pid_pitch_setpoint);//Divide the setpoint for the PID pitch controller by 3 to get
angles in degrees.
pid_pitch_setpoint=rangeControl(pid_pitch_setpoint);
Serial.print("Pitch ");
Serial.println(pid_pitch_setpoint);

//The PID set point in degrees per second is determined by the yaw receiver input.
//In the case of deviding by 3 the max yaw rate is aprox 164 degrees per second ( (500-8)/3 =
164d/s ).
pid_yaw_setpoint = 0;
//We need a little dead band of 16us for better results.
if(receiver_input_channel_3 > 1050){ //Do not yaw when turning off the motors.
if(receiver_input_channel_4 > 1508)pid_yaw_setpoint = (receiver_input_channel_4 -
1508)/3.0;
else if(receiver_input_channel_4 < 1492)pid_yaw_setpoint = (receiver_input_channel_4 -
1492)/3.0;

calculate_pid(); //PID inputs are known. So we can


calculate the pid output.

//The battery voltage is needed for compensation.


//A complementary filter is used to reduce noise.

73
//0.09853 = 0.08 * 1.2317.
battery_voltage = battery_voltage * 0.92 + (analogRead(0) + 65) * 0.09853;

//Turn on the led if battery voltage is to low.


if(battery_voltage < 1000 && battery_voltage > 600)digitalWrite(12, HIGH);

throttle = receiver_input_channel_3; //We need the throttle signal as a


base signal.

if (start == 2){ //The motors are started.


if (throttle > 1800) throttle = 1800; //We need some room to keep full
control at full throttle.
esc_1 = throttle - pid_output_pitch + pid_output_roll - pid_output_yaw; //Calculate the
pulse for esc 1 (front-right - CCW)
esc_2 = throttle + pid_output_pitch + pid_output_roll + pid_output_yaw; //Calculate the
pulse for esc 2 (rear-right - CW)
esc_3 = throttle + pid_output_pitch - pid_output_roll - pid_output_yaw; //Calculate the
pulse for esc 3 (rear-left - CCW)
esc_4 = throttle - pid_output_pitch - pid_output_roll + pid_output_yaw; //Calculate the
pulse for esc 4 (front-left - CW)

if (battery_voltage < 1240 && battery_voltage > 800){ //Is the battery
connected?
esc_1 += esc_1 * ((1240 - battery_voltage)/(float)3500); //Compensate the esc-1
pulse for voltage drop.
esc_2 += esc_2 * ((1240 - battery_voltage)/(float)3500); //Compensate the esc-2
pulse for voltage drop.
esc_3 += esc_3 * ((1240 - battery_voltage)/(float)3500); //Compensate the esc-3
pulse for voltage drop.
esc_4 += esc_4 * ((1240 - battery_voltage)/(float)3500); //Compensate the esc-4
pulse for voltage drop.
}

if (esc_1 < 1100) esc_1 = 1000; //Keep the motors running.


if (esc_2 < 1100) esc_2 = 1000; //Keep the motors running.
if (esc_3 < 1100) esc_3 = 1000; //Keep the motors running.
if (esc_4 < 1100) esc_4 = 1000; //Keep the motors running.

if(esc_1 > 2000)esc_1 = 2000; //Limit the esc-1 pulse to 2000us.


if(esc_2 > 2000)esc_2 = 2000; //Limit the esc-2 pulse to 2000us.
if(esc_3 > 2000)esc_3 = 2000; //Limit the esc-3 pulse to 2000us.
if(esc_4 > 2000)esc_4 = 2000; //Limit the esc-4 pulse to 2000us.
}

else{
esc_1 = 1000; //If start is not 2 keep a 1000us pulse for
ess-1.

74
esc_2 = 1000; //If start is not 2 keep a 1000us pulse for
ess-2.
esc_3 = 1000; //If start is not 2 keep a 1000us pulse for
ess-3.
esc_4 = 1000; //If start is not 2 keep a 1000us pulse for
ess-4.
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//Creating the pulses for the ESC's is explained in this video:
//https://youtu.be/fqEkVcqxtU8
////////////////////////////////////////////////////////////////////////////////////////////////////

//! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
//Because of the angle calculation the loop time is getting very important. If the loop time is
//longer or shorter than 4000us the angle calculation is off. If you modify the code make sure
//that the loop time is still 4000us and no longer! More information can be found on
//the Q&A page:
//! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !

if(micros() - loop_timer > 4050)digitalWrite(12, HIGH); //Turn on the LED if the


loop time exceeds 4050us.

//All the information for controlling the motor's is available.


//The refresh rate is 250Hz. That means the esc's need there pulse every 4ms.
while(micros() - loop_timer < 4000); //We wait until 4000us are
passed.
loop_timer = micros(); //Set the timer for the next loop.

PORTD |= B11110000; //Set digital outputs 4,5,6 and 7


high.
timer_channel_1 = esc_1 + loop_timer; //Calculate the time of the
faling edge of the esc-1 pulse.
timer_channel_2 = esc_2 + loop_timer; //Calculate the time of the
faling edge of the esc-2 pulse.
timer_channel_3 = esc_3 + loop_timer; //Calculate the time of the
faling edge of the esc-3 pulse.
timer_channel_4 = esc_4 + loop_timer; //Calculate the time of the
faling edge of the esc-4 pulse.

//There is always 1000us of spare time. So let's do something usefull that is very time
consuming.
//Get the current gyro and receiver data and scale it to degrees per second for the pid
calculations.
gyro_signalen();

while(PORTD >= 16){ //Stay in this loop until output 4,5,6


and 7 are low.
esc_loop_timer = micros(); //Read the current time.

75
if(timer_channel_1 <= esc_loop_timer)PORTD &= B11101111; //Set digital
output 4 to low if the time is expired.
if(timer_channel_2 <= esc_loop_timer)PORTD &= B11011111; //Set digital
output 5 to low if the time is expired.
if(timer_channel_3 <= esc_loop_timer)PORTD &= B10111111; //Set digital
output 6 to low if the time is expired.
if(timer_channel_4 <= esc_loop_timer)PORTD &= B01111111; //Set digital
output 7 to low if the time is expired.
}
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//This routine is called every time input 8, 9, 10 or 11 changed state. This is used to read the
receiver signals.
//More information about this subroutine can be found in this video:
//https://youtu.be/bENjl1KQbvo
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ISR(PCINT0_vect){
current_time = micros();
//Channel 1=========================================
if(PINB & B00000001){ //Is input 8 high?
if(last_channel_1 == 0){ //Input 8 changed from 0 to 1.
last_channel_1 = 1; //Remember current input state.
timer_1 = current_time; //Set timer_1 to current_time.
}
}
else if(last_channel_1 == 1){ //Input 8 is not high and changed
from 1 to 0.
last_channel_1 = 0; //Remember current input state.
receiver_input[1] = current_time - timer_1; //Channel 1 is current_time -
timer_1.
}
//Channel 2=========================================
if(PINB & B00000010 ){ //Is input 9 high?
if(last_channel_2 == 0){ //Input 9 changed from 0 to 1.
last_channel_2 = 1; //Remember current input state.
timer_2 = current_time; //Set timer_2 to current_time.
}
}
else if(last_channel_2 == 1){ //Input 9 is not high and changed
from 1 to 0.
last_channel_2 = 0; //Remember current input state.
receiver_input[2] = current_time - timer_2; //Channel 2 is current_time -
timer_2.
}
//Channel 3=========================================
if(PINB & B00000100 ){ //Is input 10 high?
if(last_channel_3 == 0){ //Input 10 changed from 0 to 1.
last_channel_3 = 1; //Remember current input state.

76
timer_3 = current_time; //Set timer_3 to current_time.
}
}
else if(last_channel_3 == 1){ //Input 10 is not high and changed
from 1 to 0.
last_channel_3 = 0; //Remember current input state.
receiver_input[3] = current_time - timer_3; //Channel 3 is current_time -
timer_3.

}
//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[4] = current_time - timer_4; //Channel 4 is current_time -
timer_4.
}
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Subroutine for reading the gyro
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void gyro_signalen(){
//Read the MPU-6050
if(eeprom_data[31] == 1){
Wire.beginTransmission(gyro_address); //Start communication with
the gyro.
Wire.write(0x3B); //Start reading @ register 43h and auto
increment with every read.
Wire.endTransmission(); //End the transmission.
Wire.requestFrom(gyro_address,14); //Request 14 bytes from the
gyro.

receiver_input_channel_1 = convert_receiver_channel(1); //Convert the actual receiver


signals for pitch to the standard 1000 - 2000us.
receiver_input_channel_2 = convert_receiver_channel(2); //Convert the actual receiver
signals for roll to the standard 1000 - 2000us.
receiver_input_channel_3 = convert_receiver_channel(3); //Convert the actual receiver
signals for throttle to the standard 1000 - 2000us.
receiver_input_channel_4 = convert_receiver_channel(4); //Convert the actual receiver
signals for yaw to the standard 1000 - 2000us.

77
while(Wire.available() < 14); //Wait until the 14 bytes are
received.
acc_axis[1] = Wire.read()<<8|Wire.read(); //Add the low and high byte
to the acc_x variable.
acc_axis[2] = Wire.read()<<8|Wire.read(); //Add the low and high byte
to the acc_y variable.
acc_axis[3] = Wire.read()<<8|Wire.read(); //Add the low and high byte
to the acc_z variable.
temperature = Wire.read()<<8|Wire.read(); //Add the low and high byte
to the temperature variable.
gyro_axis[1] = Wire.read()<<8|Wire.read(); //Read high and low part of
the angular data.
gyro_axis[2] = Wire.read()<<8|Wire.read(); //Read high and low part of
the angular data.
gyro_axis[3] = Wire.read()<<8|Wire.read(); //Read high and low part of
the angular data.
}

if(cal_int == 2000){
gyro_axis[1] -= gyro_axis_cal[1]; //Only compensate after the
calibration.
gyro_axis[2] -= gyro_axis_cal[2]; //Only compensate after the
calibration.
gyro_axis[3] -= gyro_axis_cal[3]; //Only compensate after the
calibration.
}
gyro_roll = gyro_axis[eeprom_data[28] & 0b00000011]; //Set gyro_roll to the
correct axis that was stored in the EEPROM.
if(eeprom_data[28] & 0b10000000)gyro_roll *= -1; //Invert gyro_roll if the
MSB of EEPROM bit 28 is set.
gyro_pitch = gyro_axis[eeprom_data[29] & 0b00000011]; //Set gyro_pitch to
the correct axis that was stored in the EEPROM.
if(eeprom_data[29] & 0b10000000)gyro_pitch *= -1; //Invert gyro_pitch if the
MSB of EEPROM bit 29 is set.
gyro_yaw = gyro_axis[eeprom_data[30] & 0b00000011]; //Set gyro_yaw to the
correct axis that was stored in the EEPROM.
if(eeprom_data[30] & 0b10000000)gyro_yaw *= -1; //Invert gyro_yaw if the
MSB of EEPROM bit 30 is set.

acc_x = acc_axis[eeprom_data[29] & 0b00000011]; //Set acc_x to the


correct axis that was stored in the EEPROM.
if(eeprom_data[29] & 0b10000000)acc_x *= -1; //Invert acc_x if the MSB
of EEPROM bit 29 is set.
acc_y = acc_axis[eeprom_data[28] & 0b00000011]; //Set acc_y to the
correct axis that was stored in the EEPROM.
if(eeprom_data[28] & 0b10000000)acc_y *= -1; //Invert acc_y if the MSB
of EEPROM bit 28 is set.
acc_z = acc_axis[eeprom_data[30] & 0b00000011]; //Set acc_z to the correct
axis that was stored in the EEPROM.

78
if(eeprom_data[30] & 0b10000000)acc_z *= -1; //Invert acc_z if the MSB
of EEPROM bit 30 is set.
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Subroutine for calculating pid outputs
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//The PID controllers are explained in part 5 of the YMFC-3D video session:
//https://youtu.be/JBvnB0279-Q
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void calculate_pid(){
//Roll calculations
pid_error_temp = gyro_roll_input - pid_roll_setpoint;
pid_i_mem_roll += pid_i_gain_roll * pid_error_temp;
if(pid_i_mem_roll > pid_max_roll)pid_i_mem_roll = pid_max_roll;
else if(pid_i_mem_roll < pid_max_roll * -1)pid_i_mem_roll = pid_max_roll * -1;

pid_output_roll = pid_p_gain_roll * pid_error_temp + pid_i_mem_roll + pid_d_gain_roll *


(pid_error_temp - pid_last_roll_d_error);
if(pid_output_roll > pid_max_roll)pid_output_roll = pid_max_roll;
else if(pid_output_roll < pid_max_roll * -1)pid_output_roll = pid_max_roll * -1;

pid_last_roll_d_error = pid_error_temp;

//Pitch calculations
pid_error_temp = gyro_pitch_input - pid_pitch_setpoint;
pid_i_mem_pitch += pid_i_gain_pitch * pid_error_temp;
if(pid_i_mem_pitch > pid_max_pitch)pid_i_mem_pitch = pid_max_pitch;
else if(pid_i_mem_pitch < pid_max_pitch * -1)pid_i_mem_pitch = pid_max_pitch * -1;

pid_output_pitch = pid_p_gain_pitch * pid_error_temp + pid_i_mem_pitch +


pid_d_gain_pitch * (pid_error_temp - pid_last_pitch_d_error);
if(pid_output_pitch > pid_max_pitch)pid_output_pitch = pid_max_pitch;
else if(pid_output_pitch < pid_max_pitch * -1)pid_output_pitch = pid_max_pitch * -1;

pid_last_pitch_d_error = pid_error_temp;

//Yaw calculations
pid_error_temp = gyro_yaw_input - pid_yaw_setpoint;
pid_i_mem_yaw += pid_i_gain_yaw * pid_error_temp;
if(pid_i_mem_yaw > pid_max_yaw)pid_i_mem_yaw = pid_max_yaw;
else if(pid_i_mem_yaw < pid_max_yaw * -1)pid_i_mem_yaw = pid_max_yaw * -1;

pid_output_yaw = pid_p_gain_yaw * pid_error_temp + pid_i_mem_yaw + pid_d_gain_yaw


* (pid_error_temp - pid_last_yaw_d_error);
if(pid_output_yaw > pid_max_yaw)pid_output_yaw = pid_max_yaw;
else if(pid_output_yaw < pid_max_yaw * -1)pid_output_yaw = pid_max_yaw * -1;

pid_last_yaw_d_error = pid_error_temp;

79
}

//This part converts the actual receiver signals to a standardized 1000 – 1500 – 2000
microsecond value.
//The stored data in the EEPROM is used.
int convert_receiver_channel(byte function){
byte channel, reverse; //First we declare some local
variables
int low, center, high, actual;
int difference;

channel = eeprom_data[function + 23] & 0b00000111; //What channel


corresponds with the specific function
if(eeprom_data[function + 23] & 0b10000000)reverse = 1; //Reverse channel
when most significant bit is set
else reverse = 0; //If the most significant is not set there
is no reverse

actual = receiver_input[channel]; //Read the actual receiver value


for the corresponding function
low = (eeprom_data[channel * 2 + 15] << 8) | eeprom_data[channel * 2 + 14]; //Store the
low value for the specific receiver input channel
center = (eeprom_data[channel * 2 - 1] << 8) | eeprom_data[channel * 2 - 2]; //Store the
center value for the specific receiver input channel
high = (eeprom_data[channel * 2 + 7] << 8) | eeprom_data[channel * 2 + 6]; //Store the
high value for the specific receiver input channel

if(actual < center){ //The actual receiver value is lower


than the center value
if(actual < low)actual = low; //Limit the lowest value to the
value that was detected during setup
difference = ((long)(center - actual) * (long)500) / (center - low); //Calculate and scale
the actual value to a 1000 - 2000us value
if(reverse == 1)return 1500 + difference; //If the channel is reversed
else return 1500 - difference; //If the channel is not reversed
}
else if(actual > center){ //The actual receiver
value is higher than the center value
if(actual > high)actual = high; //Limit the lowest value to the
value that was detected during setup
difference = ((long)(actual - center) * (long)500) / (high - center); //Calculate and scale
the actual value to a 1000 - 2000us value
if(reverse == 1)return 1500 - difference; //If the channel is reversed
else return 1500 + difference; //If the channel is not reversed
}
else return 1500;
}

void set_gyro_registers(){

80
//Setup the MPU-6050
if(eeprom_data[31] == 1){
Wire.beginTransmission(gyro_address); //Start communication with
the address found during search.
Wire.write(0x6B); //We want to write to the
PWR_MGMT_1 register (6B hex)
Wire.write(0x00); //Set the register bits as 00000000 to
activate the gyro
Wire.endTransmission(); //End the transmission with the
gyro.

Wire.beginTransmission(gyro_address); //Start communication with


the address found during search.
Wire.write(0x1B); //We want to write to the
GYRO_CONFIG register (1B hex)
Wire.write(0x08); //Set the register bits as 00001000
(500dps full scale)
Wire.endTransmission(); //End the transmission with the
gyro

Wire.beginTransmission(gyro_address); //Start communication with


the address found during search.
Wire.write(0x1C); //We want to write to the
ACCEL_CONFIG register (1A hex)
Wire.write(0x10); //Set the register bits as 00010000
(+/- 8g full scale range)
Wire.endTransmission(); //End the transmission with the
gyro

//Let's perform a random register check to see if the values are written correct
Wire.beginTransmission(gyro_address); //Start communication with
the address found during search
Wire.write(0x1B); //Start reading @ register 0x1B
Wire.endTransmission(); //End the transmission
Wire.requestFrom(gyro_address, 1); //Request 1 bytes from the
gyro
while(Wire.available() < 1); //Wait until the 6 bytes are
received
if(Wire.read() != 0x08){ //Check if the value is 0x08
digitalWrite(12,HIGH); //Turn on the warning led
while(1)delay(10); //Stay in this loop for ever
}

Wire.beginTransmission(gyro_address); //Start communication with the address


found during search
Wire.write(0x1A); //We want to write to the CONFIG
register (1A hex)
Wire.write(0x03); //Set the register bits as 00000011
(Set Digital Low Pass Filter to ~43Hz)

81
Wire.endTransmission(); //End the transmission with the
gyro

}
}
float rangeControl(float input){
float output=map(input,-164,164,-30,30);

if(input>(float)maxInput){
output=(float)maxInput;
}else if (output<(float)minInput){
output=(float)minInput;
}
return output;
}

82
APPENDIX B (GPS CODES)

TRANSMITTER

/*

* Rui Santos

* Complete Project Details https://randomnerdtutorials.com

*/

#include <SPI.h>

#include <nRF24L01.h>

#include <RF24.h>

#include <SoftwareSerial.h>

// The serial connection to the GPS module

SoftwareSerial ss(6, 5);//TX,RX

RF24 radio(7, 8); // CE, CSN

const byte address[6] = "00001";

int i = 0;

void splitmsg(const char *msg, const int arraySize, const int len){

// byte numpackets = (int)(arraySize/len)

Serial.print("Array size: ");

Serial.println(arraySize);

byte numPackets = (int)(arraySize / len);

byte P_iterator = 0;

83
if (arraySize % len > 0)

numPackets++;

Serial.print("num_Packets: ");

Serial.println(numPackets);

while (P_iterator < numPackets)

char t[len+1];

char *ptr1 = msg + P_iterator * (len);

strncpy(t, ptr1, len);

t[len] = '\0';

Serial.println(t);

radio.write(&t, sizeof(t));

P_iterator++;

void setup(){

pinMode(10, OUTPUT);

Serial.begin(115200);

ss.begin(9600);

Serial.flush();

Serial.print("Starting up\n");

radio.begin();

84
radio.openWritingPipe(address);

// radio.setChannel(0x76);

radio.setPALevel(RF24_PA_MIN);

radio.setDataRate(RF24_250KBPS);

radio.stopListening();

// radio.enableDynamicPayloads();

// radio.powerUp();

Serial.println("Starting to send");

void loop(){

// Serial.println(ss.available());

// const char text[32] = "Hello world";

// radio.write(&text, sizeof(text)) ;

// Serial.println("Sending");

const int sizebuf = 32;

byte gpsd[sizebuf];

bool in_loop = false;

while (i < sizebuf){

// // get the byte data from the GPS

// // char gpsData;

while (ss.available() > 0 && i < sizebuf){

in_loop = true;

byte gpsData = ss.read();

gpsd[i] = gpsData;

85
i += 1;

// if (i < (sizebuf)){

// i += 1;

// }else{

// for (int j = 0; j < i; j++){

// // Serial.print();

// Serial.print(gpsd[j]);

// }

// Serial.print(" Size: ");

// Serial.println(i);

// i = 0;

if (i != 0){

for (int j = 0; j < i; j++){

// Serial.print();

Serial.print((char)gpsd[j]);

Serial.print(" Size: ");

86
Serial.println(i);

radio.write(&gpsd, i);

// delay(100);

i = 0;

//

// Serial.println(" here");

// // String info = Serial.readString();

// Serial.println();

// if (sizeof(gpsd) > 1){

// splitmsg(gpsd, sizeof(gpsd), 7);

// radio.write((String)gpsd, sizeof(gpsd));

// }

RECEIVER

87
#include <SPI.h>

#include <nRF24L01.h>

#include <RF24.h>

RF24 radio(7, 8); // CE, CSN

const byte address[6] = "00001";

//struct dataStruct{

// double latitude;

// double longitude;

// unsigned long date;

// unsigned long time;

//}gpsData;

void setup() {

pinMode(10, OUTPUT);

Serial.begin(115200);

// Setup receiver radio

radio.begin();

radio.openReadingPipe(1, address);

// radio.setChannel(0x76);

radio.setPALevel(RF24_PA_MIN);

radio.setDataRate(RF24_250KBPS);

radio.startListening();

// radio.enableDynamicPayloads();

88
// radio.powerUp();

Serial.println("Starting..");

Serial.println("Starting..dc");

void loop() {

// Serial.println(radio.available());

if (radio.available())

byte buf[32];

radio.read(&buf, sizeof(buf));

Serial.write(buf, 32);

// delay(100);

// el{

// Serial.println("No radio") ;

// }

89
APPENDIX C (LIST OF ITEMS ORDERED)

Component Quantity Total


Unit
Cost(₵)
Price(₵)

V5.0 Sensor Shield for Arduino 1 35 35.0

NEO-6M v2 GPS module with EEPROM 2 65 130.0

Arduino Uno with USB cable 1 149 149.0

Arduino-Nano with USB cable 1 75 75.0

MPU-6050 3 Axis Acceleration + Gyro 2 38 76.0


Breakout
Male to Male jumper wires 40pcs-20cm 2 17 34.0

NRF24L01+ Wireless Module 2.4Ghz 2 45 90.0

Female to Female jumper wires 40pcs-20cm 2 17 34.0

Female to Male jumper wires 40pcs-20cm 2 17 34.0

Right Angle Pin Header 2.54mm 1 1.50 1.50

90

You might also like