[SOLVED] Arduino or NodeMCU GPS tracking system on Map widget

thanks. Please do not hesitate to help me out

No problem… my best advice… listen to @Costas!! He is smart, but like me, prone to back away if his directions go unheeded.

1 Like

SM for this sketch (you might need to set GPSBaud at 9600):

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
/*
   This sample sketch demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 12(rx) and 13(tx).
*/
static const int RXPin = 12, TXPin = 13;
static const uint32_t GPSBaud = 4800;

// The TinyGPS++ object
TinyGPSPlus gps;

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

void setup()
{
  Serial.begin(115200);
  ss.begin(GPSBaud);

  Serial.println(F("DeviceExample.ino"));
  Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
  Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
  Serial.println(F("by Mikal Hart"));
  Serial.println();
}

void loop()
{
  // This sketch displays information every time a new sentence is correctly encoded.
  while (ss.available() > 0)
    if (gps.encode(ss.read()))
      displayInfo();

  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println(F("No GPS detected: check wiring."));
    while(true);
  }
}

void displayInfo()
{
  Serial.print(F("Location: ")); 
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Date/Time: "));
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.year());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F(" "));
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(F("."));
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.print(gps.time.centisecond());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.println();
}
1 Like

gps location from serial monitor worked

Progress at last.

I only have GPS with my Smartphones but give me some time and I will Blynkify your working sketch.

1 Like

thank you so much. I’m waiting :tulip: :tulip: :tulip:

Are you using 4800 or 9600 for the GPS baud?

1 Like

9600

Look through all the comments in this sketch and see how you go with it.

/* BlynkifyGPS.ino for https://community.blynk.cc/t/arduino-or-nodemcu-gps-tracking-system-on-map-widget/15739
  Sketch for physical GPS device connected to a decent ESP
  In map widget set SHOW MY LOCATION to NO unless you also want Smartphone actual location in addition to GPS device + ESP
*/
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

TinyGPSPlus gps; // The TinyGPS++ object

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

BlynkTimer timer;

char auth[] = "4bb191e6da5a438bb071ecca688732f3";
char ssid[] = "MikroTik Home";
char pass[] = "";
char server[] = "192.168.1.104";

//unsigned int move_index;         // moving index, to be used later
unsigned int move_index = 1;       // fixed location for now
bool simulation = false;           // set to true for simulation mode, else false. If IranHack is true this must be false
                                   // simulation location is in Egypt
                                   
bool IranHack = false;             // set to true if GPS is faulty, else false. If simulation is true this must be false

WidgetMap myMap(V5);

void setup()
{
  Serial.begin(115200);
  Serial.println();
  ss.begin(GPSBaud);
  Blynk.begin(auth, ssid, pass, server);
  timer.setInterval(5000L, checkGPS); // every 5s check if GPS is connected, only really needs to be done once
}

void checkGPS(){
  if (gps.charsProcessed() < 10)
  {
    Serial.println(F("No GPS detected: check wiring."));
    Blynk.virtualWrite(V10, "GPS ERROR");  // Value Display widget set as PUSH frequency on V10
    Blynk.virtualWrite(V7, "--------");    // Value Display widget set as PUSH frequency on V7 LATITUDE
    Blynk.virtualWrite(V8, "--------");    // Value Display widget set as PUSH frequency on V8 LONGITUDE
  }
}

void loop()
{
  delay(1000);  // NOT RECOMENDED
  if(simulation == true || IranHack == true)
  {
    displayInfo();  
  }
  else
  {
    while (ss.available() > 0)  // sketch displays information every time a new sentence is correctly encoded.
      if (gps.encode(ss.read()))
        displayInfo();
  }
  Blynk.run();
  timer.run();
}

void displayInfo()
{ 

  if (gps.location.isValid() || simulation == true || IranHack == true) 
  {
    //move_index++;                        // moving index, maybe use later
    Blynk.virtualWrite(V10, "GPS OK");
    float latitude = (gps.location.lat());  // removed , 6 as it can't be used for creating the float
    float longitude = (gps.location.lng()); // removed , 6 as it can't be used for creating the float

    if(latitude == 0 && longitude == 0 )    // checking to see if the 2 floats variables are correct
    {
      Blynk.virtualWrite(V7, "--------");   
      Blynk.virtualWrite(V8, "--------");
      Blynk.virtualWrite(V10, "0,0");
    }
 
    if(simulation == true)           // location in Egypt
    {
      latitude  = 30.000123;       // also used for debugging
      longitude = 30.000987;       // also used for debugging  
    }
    
    if(IranHack == true)
    {
      latitude  = 32.644824;
      longitude = 51.681746;
    }    
    Serial.print("LAT:  ");
    Serial.println(latitude, 6);  // float to x decimal places
    Serial.print("LONG: ");
    Serial.println(longitude, 6);
      
    Blynk.virtualWrite(V7, String(latitude, 6));   
    Blynk.virtualWrite(V8, String(longitude, 6));  

    myMap.location(move_index, latitude, longitude, "GPS_Location");
  }
  else
  {
    Serial.print(F("INVALID"));
    Blynk.virtualWrite(V10, "GPS INVALID");
    Blynk.virtualWrite(V7, "--------");   
    Blynk.virtualWrite(V8, "--------");  
  }

  Serial.println();
}
4 Likes

@Costas @Gunner
thanks a lot. the problem is solved :rose: I will never forget this great favor

update: the NodeMCU disconnecting from AP and cant keep connection

That will be because the main loop() is not really suitable for Blynk.
I just wanted to ensure your GPS and the Map widget were working OK.
Now you know the basic system works the fine tuning can begin.

1 Like

thanks. which line is need tuning ?

@ErfanDL this area in loop() is what needs to be fine tuned but it’s a little difficult for me without a GPS device, hence some of the simulation code in the sketch:

  delay(1000);  // NOT RECOMENDED
  if(simulation == true || IranHack == true)
  {
    displayInfo();  
  }
  else
  {
    while (ss.available() > 0)  // sketch displays information every time a new sentence is correctly encoded.
      if (gps.encode(ss.read()))
        displayInfo();
  }
1 Like

with uncommenting delay(1000); device status rapidly online and offline but location updating on map widget

delay() should not normally be used at all in a Blynk loop() and you should call the GPS function at timed intervals. This might be a little difficult for you as a noob to Arduino and Blynk as you need to be sure the GPS has the full stream before processing the data etc.

With trial and error you could try reducing the 1000 to see if that helps.

If you had more Blynk experience you could change the delay() time with a slider rather than changing the sketch.

1 Like

Can I create new topic and ask question about disconnecting problem ? ( Of course if you permit me )

You could but really it’s likely to be very specific to the GPS sketch I provided for you.

1 Like

@ErfanDL I have created a 30s timed interval to read the GPS data and removed everything from loop().
See how this goes:

/* BlynkifyGPSv2.ino for https://community.blynk.cc/t/arduino-or-nodemcu-gps-tracking-system-on-map-widget/15739
  Sketch for physical GPS device connected to a decent ESP
  In map widget set SHOW MY LOCATION to NO unless you also want Smartphone actual location in addition to GPS device + ESP
*/
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

TinyGPSPlus gps; // The TinyGPS++ object

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

BlynkTimer timer;

char auth[] = "4bb191e6da5a438bb071ecca688732f3";
char ssid[] = "MikroTik Home";
char pass[] = "";
char server[] = "192.168.1.104";

//unsigned int move_index;         // moving index, to be used later
unsigned int move_index = 1;       // fixed location for now
bool simulation = false;           // set to true for simulation mode, else false. If IranHack is true this must be false
                                   // simulation location is in Egypt
                                   
bool IranHack = false;             // set to true if GPS is faulty, else false. If simulation is true this must be false

WidgetMap myMap(V5);

void setup()
{
  Serial.begin(115200);
  Serial.println();
  ss.begin(GPSBaud);
  Blynk.begin(auth, ssid, pass, server);

  // disable GPS device checking for now
  //timer.setInterval(5000L, checkGPS); // every 5s check if GPS is connected, only really needs to be done once

  timer.setInterval(30000L, readGPS); // read GPS data every 30s
  readGPS();                          // read GPS data on each reboot after connection to Blynk server
}

void readGPS(){
  if(simulation == true || IranHack == true)
  {
    displayInfo();  
  }
  else
  {
    while (ss.available() > 0)  // sketch displays information every time a new sentence is correctly encoded.
      if (gps.encode(ss.read()))
        displayInfo();
  }  
}

void checkGPS(){
  if (gps.charsProcessed() < 10)
  {
    Serial.println(F("No GPS detected: check wiring."));
    Blynk.virtualWrite(V10, "GPS ERROR");  // Value Display widget set as PUSH frequency on V10
    Blynk.virtualWrite(V7, "--------");    // Value Display widget set as PUSH frequency on V7 LATITUDE
    Blynk.virtualWrite(V8, "--------");    // Value Display widget set as PUSH frequency on V8 LONGITUDE
  }
}

void loop()
{
  Blynk.run();
  timer.run();
}

void displayInfo()
{ 

  if (gps.location.isValid() || simulation == true || IranHack == true) 
  {
    //move_index++;                        // moving index, maybe use later
    Blynk.virtualWrite(V10, "GPS OK");
    float latitude = (gps.location.lat());  // removed , 6 as it can't be used for creating the float
    float longitude = (gps.location.lng()); // removed , 6 as it can't be used for creating the float

    if(latitude == 0 && longitude == 0 )    // checking to see if the 2 floats variables are correct
    {
      Blynk.virtualWrite(V7, "--------");   
      Blynk.virtualWrite(V8, "--------");
      Blynk.virtualWrite(V10, "0,0");
    }
  
    if(simulation == true)         // location in Egypt
    {
      latitude  = 30.000123;       // also used for debugging
      longitude = 30.000987;       // also used for debugging  
    }
    
    if(IranHack == true)
    {
      latitude  = 32.644824;
      longitude = 51.681746;
    }    
    Serial.print("LAT:  ");
    Serial.println(latitude, 6);  // float to x decimal places
    Serial.print("LONG: ");
    Serial.println(longitude, 6);
      
    Blynk.virtualWrite(V7, String(latitude, 6));   
    Blynk.virtualWrite(V8, String(longitude, 6));  

    myMap.location(move_index, latitude, longitude, "GPS_Location");
  }
  else
  {
    Serial.print(F("INVALID"));
    Blynk.virtualWrite(V10, "GPS INVALID");
    Blynk.virtualWrite(V7, "--------");   
    Blynk.virtualWrite(V8, "--------");  
  }

  Serial.println();
}
1 Like

thanks. the connection problem is solved but there is no GPS location and there is nothing show on V7 V8 V10