8 min read

In this tutorial, we will learn how to train the drone to do something or give the drone artificial intelligence by coding from scratch. There are several ways to build Follow Me-type drones. We will learn easy and quick ways in this article. Before going any further, let’s learn the basics of a Follow Me drone.

This is a book excerpt from Building Smart Drones with ESP8266 and Arduino written by Syed Omar Faruk Towaha.
If you are a hardcore programmer and hardware enthusiast, you can build an Arduino drone, and make it a Follow Me drone by enabling a few extra features.

For this section, you will need the following things:

  • Motors
  • ESCs
  • Battery
  • Propellers
  • Radio-controller
  • Arduino Nano
  • HC-05 Bluetooth module
  • GPS
  • MPU6050 or GY-86 gyroscope.
  • Some wires

Connections are simple:

  1. You need to connect the motors to the ESCs, and ESCs to the battery. You can use a four-way connector (power distribution board) for this, like in the following diagram:
  1. Now, connect the radio to the Arduino Nano with the following pin configuration:
Arduino pin
Radio pin
D3 CH1
D5 CH2
D2 CH3
D4 CH4
D12 CH5
D6 CH6
  1. Now, connect the Gyroscope to the Arduino Nano with the following configuration:
Arduino pin Gyroscope pin
5V 5V
  1. You are left with the four wires of the ESC signals; let’s connect them to the Arduino Nano now, as shown in the following configuration:
Arduino pin Motor signal pin
D7 Motor 1
D8 Motor 2
D9 Motor 3
D10 Motor 4

Our connection is almost complete.

Now we need to power the Arduino Nano and the ESCs. Before doing that, making common the ground means connecting both the wired to the ground.

Before going any further, we need to upload the code to the brain of our drone, which is the Arduino Nano. The code is a little bit big. I am going to explain the code after installing the necessary library. You will need a library installed to the Arduino library folder before going to the programming part. The library’s name is PinChangeInt.

Install the library and write the code for the drone. The full code can be found at Github.

Let’s explain the code a little bit.

In the code, you will find lots of functions with calculations. For our gyroscope, we needed to define all the axes, sensor data, pin configuration, temperature synchronization data, I2C data, and so on. In the following function, we have declared two structures for the accel and gyroscope data with all the directions:

typedef union accel_t_gyro_union
     uint8_t x_accel_h;
     uint8_t x_accel_l;
     uint8_t y_accel_h;
     uint8_t y_accel_l;
     uint8_t z_accel_h;
     uint8_t z_accel_l;
     uint8_t t_h;
     uint8_t t_l;
     uint8_t x_gyro_h;
     uint8_t x_gyro_l;
     uint8_t y_gyro_h;
     uint8_t y_gyro_l;
     uint8_t z_gyro_h;
     uint8_t z_gyro_l;
   } reg;
     int x_accel;
     int y_accel;
     int z_accel;
     int temperature;
     int x_gyro;
     int y_gyro;
     int z_gyro;
   } value;

In the void setup() function of our code, we have declared the pins we have connected to the motors:

myservoT.attach(7); //7-TOP
myservoR.attach(8); //8-Right
myservoB.attach(9); //9 - BACK
myservoL.attach(10); //10 LEFT

We also called our test_gyr_acc() and test_radio_reciev() functions, for testing the gyroscope and receiving data from the remote respectively. In our test_gyr_acc() function. In our test_gyr_acc()
function, we have checked if it can detect our gyroscope sensor or not and set a condition if there is an error to get gyroscope data then to set our pin 13 high to get a signal:

void test_gyr_acc() 
  error = MPU6050_read (MPU6050_WHO_AM_I, &c, 1);
  if (error != 0) 
     while (true) 
        digitalWrite(13, HIGH);
        digitalWrite(13, LOW);

We need to calibrate our gyroscope after testing if it connected. To do that, we need the help of mathematics. We will multiply both the rad_tilt_TB and rad_tilt_LR by 2.4 and add it to our x_a and y_a respectively. then we need to do some more calculations to get correct x_adder and the y_adder:

void stabilize()
   P_x = (x_a + rad_tilt_LR) * 2.4;
   P_y = (y_a + rad_tilt_TB) * 2.4;
   I_x = I_x + (x_a + rad_tilt_LR) * dt_ * 3.7;
   I_y = I_y + (y_a + rad_tilt_TB) * dt_ * 3.7;
   D_x = x_vel * 0.7;
   D_y = y_vel * 0.7;
   P_z = (z_ang + wanted_z_ang) * 2.0;
   I_z = I_z + (z_ang + wanted_z_ang) * dt_ * 0.8;
   D_z = z_vel * 0.3;
   if (P_z > 160) 
       P_z = 160;
   if (P_z < -160) 
       P_z = -160;
   if (I_x > 30) 
       I_x = 30;
   if (I_x < -30) 
       I_x = -30;
   if (I_y > 30) 
       I_y = 30;
   if (I_y < -30) 
       I_y = -30;
   if (I_z > 30) 
       I_z = 30;
   if (I_z < -30) 
       I_z = -30;
   x_adder = P_x + I_x + D_x;
   y_adder = P_y + I_y + D_y;

We then checked that our ESCs are connected properly with the escRead() function. We also called elevatorRead() and aileronRead() to configure our drone’s elevator and the aileron.

We called test_radio_reciev() to test if the radio we have connected is working, then we called check_radio_signal() to check if the signal is working. We called all the stated functions from the void loop() function of our Arduino code. In the void loop() function, we also needed to configure the power distribution of the system. We added a condition, like the following:

if(main_power > 750)
 } else

We also set a boundary; if main_power is greater than 750 (which is a stabling value for our case), then we stabilize the system or we call zero_on_zero_throttle(), which initializes all the values of all the directions.

After uploading this, you can control your drone by sending signals from your remote control. Now, to make it a Follow Me drone, you need to connect a Bluetooth module or a GPS. You can connect your smartphone to the drone by using a Bluetooth module (HC-05 preferred) or another Bluetooth module as master-slave usage. And, of course, to make the drone follow you, you need the GPS. So, let’s connect them to our drone.

To connect the Bluetooth module, follow the following configuration:

Arduino pin Bluetooth module pin
5V 5V

See the following diagram for clarification:


For the GPS, connect it as shown in the following configuration:

Arduino pin GPS pin
D11 TX
D12 RX
5V 5V

See the following diagram for clarification:

Since all the sensors usages 5V power, I would recommend using an external 5V power supply for better communication, especially for the GPS.

If we use the Bluetooth module, we need to make the drone’s module the slave module and the other module the master module. To do that, you can set a pin mode for the master and then set the baud rate to at least 38,400, which is the minimum operating baud rate for the Bluetooth module. Then, we need to check if one module can hear the other module. For that, we can write our void loop() function as follows:

if(Serial.available() > 0)
   state = Serial.read();
if (state == '0') 
    digitalWrite(Pin, LOW);
    state = 0;
else if (state == '1') 
    digitalWrite(Pin, HIGH);
    state = 0;

And do the opposite for the other module, connecting it to another Arduino. Remember, you only need to send and receive signals, so refrain from using other utilities of the Bluetooth module, for power consumption and swiftness.

If we use the GPS, we need to calibrate the compass and make it able to communicate with another GPS module.

We need to read the long value from the I2C, as follows:

float readLongFromI2C() 
     unsigned long tmp = 0;
     for (int i = 0; i < 4; i++) 
        unsigned long tmp2 = Wire.read();
        tmp |= tmp2 << (i*8);
     return tmp;
float readFloatFromI2C() 
     float f = 0;
     byte* p = (byte*)&f;
     for (int i = 0; i < 4; i++) 
     p[i] = Wire.read();
     return f;

Then, we have to get the geo distance, as follows, where DEGTORAD is a variable that changes degree to radian:

float geoDistance(struct geoloc &a, struct geoloc &b) 
      const float R = 6371000; // Earth radius
      float p1 = a.lat * DEGTORAD;
      float p2 = b.lat * DEGTORAD;
      float dp = (b.lat-a.lat) * DEGTORAD;
      float dl = (b.lon-a.lon) * DEGTORAD;
      float x = sin(dp/2) * sin(dp/2) + cos(p1) * cos(p2)  
      * sin(dl/2) * sin(dl/2);
      float y = 2 * atan2(sqrt(x), sqrt(1-x));
      return R * y;

We also need to write a function for the Geo bearing, where lat and lon are latitude and longitude respectively, gained from the raw data of the GPS sensor:

float geoBearing(struct geoloc &a, struct geoloc &b) 
  float y = sin(b.lon-a.lon) * cos(b.lat); 
  float x = cos(a.lat)*sin(b.lat) - sin(a.lat)*cos(b.lat)*cos(b.lon-a.lon); 
  return atan2(y, x) * RADTODEG; 

You can also use a mobile app to communicate with the GPS and make the drone move with you. Then the process is simple. Connect the GPS to your drone and get the TX and RX data from the Arduino and spread it through the radio and receive it through the telemetry, and then use the GPS from the phone with DroidPlanner or Tower. You also need to add a few lines in the main code to calibrate the compass. You can see the previous calibration code. The calibration of the compass varies from location to location. So, I would suggest you use the try-error method. In the following section, I will discuss how you can use an ESP8266 to make a GPS tracker that can be used with your drone.

We learned to build a Follow Me-type drone and also used DroidPlanner 2 and Tower to configure it. Know more about using a smartphone to enable the follow me feature of ArduPilot and GPS tracker using ESP8266 from this book Building Smart Drones with ESP8266 and Arduino.

Read More


Please enter your comment!
Please enter your name here