ESP8266 Uploads GPS Position to Adafruit IO
by Mark Conner in Circuits > Arduino
20101 Views, 48 Favorites, 0 Comments
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.
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.
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 one Feed 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 here Code from Github
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>
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