Introduction: ESP8266 Uploads GPS Position to Adafruit IO

In this Instruct able I'm going to show you how to use your ESP8266 and Ublox 6m, that we built in my previous Instructable, and use it upload your GPS position to Adafruit IO over WiFi.

You can then map it's position and see immediately where on earth your Internet of Things (Iot) sensor is. Use it to track your dog as he walks around the yard and connect it to IFTTT to alert you if he travels too far away from home, or use it to track the location of something else.

I uploaded a video Youtube explaining more about the Instructable. You can watch it here. Youtube Video

Andreas Spiess has an excellent Youtube Video explaining how Adafruit IO works, I would encourage you to watch it for more information.

Andrea Spiess Youtube Adafruit IO Video

Step 1: Hookup the ESP8266 and Ublox GPS

Wire up the ESP8266-12e (NodeMCU) and Ublox GPS just like we did in my previous Instructable. Check it out here if you haven't already seen it. Link to Previous Instructable or watch the Youtube Video above.

You will need the following items.
ESP8266 aka NodeMCU 12-e
Ublox 6m GPS or compatible
Oled display
Breadboard and wires
Arduino IDE
Adafruit IO account
And an IFTTT account (optional) if you want to be alerted if your Iot device travels too far away from home.

Step 2: Get an Adafruit IO Account

First you'll need to go to Adafruit and signup for the Beta Test of Adafruit IO (they're still working out some bugs). Once you have an account, you'll need to create at least oneFeed and a Dashboard. The feed is how your ESP8266 will be able to upload GPS data to Adafruit's server, in this case we will upload our Latitude, Longitude, Altitude, and our distance from "Home". The dashboard is how Adafruit will display that data back to you, in this case it will plot our course on a map and we will be able to see where our ESP8266 is.

Keep in mind, that the ESP8266 is uploading this data to Adafruit via WIFi, so we are limited by our routers wifi signal as to how far away we can travel.

You will need to create a Feed called "gpslatlng" without the quotes. This is the name I called it in my code you could name it something else but you would have to make the necessary changes in the code (probably best to leave it the same for now).

1. Go to Adafruit IO and click on Feeds
2. Second, in the top right hand side - click on Create Feed
3. Third, when it asks your for the name, type gpslatlng
4. You don't have to give it a description but you can if you like
5. That's it! You've created your first feed.

Next you'll need to create a Dashboard

1. Go to Adafruit IO and click on "Your Dashboards"
2. Next, click Create Dashboard
3. When it asks you for a name, type GPS Location - or anything else you would like to call it
4. Next you'll need to click the "+" button in the top right hand corner to "Create a new Block"

Blocks are how your data is displayed back to you on your dashboard, think of this as the gauges on the dashboard of your car, you can have multiple "Blocks" or gauges displaying different data. For now well just be displaying our GPS position on a map.

5. Click on the Map Block, it's the one at the bottom
6. Next you'll need to select which Feed you will getting data from, select "gpslatlng" the feed we just created
7. Then click "Create Block", now you've created your dashboard

Next we'll upload the Arduino Code!

You can also Download it from Github hereCode from Github

Step 3: Upload the Code - Copy and Paste the Code Into You Arduino IDE

<p>#include "Adafruit_MQTT.h"                                  // Adafruit MQTT library<br>#include "Adafruit_MQTT_Client.h"                           // Adafruit MQTT library</p><p>#include "ESP8266WiFi.h"                                    // ESP8266 library     
#include <Adafruit_ssd1306syp.h>>                            // Adafruit Oled library for display</p><p>#include  <TinyGPS++.h >                         // Tiny GPS Plus Library</p><p>#include  <SoftwareSerial.h>                                // Software Serial Library so we can use Pins for communication with the GPS module</p><p>#define SDA_PIN 4                                           // uses GPIO pins 4(SDA) and 5(SCL) of the ESP8266 Adafruit Feather
#define SCL_PIN 5                                           // also known as pins D1(SCL) and D2(SDA) of the NodeMCU ESP-12
Adafruit_ssd1306syp display(SDA_PIN,SCL_PIN);               // Set OLED display pins</p><p>static const int RXPin = 12, TXPin = 13;                    // Ublox 6m GPS module to pins 12 and 13
static const uint32_t GPSBaud = 9600;                       // Ublox GPS default Baud Rate is 9600</p><p>TinyGPSPlus gps;                                            // Create an Instance of the TinyGPS++ object called gps
SoftwareSerial ss(RXPin, TXPin);                            // The serial connection to the GPS device</p><p>const double HOME_LAT = **.******;                          // Enter Your Latitude and Longitude here
const double HOME_LNG = -**.******;                         // to track how far away the "Dog" is away from Home </p><p>/************************* WiFi Access Point *********************************/</p><p>#define WLAN_SSID       "********"                          // Enter Your router SSID
#define WLAN_PASS       "**********"                        // Enter Your router Password</p><p>/************************* Adafruit.io Setup *********************************/</p><p>#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883                                // use 8883 for SSL
#define AIO_USERNAME    "********"                          // Enter Your Adafruit IO Username
#define AIO_KEY         "********************************"  // Enter Your Adafruit IO Key</p><p>/************ Global State (you don't need to change this!) ******************/</p><p>WiFiClient client;                                          // Create an ESP8266 WiFiClient class to connect to the MQTT server.</p><p>const char MQTT_SERVER[] PROGMEM    = AIO_SERVER;           // Store the MQTT server, username, and password in flash memory.
const char MQTT_USERNAME[] PROGMEM  = AIO_USERNAME;
const char MQTT_PASSWORD[] PROGMEM  = AIO_KEY;</p><p>// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, AIO_SERVERPORT, MQTT_USERNAME, MQTT_PASSWORD);</p><p>/****************************** Feeds ***************************************</p><p>/ Setup a feed called 'gpslat' for publishing.
// Notice MQTT paths for AIO follow the form: /feeds/   // This feed is not needed, only setup if you want to see it
const char gpslat_FEED[] PROGMEM = AIO_USERNAME "/feeds/gpslat";            
Adafruit_MQTT_Publish gpslat = Adafruit_MQTT_Publish(&mqtt, gpslat_FEED);</p><p>// Setup a feed called 'gpslng' for publishing.
// Notice MQTT paths for AIO follow the form: /feeds/   // This feed is not needed, only setup if you want to see it
const char gpslng_FEED[] PROGMEM = AIO_USERNAME "/feeds/gpslng";
Adafruit_MQTT_Publish gpslng = Adafruit_MQTT_Publish(&mqtt, gpslng_FEED);</p><p>// Setup a feed called 'gps' for publishing.
// Notice MQTT paths for AIO follow the form: /feeds/
const char gps_FEED[] PROGMEM = AIO_USERNAME "/feeds/gpslatlng/csv";          // CSV = commas seperated values
Adafruit_MQTT_Publish gpslatlng = Adafruit_MQTT_Publish(&mqtt, gps_FEED);</p><p>/****************************************************/</p><p>void setup() 
{
  Serial.begin(115200);                                 // Setup Serial Comm for Serial Monitor @ 115200 baud
  WiFi.mode(WIFI_STA);                                  // Setup ESP8266 as a wifi station
  WiFi.disconnect();                                    // Disconnect if needed
  delay(100);                                           // short delay
  
  display.initialize();  // init OLED display
  display.clear();                                      // Clear OLED display
  display.setTextSize(1);                               // Set OLED text size to small
  display.setTextColor(WHITE);                          // Set OLED color to White
  display.setCursor(0,0);                               // Set cursor to 0,0
  display.println("  Adafruit IO GPS");  
  display.println("      Tracker"); 
  display.print("---------------------");
  display.update();                                     // Update display
  delay(1000);                                          // Pause X seconds  
    
  ss.begin(GPSBaud);                                    // Set Software Serial Comm Speed to 9600     
   
  display.print("Connecting to WiFi");
  display.update();</p><p>  WiFi.begin(WLAN_SSID, WLAN_PASS);                     // Start a WiFi connection and enter SSID and Password
      while (WiFi.status() != WL_CONNECTED) 
         {                                              // While waiting on wifi connection, display "..."
           delay(500);
           display.print(".");
           display.update();
         } 
           display.println("Connected");
           display.update();             
}                                                       // End Setup</p><p>void loop() {</p><p>  smartDelay(500);                                      // Update GPS data TinyGPS needs to be fed often
  MQTT_connect();                                       // Run Procedure to connect to Adafruit IO MQTT  </p><p>  float Distance_To_Home;                               // variable to store Distance to Home  
  float GPSlat = (gps.location.lat());                  // variable to store latitude
  float GPSlng = (gps.location.lng());                  // variable to store longitude
  float GPSalt = (gps.altitude.feet());                 // variable to store altitude  
  Distance_To_Home = (unsigned long)TinyGPSPlus::distanceBetween(gps.location.lat(),gps.location.lng(),HOME_LAT, HOME_LNG);  //Query Tiny GPS to Calculate Distance to Home
    
  display.clear();    
  display.setCursor(0,0);  
  display.println(F("  GPS Tracking"));
  display.print("---------------------");
  display.update();      </p><p>  display.print("GPS Lat: ");
  display.println(gps.location.lat(), 6);               // Display latitude to 6 decimal points
  display.print("GPS Lon: ");
  display.println(gps.location.lng(), 6);               // Display longitude to 6 decimal points
  display.print("Distance: ");
  display.println(Distance_To_Home);                    // Distance to Home measured in Meters    
  display.update();     </p><p>  // ********************** Combine Data to send to Adafruit IO *********************************
  // Here we need to combine Speed, Latitude, Longitude, Altitude into a string variable buffer to send to Adafruit    
                                                            
            char gpsbuffer[30];                         // Combine Latitude, Longitude, Altitude into a buffer of size X
            char *p = gpsbuffer;                        // Create a buffer to store GPS information to upload to Adafruit IO                       </p><p>            dtostrf(Distance_To_Home, 3, 4, p);         // Convert Distance to Home to a String Variable and add it to the buffer
            p += strlen(p);
            p[0] = ','; p++;                      
            
            dtostrf(GPSlat, 3, 6, p);                   // Convert GPSlat(latitude) to a String variable and add it to the buffer
            p += strlen(p);
            p[0] = ','; p++;
                                                            
            dtostrf(GPSlng, 3, 6, p);                   // Convert GPSlng(longitude) to a String variable and add it to the buffer
            p += strlen(p);
            p[0] = ','; p++;  
                                                            
            dtostrf(GPSalt, 2, 1, p);                   // Convert GPSalt(altimeter) to a String variable and add it to the buffer
            p += strlen(p);
                                                                        
            p[0] = 0;                                   // null terminate, end of buffer array</p><p>            if ((GPSlng != 0) && (GPSlat != 0))         // If GPS longitude or latitude do not equal zero then Publish
              {
              display.println("Sending GPS Data ");     
              display.update(); 
              gpslatlng.publish(gpsbuffer);             // publish Combined Data to Adafruit IO
              Serial.println(gpsbuffer);  
              }
            
            gpslng.publish(GPSlng,6);                   // Publish the GPS longitude to Adafruit IO                 
            
            if (! gpslat.publish(GPSlat,6))             // Publish the GPS latitude to Adafruit IO
               {
                 display.println(F("Failed"));          // If it failed to publish, print Failed
               } else 
                  {
                   //display.println(gpsbuffer);
                   display.println(F("Data Sent!"));                   
                   }  
        display.update();
        delay(1000);         
    
  if (millis() > 5000 && gps.charsProcessed() < 10)
    display.println(F("No GPS data received: check wiring"));
  
  // Wait a bit before scanning again
  display.print("Pausing...");
  display.update();
  smartDelay(500);                                      // Feed TinyGPS constantly
  delay(1000);
}</p><p>// **************** Smart delay - used to feed TinyGPS ****************</p><p>static void smartDelay(unsigned long ms)                 
{
  unsigned long start = millis();
  do 
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}</p><p>// **************** MQTT Connect - connects with Adafruit IO *****************
void MQTT_connect() {
  
  int8_t ret;
  if (mqtt.connected()) { return; }                     // Stop and return to Main Loop if already connected to Adafruit IO
  display.print("Connecting to MQTT... ");
  display.update();</p><p>  uint8_t retries = 3;
  while ((ret = mqtt.connect()) != 0) {                 // Connect to Adafruit, Adafruit will return 0 if connected
       display.println(mqtt.connectErrorString(ret));   // Display Adafruits response
       display.println("Retrying MQTT...");
       mqtt.disconnect();
       display.update();
       delay(5000);                                     // wait X seconds
       retries--;
       if (retries == 0) {                              // basically die and wait for WatchDogTimer to reset me                                                          
         while (1);         
       }
  }
  display.println("MQTT Connected!");
  display.update();
  delay(1000);
}</p>

Step 4: Make Necessary Changes to the Code

Next you'll need to make some changes to the code to make it your own.

1. First you'll need to enter your GPS location. Latitude and Longitude

You can get this from the Ublox 6m or google it!

2. Next you'll need to enter your routers SSID and Password, don't worry no one else will be able to see it.

3. You'll need to enter your Adafruit IO username - this is the username you created when you setup the Adafruit IO account

4. and you'll need to enter your Adafruit IO "key" - you can get this from the "Settings" Tab from Adafruit - just click on "View AIO Keys", copy and past the key into the code.

That's it! Now upload the code to your ESP8266 and check the data stream to your "Feed" to confirm you are transmitting the GPS information, then you can watch your Dashboard to see your location on the Map

Comments

author
jgreusel1 (author)2016-11-20

I succeeded in running the first GPS program with Lat/Long data. Now trying to run the tracking program. It loads without errors but the display stops at "MQTT connecting" and the program loops to the beginning. The wifi element works as I can see it on my network. Anyone have a thought?

author
OUTATIME88 (author)jgreusel12016-11-28

I would say to make sure you are connecting up to the Adafruit IO server, try one of the Adafruit examples first. Start small, upload something simple. Make sure you have entered the correct Adafruit username and AIO Key in the code. Also, the same applies to the WiFi modem. Make sure you have entered the proper SSID and password in the code. Also, your firewall may be blocking you as well. Take it down, temporarily of course, until you can eliminate that as a possibility. Good luck! Hope you get it working!

author
jgreusel1 (author)OUTATIME882016-12-01

It works now. I backed up 4-5 versions of the MQTT library recompiled and bingo- it works. Thanks so much for such a fun project!

author
AXR AMAR (author)2016-05-21

Nice !

About This Instructable

5,085views

35favorites

License:

Bio: EZtech electronics
More by OUTATIME88:NodeMCU Motion Activated Security SystemNational Data Buoy Center Weather DisplayESP8266 uploads GPS position to Adafruit IO
Add instructable to: