Project - gps - problem - gps.location.isValid

Hello, i am working on a project where i use module GSM and module GPS. I have a problem, i dont know why but when i try to use the location from the GSM, the GPS never works, it has to be a problem from the code i believe. If i only put the if(gps.location.isValid()) {..rest of the code..}, the code works fine but when i implement the if(!gps.location.isValid() && millis() > 5000){...rest of the code...} the GPS isnt working anymore, i printed gps.location.isValid() to see what value it has and everytime it had 0. I dont understand why isnt working. Maybe you can help me.

void loop()
{
  while (Serial2.available() > 0) 
  {
    gps.encode(Serial2.read());
    if(gps.location.isValid())
    {
      // Latitude in degrees (double)
      Serial.print("Latitude= "); 
      Serial.print(gps.location.lat(), 6);
      lat_gps = gps.location.lat();

      dtostrf(lat_gps,9,6,Latitude_GPS_char);
      Latitude_GPS = String(Latitude_GPS_char);

      // Longitude in degrees (double)
      Serial.print(" Longitude= ");
      Serial.println(gps.location.lng(), 6);
      lon_gps = gps.location.lng();

      dtostrf(lon_gps,9,6,Longitude_GPS_char);
      Longitude_GPS = String(Longitude_GPS_char);

      if ( (Latitude_GPS!="") && (Longitude_GPS!="") )
      {
        //Serial.println("Latitude: " + String(Latitude_GPS) + "\tLongitude: " + String(Longitude_GPS));
        url = "script.google.com/macros/s/" + Script_ID + "/exec?value1=" + String(Latitude_GPS) + "&value2=" + String(Longitude_GPS);



        Serial.println("AT+HTTPINIT");
        Serial1.println("AT+HTTPINIT");
        delay(1000);
        updateSerial();

        Serial.println("AT+HTTPSSL=1");
        Serial1.println("AT+HTTPSSL=1");
        delay(1000);
        updateSerial();

        Serial.println("AT+HTTPPARA=\"CID\",1");
        Serial1.println("AT+HTTPPARA=\"CID\",1");
        delay(1000);
        updateSerial();

        Serial.println("AT+HTTPPARA=\"URL\","+url);
        Serial1.println("AT+HTTPPARA=\"URL\","+url);
        delay(1000);
        updateSerial();

        Serial.println("AT+HTTPACTION=0");
        Serial1.println("AT+HTTPACTION=0");
        delay(200);
        updateSerial();
        delay(2000);

        Serial1.println("AT+HTTPREAD");
        Serial1.println("AT+HTTPREAD");
        delay(1000);
        updateSerial();

        Serial.println("AT+HTTPTERM");
        Serial1.println("AT+HTTPTERM");
        delay(2000);
        updateSerial();
      }
    }
  }
  if(!gps.location.isValid() && millis() > 5000)
  {
    responce = "";
    Serial1.println("AT+CLBS=1,1"); delay(5000); //Request for location data 
    while (Serial1.available()) 
    {
      char letter = Serial1.read();
      responce = responce + String(letter); //Store the location information in string responce
      delay(1000); 
    }

    Serial.print("Result Obtained as:");   Serial.print(responce); Serial.println("*******");
    prepare_message(); delay(1000); //use prepare_message funtion to prepare the link with the obtained LAT and LONG co-ordinates 

    Serial.println("Latitude: " + Latitude + "\tLongitude: " + Longitude);
    url = "script.google.com/macros/s/" + Script_ID + "/exec?value1=" + Latitude + "&value2=" + Longitude;

    

    Serial.println("AT+HTTPINIT");
    Serial1.println("AT+HTTPINIT");
    delay(1000);
    updateSerial();

    Serial.println("AT+HTTPSSL=1");
    Serial1.println("AT+HTTPSSL=1");
    delay(1000);
    updateSerial();

    Serial.println("AT+HTTPPARA=\"CID\",1");
    Serial1.println("AT+HTTPPARA=\"CID\",1");
    delay(1000);
    updateSerial();

    Serial.println("AT+HTTPPARA=\"URL\","+url);
    Serial1.println("AT+HTTPPARA=\"URL\","+url);
    delay(1000);
    updateSerial();

    Serial.println("AT+HTTPACTION=0");
    Serial1.println("AT+HTTPACTION=0");
    delay(200);
    updateSerial();
    delay(2000);

    Serial1.println("AT+HTTPREAD");
    Serial1.println("AT+HTTPREAD");
    delay(1000);
    updateSerial();

    Serial.println("AT+HTTPTERM");
    Serial1.println("AT+HTTPTERM");
    delay(2000);
    updateSerial();
  }     
}
}
if(!gps.location.isValid() && millis() > 5000)

Why don't you merge it with the prev. if() like

... then check if the code is logically what you expect.

i dont understand what you mean, you say that i should put if(!gps.location.isValid() && millis() > 5000) in "while" or what

If you're doing this indoors, be aware that it's highly likely your GPS module will never see a satellite.

the GPS is connected to the satellite, its working fine, i said i tested without the if(!gps.location.isValid() && millis() > 5000) part and it was working but when i put this if in "while" or even outside of "while" the if(gps.location.isValid()) part is not working anymore, it will send only the location from the GSM command and i dont understand why, even tho it was supposed to work.

Yeah, sorry, I missed that in your wall of text.

You have code that executes if the location is valid, and code that executes if the location is not valid. Both of those add a huge amount of delay, and one or the other is executed between every single character read from the GPS serial input. The receive buffer for Serial2 (the GPS) will constantly be overflowing, resulting in corrupt data.

1 Like

its fine, im trying to resolve this problem for a week i cant do it, i dont really understand how the "gps.location.isValid()" function works

and how should I do it differently, maybe to put a delay or something, i dont know

Please share your whole code. In IDE, press ctrl-t to format, then press ctrl-shft-c to copy for forum, and paste into a new message. That gives us setup(), #includes, and variable declarations that are necessary for context.

Exactly the opposite, the calls to delay() are the problem.
Look at the examples from the TinyGPSPlus library (assuming that is what you are using), there is a function in some of those called smartDelay(). It uses millis() to generate the delay, and during the delay reads data from the GPS and feeds it to the encode() function.

If you want reliable data from the GPS, you cannot do anything in the sketch that will cause a buffer overflow on Serial2.

1 Like

i have delays only for the GSM and I need the AT+ commands to function correctly. I dont know what to remove.

You have:

void loop()
{
  while (Serial2.available() > 0) 
  {
    gps.encode(Serial2.read());
    if(gps.location.isValid())
    {
      ....
    }
  }
  if(!gps.location.isValid() && millis() > 5000)
  {
    ...
  }
}

This is most likely not what you really want to do.

I tried this way too but it doesnt work

void loop()
{
  while (Serial2.available() > 0) 
  {
    gps.encode(Serial2.read());
    if(gps.location.isValid())
    {
      ....
    }
    if(!gps.location.isValid())
    {
    ...
    }
  }
}

Ithat's what I'm saying: yout logic is convoluted and does not do what you intend to do. Clear it up.

For me it seems the logic is fine, i dont know how to "clear it up".

Be careful with the use of gps.location.isvalid();

If the GPS gets a fix, then isvalid() will, as far as I know, return true forever even if the GPS fails or no longer has a fix, assuming the Arduino has power.

The gps.location.isvalid(); return true only if the GPS module is working and is returning a valid location. If, for example, the GPS isnt connected to a satellite, is inside a building this gps.location.isvalid(); should be false. If i use them like this

the gps location will never be valid because:

i dont know to not make the the receive buffer for Serial2 (the GPS) constantly overflowing, resulting in corrupt data, if i delete the delays from the GSM, the commands will not work properly

But that's the program that you have written. Now that you see the problem, correct it.