vshymanskyy / TinyGSM

A small Arduino library for GSM modules, that just works
GNU Lesser General Public License v3.0
1.95k stars 723 forks source link

[SIM7600] Get GPS Coordinates locking for multiple seconds #624

Closed simkard69 closed 4 months ago

simkard69 commented 2 years ago

Hello Everyone,

I was having a strange latency occuring while querying update of GPS coordinates using "getGPS()". Fact is that this function is related to the subfunction "getGPSImpl()" while simply using "getGPSrawImpl()" outputs data instantly.

So here are my 2 cents ... probably not 100% clean, but everything work as it should and GPS coordinates outputs instantly while querying the default "getGPS()" function now. @vshymanskyy >>> Can you please update the files accordingly (you can even change/modify my code, I know it's not 100% perfect). It will be helpful for beginners/newcomers šŸ‘ Thanks for your hard work on that lib !

Same behavior occuring on one function "getSimStatus()" too so I'm going to take a look at it and try to debug this whole thing. These functions are safe as I tested them (there is no time lock) :

... Anyway, regarding "getGPS()", you can just replace this part directly into file "TinyGsmClientSIM7600.h" and things will be ok :

// get GPS informations (MODIFIED BY SIMKARD TO GET RESULTS INSTANTLY WHILE QUERYING)
  bool getGPSImpl(int* fixmode, int* gps_vs, int* glonass_vs, int* beidou_vs, float* lat, float* lon, float* speed = 0, float* alt = 0,
                  int* vsat = 0, int* usat = 0, float* accuracy = 0,
                  int* year = 0, int* month = 0, int* day = 0, int* hour = 0,
                  int* minute = 0, int* second = 0) {
    // init variables
    String GPS_str_GNSSINFO;
    int GPS_str_length          = 0;
    int GPS_str_index_start     = 0;
    int GPS_str_index_end       = 0;
    float ilat                  = 0;
    char  north;
    float ilon                  = 0;
    char  east;
    int   iyear                 = 0;
    float isecondWithSS         = 0;

    GPS_str_GNSSINFO.concat(getGPSrawImpl());
    // If data available :  "2,05,03,00,4546.722312,N,00452.604912,E,271021,114122.0,169.0,0.0,,1.9,1.7,0.9"
    // Or :                 "2,05,04,00,4546.721098,N,00452.595570,E,281021,101848.0,183.1,0.0,,1.6,1.3,0.9"
    // If not :             ",,,,,,,,,,,,,,," at best or ""

    if (GPS_str_GNSSINFO.length() > 20){
        for (int i = 0 ; i < 30 ; i++){
            if (i == 0){
                GPS_str_length = GPS_str_GNSSINFO.length();
                GPS_str_index_end = GPS_str_GNSSINFO.indexOf(',');
                *fixmode = (GPS_str_GNSSINFO.substring(GPS_str_index_start, GPS_str_index_end)).toInt();
            } else {
                GPS_str_index_start = GPS_str_index_end + 1;
                GPS_str_index_end = GPS_str_GNSSINFO.indexOf(',', GPS_str_index_start);
                       if (i == 1){     *gps_vs = (GPS_str_GNSSINFO.substring(GPS_str_index_start, GPS_str_index_end)).toInt();                                 // Valid GPS sats
                } else if (i == 2){     *glonass_vs = (GPS_str_GNSSINFO.substring(GPS_str_index_start, GPS_str_index_end)).toInt();                             // Valid GLONASS sats
                } else if (i == 3){     *beidou_vs = (GPS_str_GNSSINFO.substring(GPS_str_index_start, GPS_str_index_end)).toInt();                              // Valid BEIDOU sats
                } else if (i == 4){     ilat = (GPS_str_GNSSINFO.substring(GPS_str_index_start, GPS_str_index_end)).toFloat();                                  // Latitude 1/2
                } else if (i == 5){     *lat = (floor(ilat / 100) + fmod(ilat, 100.) / 60) * (GPS_str_GNSSINFO.charAt(GPS_str_index_start) == 'N' ? 1 : -1);    // Latitude 2/2
                } else if (i == 6){     ilon = (GPS_str_GNSSINFO.substring(GPS_str_index_start, GPS_str_index_end)).toFloat();                                  // Longitude 1/2
                } else if (i == 7){     *lon = (floor(ilon / 100) + fmod(ilon, 100.) / 60) * (GPS_str_GNSSINFO.charAt(GPS_str_index_start) == 'E' ? 1 : -1);    // Longitude 2/2
                } else if (i == 8){                                                                                                                             // Date
                    *day = (GPS_str_GNSSINFO.substring(GPS_str_index_start, GPS_str_index_start + 2)).toInt();
                    *month = (GPS_str_GNSSINFO.substring(GPS_str_index_start + 2, GPS_str_index_start + 4)).toInt();
                    iyear = (GPS_str_GNSSINFO.substring(GPS_str_index_start + 4, (GPS_str_index_end))).toInt();
                    if (iyear < 2000) { *year = iyear += 2000;
                    } else {            *year = iyear;
                    }
                } else if (i == 9){                                                                                                                             // Time
                    *hour = (GPS_str_GNSSINFO.substring(GPS_str_index_start, GPS_str_index_start + 2)).toInt();
                    *minute = (GPS_str_GNSSINFO.substring(GPS_str_index_start + 2, GPS_str_index_start + 4)).toInt();
                    isecondWithSS = (GPS_str_GNSSINFO.substring(GPS_str_index_start + 4, (GPS_str_index_end))).toFloat();
                    *second = static_cast<int>(isecondWithSS);
                } else if (i == 10){    *alt = (GPS_str_GNSSINFO.substring(GPS_str_index_start, GPS_str_index_end)).toFloat();                                  // Altitude
                } else if (i == 11){    *speed = (GPS_str_GNSSINFO.substring(GPS_str_index_start, GPS_str_index_end)).toFloat();                                // Speed
                } else if (i == 13){    *accuracy = (GPS_str_GNSSINFO.substring(GPS_str_index_start, GPS_str_index_end)).toFloat();                             // PDOP
                }
                if (GPS_str_index_end == -1){
                    return true;
                }
            }
        }
    }
    return false;
  }
star297 commented 2 years ago

Please see bottom of #566 You would need to to test for valid fixmode first before too much processing and avoid using 'String' But the official library version is not ideal.

NicoYaez commented 2 years ago

Hello, good, you know that I have a problem when making the gps work, it does not show me anything, I have the LilyGo SIM7600G R2 board, I think it is the same as you, how did you do to turn it on, it takes several hours and it only shows me the empty readings, greetings.

star297 commented 2 years ago

Have you started the GPS? Something like this..

if (!modem.enableGPS()) {     
    Serial.printf("GPS started\n");
}

You need to set the GPS mode too...

/*
CGNSSMODE: <gnss_mode>,<dpo_mode>
This command is used to configure GPS, GLONASS, BEIDOU and QZSS support mode.
Add to get the required combination, eg, 5 = GLONSASS + GALILEO
gnss_mode:
bit0 : GLONASS   //  1
bit1 : BEIDOU    //  2
bit2 : GALILEO   //  4
bit3 : QZSS      //  8
dpo_mode :       //  reduces power in the RF section, 1 = RF is only powered long enough to get gnss signal
 0 disable
 1 enable
*/

 String res = modem.setGNSSMode(5, 0);   
 if (res == "OK")
 {
 Serial.printf("Set GNSS Mode to: % d\n", modem.getGNSSMode());
 }