Unsure if my NEO-6M GPS is working or not

I have an ESP32 connected to a NEO-6M GPS Module. I'm trying to get the Latitude and Longitude of my Location so I can put it in my Database in making a GPS Map in my app. My code seems to be okay, no errors or anything, but it still havent given me no data. Both lat and lng just return 0.000000. I heard that I need to go outside or to another area and or waiting for at least an hour or more so the GPS module can have a better chance in getting data, but I'm not sure. Any solutions? Are there any modules you recommend in getting the data faster?

Here is my wiring:
VCC - 3V3
RX - TX2
TX - RX2
GND - GND

And here is the code

#include <Arduino.h>
#if defined(ESP32)
  #include <WiFi.h>
#elif defined(ESP8266)
  #include <ESP8266WiFi.h>
#endif
#include <TinyGPS++.h>
#include <TinyGPSPlus.h>
#include <Wire.h>

//-------------------------------------------------------//
#include <Firebase_ESP_Client.h>
//Provide the token generation process info.
#include "addons/TokenHelper.h"
//Provide the RTDB payload printing info and other helper functions.
#include "addons/RTDBHelper.h"

//Provide the token generation process info.
#include "addons/TokenHelper.h"
//Provide the RTDB payload printing info and other helper functions.
#include "addons/RTDBHelper.h"
// Insert Firebase project API Key
#define API_KEY "***********"

// Insert RTDB URLefine the RTDB URL */
#define DATABASE_URL "***********" 

//Define Firebase Data object
FirebaseData fbdo;

FirebaseAuth auth;
FirebaseConfig config;

unsigned long sendDataPrevMillis = 0;
int count = 0;
bool signupOK = false;
int NoGPSData =0;
//-------------------------------------------------------//

#define WIFI_SSID "***********"
#define WIFI_PASSWORD "***********
#define RXD2 16
#define TXD2 17
HardwareSerial neogps(1);

TinyGPSPlus gps;

void setup() {
  Serial.begin(115200);
  //Begin serial communication Arduino IDE (Serial Monitor)

  //Begin serial communication Neo6mGPS
  neogps.begin(9600, SERIAL_8N1, RXD2, TXD2);

    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED){
    Serial.print(".");
    delay(300);
  }
  Serial.println();
  Serial.print("Connected with IP: ");
  Serial.println(WiFi.localIP());
  Serial.println();
//-------------------------------------------------------//
  /* Assign the api key (required) */
  config.api_key = API_KEY;

  /* Assign the RTDB URL (required) */
  config.database_url = DATABASE_URL;

  /* Sign up */
  if (Firebase.signUp(&config, &auth, "", "")){
    Serial.println("ok");
    signupOK = true;
  }
  else{
    Serial.printf("%s\n", config.signer.signupError.message.c_str());
  }

  /* Assign the callback function for the long running token generation task */
  config.token_status_callback = tokenStatusCallback; //see addons/TokenHelper.h
  
  Firebase.begin(&config, &auth);
  Firebase.reconnectWiFi(true);
 //-------------------------------------------------------//
delay(300);
}
void loop() {
    float latitude = gps.location.lat();
    float longitude = gps.location.lng();
    
  boolean newData = false;
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (neogps.available())
    {
      if (gps.encode(neogps.read()))
      {
        newData = true;
      }
    }
  }

  //If newData is true
  if(newData == true && gps.location.lat() > 0 && gps.location.lng() > 0)
  {
    newData = false;
    Serial.print("Latitude: ");
    Serial.println(gps.location.lat(),6);
    Serial.print("Longitude: ");
    Serial.println(gps.location.lng(),6);  
    //Serial.println(gps.satellites.value());
    if (Firebase.RTDB.setInt(&fbdo, "test/Location/GPSCheck",1)){

    }
    else {
      Serial.println("FAILED");
      Serial.println("REASON: " + fbdo.errorReason());
    }
    if(Firebase.RTDB.setFloat(&fbdo,"test/Location/latitude",latitude)){
      
    }else{
      Serial.println("FAILED");
      Serial.println("REASON: " + fbdo.errorReason());
    }

    if(Firebase.RTDB.setFloat(&fbdo,"test/Location/longitude",longitude)){
      
    }else{
      Serial.println("FAILED");
      Serial.println("REASON: " + fbdo.errorReason());
    }
  //-------------------------------------------------------//   
  }
  else
  {  
    
    if (Firebase.RTDB.setInt(&fbdo, "test/Location/GPSCheck",NoGPSData )){

    }
    else {
      Serial.println("FAILED");
      Serial.println("REASON: " + fbdo.errorReason());
    }
     
    
    Serial.println("No Data");
  }  
  delay(100);
}

You do need to be outside with a clear unobstructed view of the sky. It may work indoors, but that is iffy, at best.
My Neo6M gets enough satellites, if outdoors, in about 5 minutes or less to show me lat and long.

Did you try talking to the GPS with a simple sketch that just does that, nothing more?

Maybe adapt something like this:

//gps test

#include <SoftwareSerial.h>

SoftwareSerial mySerial(4, -1); // RX, TX

void setup()
{
   // Open serial communications
   Serial.begin(9600);
   Serial.println("Neo6M GPS module test code");
   // set the data rate for the SoftwareSerial port
   mySerial.begin(9600);
}

void loop()
{
   if (mySerial.available())
   {
      Serial.print(char(mySerial.read()));
   }
}

You may get signal close to a window or under a skylight, but to be sure, you need to go outside.

I'm not sure what the TX and RX I should put in the Software Serial since it sometimes does not register a D1- D23

Use the plain pin numbers as printed on the board with no D prefix

The NEO-6 datasheet gives TtFF as 26s so it should work in much less than 5 minutes with a good signal.

The most likely cause of poor reception is the antenna - those ceramic patch antennas can be really bad as they are not necessarily tuned to the right frequency!!

IMHO (as I used to work for them) you can't do much better than u-blox for GPS. If you explore the u-blox support you may find reference code.

Well I had it worked but it only gives me missing coordinates like so

$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30
$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,2,1,08,04,,,28,15,,,21,24,,,21,25,,,11*79
$GPGSV,2,2,08,26,,,17,27,,,19,30,,,21,31,,,24*7A
$GPGLL,,,,,,V,N*64

Also I dont know how to get the lat and lng from this if the data was complete

Well first, you need to see lat lon in your data. You've clearly got the serial connection going, but you need the GPS to see satellites. Outside will help, but even there tall buildings or trees can handicap the GPS' ability to see enough satellites.

1 Like

Okay, but I think using float latitude = gps.location.lat() and float longitude = gps.location.lng() would be much easier to get for my ESP32 IMO.

So if I were to go outside, I have to make sure my device is completely unobstructed by anything? So like do I have to be out in a field where nothing is around me in like 1-2 miles? Also how long do I have to wait till I get some data?

Usually, just being outside is enough unless you live in a city surrounded by tower blocks. You can expect to see a lock from a cold start within five minutes, but you may well see some of those other fields filled in rather sooner.

People put these devices in dongles used for interactive car assurance that plug into the OBD2 port to link to the CAN bus. These connectors are usually somewhere near the driver's seat but the GPS antenna can point at the floor but nevertheless usually they work fine. GPS chip designers work incredibly hard to gat the utmost sensitivity so that the end product designer can pay even less attention to the antenna choice and placement. So no, you don't need unobstructed view of the sky. My phone is currently seeing 35 satellites and getting 6 fixes sitting on my desk 3 foot from a window, and phones have pretty poor antennas and non-optimum GPS receivers.

Use a library like TintGPS++ to extract the lat and long. Install the library using the Arduino IDE library manager. See how to install Arduino libraries.

That data does not even show time. You will see the time data before the lat and long become available.

Ok, I'll first test out my code before yours since it seems to be the most simplest and would mean less taxing to compile and do in my device

Also, is there a way I can use my ESP32 or if there is any modules I can purchase, where it can just connect to wifi and ask where is its location without going out?

There are services that will report a geographic position from an IP address. You have probably seen it in action when you visit a commercial website and it figures out roughly where you live. I wouldn't expect it to be able to do much better than naming your town, so whether it would help you depends on the accuracy you require.

Also, I'd expect that there are anomalies in the data so that some IP addresses are misreported, especially when an ISP is reorganizing their network.

Alright so my GPS works! But I have issues with a bit of coding. You see I want to make sure that if my GPS cant get any lat or long data (whether the antennae is obstructed or is just removed somewhow) it would send data to my Database to notify me in my app, it being "/GPS/GPSCheck, 1".

It seems that if I got data already but if I go somewhere it cant, it still remains the same data which is one. Is there someway to fix this?

Here is the code

FirebaseData firebaseData;

FirebaseJson json;
//-----------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------
//GPS Module RX pin to NodeMCU D1
//GPS Module TX pin to NodeMCU D2
const int RXPin = 4, TXPin = 5;
SoftwareSerial neo6m(RXPin, TXPin);
TinyGPSPlus gps;
//-----------------------------------------------------------------------------------


//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
void setup()
{

  Serial.begin(115200);

  neo6m.begin(9600);
  
  wifiConnect();

  Serial.println("Connecting Firebase.....");
  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
  Firebase.reconnectWiFi(true);
  Serial.println("Firebase OK.");

}
//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM


//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
void loop() {
  
  smartdelay_gps(1000);

  if(gps.location.isValid() && gps.location.lat() > 0 && gps.location.lng() > 0) 
  {
    float latitude = gps.location.lat();
    float longitude = gps.location.lng();

    if(Firebase.setFloat(firebaseData, "/GPS/GPSCheck",1))
      {print_ok();}
    else
      {print_fail();}
    if(Firebase.setFloat(firebaseData, "/GPS/f_latitude", latitude))
      {print_ok();}
    else
      {print_fail();}
    //-------------------------------------------------------------
    if(Firebase.setFloat(firebaseData, "/GPS/f_longitude", longitude))
      {print_ok();}
    else
      {print_fail();}
   //-------------------------------------------------------------
  }
  else
  {
    if(Firebase.setFloat(firebaseData, "/GPS/GPSCheck",0))
      {print_ok();}
    else
      {print_fail();}
    Serial.println("No valid GPS data found.");
  }
  
  delay(5000);
}
//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM


//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
static void smartdelay_gps(unsigned long ms)
{
  unsigned long start = millis();
  do 
  {
    while (neo6m.available())
      gps.encode(neo6m.read());
  } while (millis() - start < ms);
}
//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM


//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
void wifiConnect()
{
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(300);
  }
  Serial.println();
  Serial.print("Connected with IP: ");
  Serial.println(WiFi.localIP());
  Serial.println();
}
//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM


//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
void print_ok()
{
    Serial.println("------------------------------------");
    Serial.println("OK");
    Serial.println("PATH: " + firebaseData.dataPath());
    Serial.println("TYPE: " + firebaseData.dataType());
    Serial.println("ETag: " + firebaseData.ETag());
    Serial.println("------------------------------------");
    Serial.println();
}
//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM


//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
void print_fail()
{
    Serial.println("------------------------------------");
    Serial.println("FAILED");
    Serial.println("REASON: " + firebaseData.errorReason());
    Serial.println("------------------------------------");
    Serial.println();
}
//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

void firebaseReconnect()
{
  Serial.println("Trying to reconnect");
  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
}

Is gps.location.isValid() true under those circumstances ?

I think the gps keeps it true after it has a the data. If I go back inside, it didnt change

That sounds wrong, otherwise what is the point of having the function ?

There is also an isUpdated() function that could be useful to determine whether data is being received

Im not sure where I should put that here

if(gps.location.isValid() && gps.location.lat() > 0 && gps.location.lng() > 0) 
  {
    float latitude = gps.location.lat();
    float longitude = gps.location.lng();

    if(Firebase.setFloat(firebaseData, "/GPS/GPSCheck",1))
      {print_ok();}
    else
      {print_fail();}
    if(Firebase.setFloat(firebaseData, "/GPS/f_latitude", latitude))
      {print_ok();}
    else
      {print_fail();}
    //-------------------------------------------------------------
    if(Firebase.setFloat(firebaseData, "/GPS/f_longitude", longitude))
      {print_ok();}
    else
      {print_fail();}
   //-------------------------------------------------------------
  }
  else
  {
    if(Firebase.setFloat(firebaseData, "/GPS/GPSCheck",0))
      {print_ok();}
    else
      {print_fail();}
    Serial.println("No valid GPS data found.");
  }
  
  delay(5000);