Autonomous Navigation With an ESP8266

Display showing current heading (bearing), target heading, direction to turn and GPS position

We think its good to have drones at sea, we need them, we need them to be cheap, so we can do stuff in our oceans like iron fertilizes, grow crops, generate fresh water etc. To work on that we develop a simple ocean drone at low cost. The parts of which are easy to buy. Thanks to an active tinkering community the software development is now also very easy.

D1 Mini Pro esp8266 board

We use an ESP8266 module called the D1 Mini Pro because it is easy to program using the Arduino IDE and it has a respectable transmission range of up to 100 meters (Wifi). We plan to use an external transmitter (1,5 km range) but for testing this is enough. Once it navigates we can program it to stay close to the side of the pond we will test in.


The GPS module is from amazon, the NEO-6M. It spits out the GPS data through a serial connection at 9600 Baud. It has the coordinates, spead over land and altitude if you need that data. It pinpointed our desk very precisely inside our home from about 4 satelites.

HMC 5883L

The compass module is the HMC 5883L three axis magnetometer. It has an I2C connection, for which there is an actual adafruit library, so it is easy to query. Its not tilt compensated so this might be a problem at sea. For the purpose of a first prototype to work from this will do.

Battery with charge controller

As a power source we want to use a floating solar panel, but for now we use this LiPo battery and charging module. We also add an oled screen for good measure. Servo’s can be controlled directly from the ESP8266 pins. We tested all the connected devices and we get input from them and can output to the screen. I2C connections can be shared, its a bus type protocol. The GPS is read by so called soft serial input, which can be any pin.

GPS and compass calculating a heading to a waypoint. Display shows bearing, heading, direction to turn, longitude and lattitude

The code below will show you the heading and turn direction (left or right) you will have to make to reach the coordinates (latto,lonto) given at the beginning of the script. Those coordinates can be found using Google Maps. They show as decimal coordinates in the address bar. The screen shows your coordinates as you move. The next steps are to make it possible to set waypoints (new destinations) and use the turn direction to actually control a small drone boat.

#include <SoftwareSerial.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>
#include <Adafruit_SSD1306.h>

    // Compass Assign a unique ID to this sensor at the same time 
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);

    // Oled Display
#define OLED_RESET 0  // GPIO0
Adafruit_SSD1306 display(OLED_RESET);

    // GPS
String gpsline;
String gpspos;

float latfrom; // gps current coordinates
float lonfrom; // gps current coordinates
float latto = 52.107177; 
float lonto = 4.269356;
float heading; // the direction you should go
float bearing; // the direction you are pointed
float control; // the direction 1 = right -1 = left to turn

static const int RXPin = 0, TXPin = 15; // Pin D3
static const uint32_t GPSBaud = 9600;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

void setup()

    if( ! mag.begin())
        Serial.println("ERROR : Check the compass wiring");

    // Oled
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  
    // initialize with the I2C addr 0x3C (for the 64x48)
    //text display tests
    display.println("Tracker 0.1");

     // Start GPS

// read compass
float getcompassheading() {
    sensors_event_t event; 
    mag.getEvent( & event);

    float currentheading = atan2(event.magnetic.y, event.magnetic.x);
    if(currentheading < 0)
        currentheading += 2 * PI;
    return currentheading * 180 / M_PI; 

// calculate bearing from two float coordinates
float calculatebearing(float lat, float lon, float lat2, float lon2){

    float teta1 = radians(lat);
    float teta2 = radians(lat2);
    float delta1 = radians(lat2-lat);
    float delta2 = radians(lon2-lon);

    float y = sin(delta2) * cos(teta2);
    float x = cos(teta1) * sin(teta2) - sin(teta1) * cos(teta2) * cos(delta2);
    float brng = atan2(y, x);
    brng = degrees(brng); // radians to degrees
    brng = (((int)brng + 360) % 360); 

    return brng;


    // string function to parse GPS
    String getValue(String data, char separator, int index)
    int found = 0;
    int strIndex[] = {0, -1};
    int maxIndex = data.length()-1;

    for(int i=0; i <= maxIndex && found <= index; i ++ ){
        if(data.charAt(i) == separator || i == maxIndex){
            found ++ ;
            strIndex[0] = strIndex[1] + 1;
            strIndex[1] = (i == maxIndex) ? i + 1: i;

    return found > index ? data.substring(strIndex[0], strIndex[1]): "";

// Move the decimal point to where it should be
float cleancoordinate(String coordinate) {
    char ch = '.';
    String c1 = getValue(coordinate, '.', 0);
    String c2 = getValue(coordinate, '.', 1);    
    int clen = c1.length();
    String cbefore = c1.substring(0, clen-2); 
    String cafter = c1.substring(clen-2, clen);
    String result = cbefore + '.' + cafter + c2;
    return result.toFloat();

// translate difference between heading and bearing
// into a control signal go left or right
String getcontroldirection(float bearing1,float heading1) {

    //Serial.println("get control direction");

    //Serial.println(" bearing " + String(bearing1) + " heading " + String(heading1));

    float opposite = heading1 + 180;
    if(opposite > 360) {
        opposite = opposite - 360;

    if(heading1 > 0 and heading1 < 180) {
      if(bearing1 < heading1 and bearing1 > 0) {
        control = 1;
        return "1 right";     

      if(bearing1 > (heading1 + 180)) { 
        control = 1;
        return "2 right";        
      if(bearing1 < (heading1 + 180) and bearing1 > heading1) {
          control = -1;
          return "3 left";      

    } else {

      if(bearing1 < heading1 and bearing1 > opposite) {
        control = 1;
        return "4 right";  

      if(bearing1 > heading1 and bearing1 < 360) {
        control = -1;
         return "5 left";

      if(bearing1 > 0 and bearing1 < opposite) {
         control = -1;
         return "6 left";     

void loop()
        gpsline = ss.readStringUntil('\n');

        gpspos = gpsline.substring(1,6);

        bearing  = getcompassheading();

        // Only parse the GPRMC line of the GPS info
        if(gpspos == "GPRMC") {

            String slonfrom = gpsline.substring(19, 29);        
            float lonfrom = cleancoordinate(slonfrom);
            String slatfrom = gpsline.substring(32, 42);
            float latfrom = cleancoordinate(slatfrom);
            heading = calculatebearing(latfrom, lonfrom, latto, lonto);  
            String advice = getcontroldirection(bearing,heading);
            display.println(String(bearing) + ' ' + advice);
            display.println(String(heading) + ' ' + String(control));


You can order a complete device for 80,- Euro ext btw/shipping if you mail us at Any requests are welcome.

The data can also be shared to your phone, by Wifi where you can have a screen to set a new target. This needs some development but should allow you to use Google Maps to set waypoints.

You could make Robocop glasses 😉

Next step is to add a 1,5 km transmitter to the mix, this will allow remote control from the beach or side of the water as we plan to use the controller in a floating device. We’re also looking at an RC interface.

London will be China’s new Trans-Atlantic Hub?

This thought we had years ago is starting to recur to us these days : The UK is selling itself to China. It also seems to sell itself to the US, but the US seemst o have retracted because it can’t easily get the fracking and meat export expansion it wants. The UK also is liable to lose its northern oil reserves if Scotland splits off..

Boris Johnson offers residence to Hong Kong people

Why would we think that the UK is selling itself to China, that it is punishing itself in service of China. Simple : Old scores. We can all read in the history books that Britain was a complete asshole to China and India, much more so than Holland who left much sooner. The UK addicted the chinese to opium and went up their rivers with gunships when they could not pay for the porcelain in silver, as China requested. Then they grew the opium in Afganistan and this brought a lot of wealth to the island. The story of India is as warped. The people there where forbidden to find salt on the beach, and had to instead buy it from England, in return for Indian wealth. People died of lack of salt until Ghandi arrived and turned the relatively docile population into a force that the brits could no longer ignore.

So if the plan of Britain is to allow its territory to be used by the chinese, this means it can become a transatlantic logistics hub. It happens so that China is driving people out of Hong Kong in its attempt to annex it fully. Boris Johnson welcomes these people, a transmigration of a huge number of people used to work a multi language port. If even 10% would move it would still be 300.000 Hong Kong residents.

Now if you want the UK to be a Chinese satelite, then you’d like it to be outside the EU. Hence the no deal Brexit. You’d completely by pass the european ports when it comes to US logistics. Why not transpacific? Because the oil producers are in the middle of the EU route, and you want to supply the EU, which you can do though EU ports no problem.

Is this a likely scenario? Respond to Twitter @climatebabes