diff --git a/examples/AllFunctions/AllFunctions.ino b/examples/AllFunctions/AllFunctions.ino index 4fce7d6..d2a41af 100644 --- a/examples/AllFunctions/AllFunctions.ino +++ b/examples/AllFunctions/AllFunctions.ino @@ -318,6 +318,7 @@ void loop() { #endif #if TINY_GSM_TEST_GSM_LOCATION && defined TINY_GSM_MODEM_HAS_GSM_LOCATION + DBG("Waiting for GSM location"); String location = modem.getGsmLocation(); DBG("GSM Based Location String:", location); float lat = 0; @@ -328,7 +329,9 @@ void loop() { int day = 0; int hour = 0; int min = 0; - int sec = 0; + int sec = 0; + for (int8_t i = 5; i; i--) { + DBG("Waiting for GSM location"); if (modem.getGsmLocation(&lat, &lon, &accuracy, &year, &month, &day, &hour, &min, &sec)) { DBG("Latitude:", String(lat, 8)); @@ -341,12 +344,15 @@ void loop() { DBG("Minute:", min); DBG("Second:", sec); } else { - DBG("Couldn't get GSM location"); + DBG("Couldn't get GSM location, retrying in 10s."); + delay(10000L); + } } #endif #if TINY_GSM_TEST_GPS && defined TINY_GSM_MODEM_HAS_GPS modem.enableGPS(); + DBG("Waiting for GPS/GNSS/GLONASS location"); String gps_raw = modem.getGPSraw(); DBG("GPS/GNSS Based Location String:", gps_raw); float lat2 = 0; @@ -362,7 +368,9 @@ void loop() { int hour2 = 0; int min2 = 0; int sec2 = 0; - if (modem.getGPS(&lat2, &lon, &speed2, &alt2, &vsat2, &usat2, &accuracy2, + for (int8_t i = 5; i; i--) { + DBG("Waiting for GPS/GNSS/GLONASS location"); + if (modem.getGPS(&lat2, &lon2, &speed2, &alt2, &vsat2, &usat2, &accuracy2, &year2, &month2, &day2, &hour2, &min2, &sec2)) { DBG("Latitude:", String(lat2, 8)); DBG("Longitude:", String(lon2, 8)); @@ -377,8 +385,11 @@ void loop() { DBG("Hour:", hour2); DBG("Minute:", min2); DBG("Second:", sec2); + break; } else { - DBG("Couldn't get GPS/GNSS location"); + DBG("Couldn't get GSM location, retrying in 10s."); + delay(10000L); + } } modem.disableGPS(); #endif diff --git a/examples/HttpsClient/HttpsClient.ino b/examples/HttpsClient/HttpsClient.ino index 3f9e181..ace7da7 100644 --- a/examples/HttpsClient/HttpsClient.ino +++ b/examples/HttpsClient/HttpsClient.ino @@ -46,7 +46,9 @@ // Chips without internal buffering (A6/A7, ESP8266, M590) // need enough space in the buffer for the entire response // else data will be lost (and the http library will fail). +#if !defined(TINY_GSM_RX_BUFFER) #define TINY_GSM_RX_BUFFER 650 +#endif // See all AT commands, if wanted // #define DUMP_AT_COMMANDS diff --git a/src/TinyGsmClientSIM7000.h b/src/TinyGsmClientSIM7000.h index 161368b..ea31940 100644 --- a/src/TinyGsmClientSIM7000.h +++ b/src/TinyGsmClientSIM7000.h @@ -194,7 +194,6 @@ class TinyGsmSim7000 : public TinyGsmModem, res2.trim(); name = res2; - DBG("### Modem:", name); return name; } @@ -375,7 +374,15 @@ class TinyGsmSim7000 : public TinyGsmModem, * SIM card functions */ protected: - // Able to follow all SIM card functions as inherited from the template + // Doesn't return the "+CCID" before the number + String getSimCCIDImpl() { + sendAT(GF("+CCID")); + if (waitResponse(GF(GSM_NL)) != 1) { return ""; } + String res = stream.readStringUntil('\n'); + waitResponse(); + res.trim(); + return res; + } /* * Messaging functions @@ -403,7 +410,7 @@ class TinyGsmSim7000 : public TinyGsmModem, // get the RAW GPS output String getGPSrawImpl() { sendAT(GF("+CGNSINF")); - if (waitResponse(GF(GSM_NL "+CGNSINF:")) != 1) { return ""; } + if (waitResponse(10000L, GF(GSM_NL "+CGNSINF:")) != 1) { return ""; } String res = stream.readStringUntil('\n'); waitResponse(); res.trim(); @@ -415,84 +422,76 @@ class TinyGsmSim7000 : public TinyGsmModem, 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) { - bool fix = false; - sendAT(GF("+CGNSINF")); - if (waitResponse(GF(GSM_NL "+CGNSINF:")) != 1) { return false; } - - streamSkipUntil(','); // GNSS run status - if (streamGetInt(',') == 1) fix = true; // fix status - - // UTC date & Time - char dtSBuff[7] = {'\0'}; - stream.readBytes(dtSBuff, 4); // Four digit year - dtSBuff[4] = '\0'; // null terminate buffer - if (year != NULL) *year = atoi(dtSBuff); // Convert to int - - stream.readBytes(dtSBuff, 2); // Two digit month - dtSBuff[2] = '\0'; - if (month != NULL) *month = atoi(dtSBuff); - - stream.readBytes(dtSBuff, 2); // Two digit day - dtSBuff[2] = '\0'; - if (day != NULL) *day = atoi(dtSBuff); - - stream.readBytes(dtSBuff, 2); // Two digit hour - dtSBuff[2] = '\0'; - if (hour != NULL) *hour = atoi(dtSBuff); - - stream.readBytes(dtSBuff, 2); // Two digit minute - dtSBuff[2] = '\0'; - if (minute != NULL) *minute = atoi(dtSBuff); - - stream.readBytes(dtSBuff, 6); // 6 digit second with subseconds - dtSBuff[6] = '\0'; - if (second != NULL) *second = atoi(dtSBuff); - // *secondWithSS = atof(dtSBuff); - streamSkipUntil(','); // Throw away the final comma - - *lat = streamGetFloat(','); // Latitude - *lon = streamGetFloat(','); // Longitude - if (alt != NULL) { // MSL Altitude. Unit is meters - *alt = streamGetFloat(','); - } else { - streamSkipUntil(','); - } - if (speed != NULL) { // Speed Over Ground. Unit is knots. - *speed = streamGetFloat(','); - } else { - streamSkipUntil(','); - } - streamSkipUntil(','); // Course Over Ground. Degrees. - streamSkipUntil(','); // Fix Mode - streamSkipUntil(','); // Reserved1 - streamSkipUntil(','); // Horizontal Dilution Of Precision - if (accuracy != NULL) { // Position Dilution Of Precision - *accuracy = streamGetFloat(','); - } else { - streamSkipUntil(','); - } - streamSkipUntil(','); // Vertical Dilution Of Precision - streamSkipUntil(','); // Reserved2 - if (vsat != NULL) { // GNSS Satellites in View - *vsat = streamGetInt(','); - } else { - streamSkipUntil(','); - } - if (usat != NULL) { // GNSS Satellites Used - *usat = streamGetInt(','); - } else { - streamSkipUntil(','); + if (waitResponse(10000L, GF(GSM_NL "+CGNSINF:")) != 1) { return false; } + + streamSkipUntil(','); // GNSS run status + if (streamGetInt(',') == 1) { // fix status + // init variables + float ilat = 0; + float ilon = 0; + float ispeed = 0; + int ialt = 0; + int ivsat = 0; + int iusat = 0; + float iaccuracy = 0; + int iyear = 0; + int imonth = 0; + int iday = 0; + int ihour = 0; + int imin = 0; + float secondWithSS = 0; + + // UTC date & Time + iyear = streamGetInt(static_cast(4)); // Four digit year + imonth = streamGetInt(static_cast(2)); // Two digit month + iday = streamGetInt(static_cast(2)); // Two digit day + ihour = streamGetInt(static_cast(2)); // Two digit hour + imin = streamGetInt(static_cast(2)); // Two digit minute + secondWithSS = streamGetFloat(','); // 6 digit second with subseconds + + ilat = streamGetFloat(','); // Latitude + ilon = streamGetFloat(','); // Longitude + ialt = streamGetFloat(','); // MSL Altitude. Unit is meters + ispeed = streamGetFloat(','); // Speed Over Ground. Unit is knots. + streamSkipUntil(','); // Course Over Ground. Degrees. + streamSkipUntil(','); // Fix Mode + streamSkipUntil(','); // Reserved1 + streamSkipUntil(','); // Horizontal Dilution Of Precision + iaccuracy = streamGetFloat(','); // Position Dilution Of Precision + streamSkipUntil(','); // Vertical Dilution Of Precision + streamSkipUntil(','); // Reserved2 + ivsat = streamGetInt(','); // GNSS Satellites in View + iusat = streamGetInt(','); // GNSS Satellites Used + streamSkipUntil(','); // GLONASS Satellites Used + streamSkipUntil(','); // Reserved3 + streamSkipUntil(','); // C/N0 max + streamSkipUntil(','); // HPA + streamSkipUntil('\n'); // VPA + + // Set pointers + if (lat != NULL) *lat = ilat; + if (lon != NULL) *lon = ilon; + if (speed != NULL) *speed = ispeed; + if (alt != NULL) *alt = ialt; + if (vsat != NULL) *vsat = ivsat; + if (usat != NULL) *usat = iusat; + if (accuracy != NULL) *accuracy = iaccuracy; + if (iyear < 2000) iyear += 2000; + if (year != NULL) *year = iyear; + if (month != NULL) *month = imonth; + if (day != NULL) *day = iday; + if (hour != NULL) *hour = ihour; + if (minute != NULL) *minute = imin; + if (second != NULL) *second = static_cast(secondWithSS); + + waitResponse(); + return true; } - streamSkipUntil(','); // GLONASS Satellites Used - streamSkipUntil(','); // Reserved3 - streamSkipUntil(','); // C/N0 max - streamSkipUntil(','); // HPA - streamSkipUntil('\n'); // VPA + streamSkipUntil('\n'); // toss the row of commas waitResponse(); - - return fix; + return false; } /* diff --git a/src/TinyGsmClientSIM7600.h b/src/TinyGsmClientSIM7600.h index 5de82ff..a34b2ce 100644 --- a/src/TinyGsmClientSIM7600.h +++ b/src/TinyGsmClientSIM7600.h @@ -314,10 +314,10 @@ class TinyGsmSim7600 : public TinyGsmModem, // = 10 (default) // DelayTm = number of milliseconds to delay before outputting received data // = 0 (default) - // Ack = sets whether reporting a string “Send ok” = 0 (don't report) + // Ack = sets whether reporting a string "Send ok" = 0 (don't report) // errMode = mode of reporting error result code = 0 (numberic values) // HeaderType = which data header of receiving data in multi-client mode - // = 1 (“+RECEIVE,,”) + // = 1 (+RECEIVE,,) // AsyncMode = sets mode of executing commands // = 0 (synchronous command executing) // TimeoutVal = minimum retransmission timeout in milliseconds = 75000 @@ -439,69 +439,69 @@ class TinyGsmSim7600 : public TinyGsmModem, uint8_t fixMode = streamGetInt(','); // mode 2=2D Fix or 3=3DFix // TODO(?) Can 1 be returned if (fixMode == 1 || fixMode == 2 || fixMode == 3) { + // init variables + float ilat = 0; + float ilon = 0; + float ispeed = 0; + int ialt = 0; + int ivsat = 0; + int iusat = 0; + float iaccuracy = 0; + int iyear = 0; + int imonth = 0; + int iday = 0; + int ihour = 0; + int imin = 0; + float secondWithSS = 0; + streamSkipUntil(','); // GPS satellite valid numbers streamSkipUntil(','); // GLONASS satellite valid numbers streamSkipUntil(','); // BEIDOU satellite valid numbers - *lat = streamGetFloat(','); // Latitude + ilat = streamGetFloat(','); // Latitude streamSkipUntil(','); // N/S Indicator, N=north or S=south - *lon = streamGetFloat(','); // Longitude + ilon = streamGetFloat(','); // Longitude streamSkipUntil(','); // E/W Indicator, E=east or W=west // Date. Output format is ddmmyy - char dtSBuff[7] = {'\0'}; - stream.readBytes(dtSBuff, 2); // Two digit day - dtSBuff[2] = '\0'; // null terminate buffer - if (day != NULL) *day = atoi(dtSBuff); // Convert to int - - stream.readBytes(dtSBuff, 2); // Two digit month - dtSBuff[2] = '\0'; - if (month != NULL) *month = atoi(dtSBuff); - - stream.readBytes(dtSBuff, 2); // Two digit year - dtSBuff[2] = '\0'; - if (year != NULL) *year = atoi(dtSBuff); - streamSkipUntil(','); // Throw away the final comma + iday = streamGetInt(static_cast(2)); // Two digit day + imonth = streamGetInt(static_cast(2)); // Two digit month + iyear = streamGetInt(','); // Two digit year // UTC Time. Output format is hhmmss.s - stream.readBytes(dtSBuff, 2); // Two digit hour - dtSBuff[2] = '\0'; - if (hour != NULL) *hour = atoi(dtSBuff); - - stream.readBytes(dtSBuff, 2); // Two digit minute - dtSBuff[2] = '\0'; - if (minute != NULL) *minute = atoi(dtSBuff); - - stream.readBytes(dtSBuff, 6); // 6 digit second with subseconds - dtSBuff[6] = '\0'; - if (second != NULL) *second = atoi(dtSBuff); - // *secondWithSS = atof(dtSBuff); - streamSkipUntil(','); // Throw away the final comma - - if (alt != NULL) { // MSL Altitude. Unit is meters - *alt = streamGetFloat(','); - } else { - streamSkipUntil(','); - } - if (speed != NULL) { // Speed Over Ground. Unit is knots. - *speed = streamGetFloat(','); - } else { - streamSkipUntil(','); - } - streamSkipUntil(','); // Course Over Ground. Degrees. - streamSkipUntil(','); // After set, will report GPS every x seconds - if (accuracy != NULL) { // Position Dilution Of Precision - *accuracy = streamGetFloat(','); - } else { - streamSkipUntil(','); - } - streamSkipUntil(','); // Horizontal Dilution Of Precision - streamSkipUntil(','); // Vertical Dilution Of Precision - streamSkipUntil('\n'); // TODO(?) is one more field reported?? + ihour = streamGetInt(static_cast(2)); // Two digit hour + imin = streamGetInt(static_cast(2)); // Two digit minute + secondWithSS = streamGetFloat(','); // 4 digit second with subseconds + + ialt = streamGetFloat(','); // MSL Altitude. Unit is meters + ispeed = streamGetFloat(','); // Speed Over Ground. Unit is knots. + streamSkipUntil(','); // Course Over Ground. Degrees. + streamSkipUntil(','); // After set, will report GPS every x seconds + iaccuracy = streamGetFloat(','); // Position Dilution Of Precision + streamSkipUntil(','); // Horizontal Dilution Of Precision + streamSkipUntil(','); // Vertical Dilution Of Precision + streamSkipUntil('\n'); // TODO(?) is one more field reported?? + + // Set pointers + if (lat != NULL) *lat = ilat; + if (lon != NULL) *lon = ilon; + if (speed != NULL) *speed = ispeed; + if (alt != NULL) *alt = ialt; + if (vsat != NULL) *vsat = ivsat; + if (usat != NULL) *usat = iusat; + if (accuracy != NULL) *accuracy = iaccuracy; + if (iyear < 2000) iyear += 2000; + if (year != NULL) *year = iyear; + if (month != NULL) *month = imonth; + if (day != NULL) *day = iday; + if (hour != NULL) *hour = ihour; + if (minute != NULL) *minute = imin; + if (second != NULL) *second = static_cast(secondWithSS); waitResponse(); - return true; } + + waitResponse(); return false; } diff --git a/src/TinyGsmClientSIM808.h b/src/TinyGsmClientSIM808.h index 1bd74b5..e228836 100644 --- a/src/TinyGsmClientSIM808.h +++ b/src/TinyGsmClientSIM808.h @@ -41,7 +41,7 @@ class TinyGsmSim808 : public TinyGsmSim800, public TinyGsmGPS { // works only with ans SIM808 V2 String getGPSrawImpl() { sendAT(GF("+CGNSINF")); - if (waitResponse(GF(GSM_NL "+CGNSINF:")) != 1) { return ""; } + if (waitResponse(10000L, GF(GSM_NL "+CGNSINF:")) != 1) { return ""; } String res = stream.readStringUntil('\n'); waitResponse(); res.trim(); @@ -54,84 +54,76 @@ class TinyGsmSim808 : public TinyGsmSim800, public TinyGsmGPS { 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) { - bool fix = false; - sendAT(GF("+CGNSINF")); - if (waitResponse(GF(GSM_NL "+CGNSINF:")) != 1) { return false; } - - streamSkipUntil(','); // GNSS run status - if (streamGetInt(',') == 1) fix = true; // fix status - - // UTC date & Time - char dtSBuff[7] = {'\0'}; - stream.readBytes(dtSBuff, 4); // Four digit year - dtSBuff[4] = '\0'; // null terminate buffer - if (year != NULL) *year = atoi(dtSBuff); // Convert to int - - stream.readBytes(dtSBuff, 2); // Two digit month - dtSBuff[2] = '\0'; - if (month != NULL) *month = atoi(dtSBuff); - - stream.readBytes(dtSBuff, 2); // Two digit day - dtSBuff[2] = '\0'; - if (day != NULL) *day = atoi(dtSBuff); - - stream.readBytes(dtSBuff, 2); // Two digit hour - dtSBuff[2] = '\0'; - if (hour != NULL) *hour = atoi(dtSBuff); - - stream.readBytes(dtSBuff, 2); // Two digit minute - dtSBuff[2] = '\0'; - if (minute != NULL) *minute = atoi(dtSBuff); - - stream.readBytes(dtSBuff, 6); // 6 digit second with subseconds - dtSBuff[6] = '\0'; - if (second != NULL) *second = atoi(dtSBuff); - // *secondWithSS = atof(dtSBuff); - streamSkipUntil(','); // Throw away the final comma - - *lat = streamGetFloat(','); // Latitude - *lon = streamGetFloat(','); // Longitude - if (alt != NULL) { // MSL Altitude. Unit is meters - *alt = streamGetFloat(','); - } else { - streamSkipUntil(','); - } - if (speed != NULL) { // Speed Over Ground. Unit is knots. - *speed = streamGetFloat(','); - } else { - streamSkipUntil(','); - } - streamSkipUntil(','); // Course Over Ground. Degrees. - streamSkipUntil(','); // Fix Mode - streamSkipUntil(','); // Reserved1 - streamSkipUntil(','); // Horizontal Dilution Of Precision - if (accuracy != NULL) { // Position Dilution Of Precision - *accuracy = streamGetFloat(','); - } else { - streamSkipUntil(','); + if (waitResponse(10000L, GF(GSM_NL "+CGNSINF:")) != 1) { return false; } + + streamSkipUntil(','); // GNSS run status + if (streamGetInt(',') == 1) { // fix status + // init variables + float ilat = 0; + float ilon = 0; + float ispeed = 0; + int ialt = 0; + int ivsat = 0; + int iusat = 0; + float iaccuracy = 0; + int iyear = 0; + int imonth = 0; + int iday = 0; + int ihour = 0; + int imin = 0; + float secondWithSS = 0; + + // UTC date & Time + iyear = streamGetInt(static_cast(4)); // Four digit year + imonth = streamGetInt(static_cast(2)); // Two digit month + iday = streamGetInt(static_cast(2)); // Two digit day + ihour = streamGetInt(static_cast(2)); // Two digit hour + imin = streamGetInt(static_cast(2)); // Two digit minute + secondWithSS = streamGetFloat(','); // 6 digit second with subseconds + + ilat = streamGetFloat(','); // Latitude + ilon = streamGetFloat(','); // Longitude + ialt = streamGetFloat(','); // MSL Altitude. Unit is meters + ispeed = streamGetFloat(','); // Speed Over Ground. Unit is knots. + streamSkipUntil(','); // Course Over Ground. Degrees. + streamSkipUntil(','); // Fix Mode + streamSkipUntil(','); // Reserved1 + streamSkipUntil(','); // Horizontal Dilution Of Precision + iaccuracy = streamGetFloat(','); // Position Dilution Of Precision + streamSkipUntil(','); // Vertical Dilution Of Precision + streamSkipUntil(','); // Reserved2 + ivsat = streamGetInt(','); // GNSS Satellites in View + iusat = streamGetInt(','); // GNSS Satellites Used + streamSkipUntil(','); // GLONASS Satellites Used + streamSkipUntil(','); // Reserved3 + streamSkipUntil(','); // C/N0 max + streamSkipUntil(','); // HPA + streamSkipUntil('\n'); // VPA + + // Set pointers + if (lat != NULL) *lat = ilat; + if (lon != NULL) *lon = ilon; + if (speed != NULL) *speed = ispeed; + if (alt != NULL) *alt = ialt; + if (vsat != NULL) *vsat = ivsat; + if (usat != NULL) *usat = iusat; + if (accuracy != NULL) *accuracy = iaccuracy; + if (iyear < 2000) iyear += 2000; + if (year != NULL) *year = iyear; + if (month != NULL) *month = imonth; + if (day != NULL) *day = iday; + if (hour != NULL) *hour = ihour; + if (minute != NULL) *minute = imin; + if (second != NULL) *second = static_cast(secondWithSS); + + waitResponse(); + return true; } - streamSkipUntil(','); // Vertical Dilution Of Precision - streamSkipUntil(','); // Reserved2 - if (vsat != NULL) { // GNSS Satellites in View - *vsat = streamGetInt(','); - } else { - streamSkipUntil(','); - } - if (usat != NULL) { // GNSS Satellites Used - *usat = streamGetInt(','); - } else { - streamSkipUntil(','); - } - streamSkipUntil(','); // GLONASS Satellites Used - streamSkipUntil(','); // Reserved3 - streamSkipUntil(','); // C/N0 max - streamSkipUntil(','); // HPA - streamSkipUntil('\n'); // VPA + streamSkipUntil('\n'); // toss the row of commas waitResponse(); - - return fix; + return false; } }; diff --git a/src/TinyGsmClientSaraR4.h b/src/TinyGsmClientSaraR4.h index ae86c90..cef7bcf 100644 --- a/src/TinyGsmClientSaraR4.h +++ b/src/TinyGsmClientSaraR4.h @@ -445,14 +445,14 @@ class TinyGsmSaraR4 if (waitResponse(10000L, GF(GSM_NL "+UGPS:")) != 1) { return false; } return waitResponse(10000L) == 1; } - String getUbloxLocationRaw(int8_t sensor) { + String inline getUbloxLocationRaw(int8_t sensor) { // AT+ULOC=,,,, // - 2: single shot position // - 0: use the last fix in the internal database and stop the GNSS // receiver // - 1: use the GNSS receiver for localization - // - 2: use cellular CellLocate® location information - // - 3: ?? use the combined GNSS receiver and CellLocate® service + // - 2: use cellular CellLocate location information + // - 3: ?? use the combined GNSS receiver and CellLocate service // information ?? - Docs show using sensor 3 and it's // documented for the +UTIME command but not for +ULOC // - 0: standard (single-hypothesis) response @@ -475,18 +475,18 @@ class TinyGsmSaraR4 return getUbloxLocationRaw(1); } - bool getUbloxLocation(int8_t sensor, float* lat, float* lon, float* speed = 0, + bool inline getUbloxLocation(int8_t sensor, float* lat, float* lon, float* speed = 0, int* 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) { // AT+ULOC=,,,, // - 2: single shot position - // - 2: use cellular CellLocate® location information + // - 2: use cellular CellLocate location information // - 0: use the last fix in the internal database and stop the GNSS // receiver // - 1: use the GNSS receiver for localization - // - 3: ?? use the combined GNSS receiver and CellLocate® service + // - 3: ?? use the combined GNSS receiver and CellLocate service // information ?? - Docs show using sensor 3 and it's documented // for the +UTIME command but not for +ULOC // - 0: standard (single-hypothesis) response @@ -502,74 +502,60 @@ class TinyGsmSaraR4 // , , , , , // + // init variables + float ilat = 0; + float ilon = 0; + float ispeed = 0; + int ialt = 0; + int iusat = 0; + float iaccuracy = 0; + int iyear = 0; + int imonth = 0; + int iday = 0; + int ihour = 0; + int imin = 0; + float secondWithSS = 0; + // Date & Time - char dtSBuff[7] = {'\0'}; - - stream.readBytes(dtSBuff, 2); // Two digit day - dtSBuff[2] = '\0'; // null terminate buffer - if (day != NULL) *day = atoi(dtSBuff); // Convert to int - streamSkipUntil('/'); // Throw out slash - - stream.readBytes(dtSBuff, 2); // Two digit month - dtSBuff[2] = '\0'; - if (month != NULL) *month = atoi(dtSBuff); - streamSkipUntil('/'); // Throw out slash - - stream.readBytes(dtSBuff, 4); // Four digit year - dtSBuff[4] = '\0'; - if (year != NULL) *year = atoi(dtSBuff); - streamSkipUntil(','); // Throw out comma - - stream.readBytes(dtSBuff, 2); // Two digit hour - dtSBuff[2] = '\0'; - if (hour != NULL) *hour = atoi(dtSBuff); - streamSkipUntil(':'); // Throw out colon - - stream.readBytes(dtSBuff, 2); // Two digit minute - dtSBuff[2] = '\0'; - if (minute != NULL) *minute = atoi(dtSBuff); - streamSkipUntil(':'); // Throw out colon - - stream.readBytes(dtSBuff, 6); // 6 digit second with subseconds - dtSBuff[6] = '\0'; - if (second != NULL) *second = atoi(dtSBuff); - // *secondWithSS = atof(dtSBuff); - streamSkipUntil(','); // Throw away the final comma - - *lat = streamGetFloat(','); // Estimated latitude, in degrees - *lon = streamGetFloat(','); // Estimated longitude, in degrees - - if (alt != NULL) { // Estimated altitude, in meters - only for GNSS - // positioning, 0 in case of CellLocate - *alt = streamGetFloat(','); - } else { - streamSkipUntil(','); - } - if (accuracy != NULL) { // Maximum possible error, in meters (0 - 20000000) - *accuracy = streamGetFloat(','); - } else { - streamSkipUntil(','); - } - if (speed != NULL) { // Speed over ground m/s3 - *speed = streamGetFloat(','); - } else { - streamSkipUntil(','); - } + iday = streamGetInt('/'); // Two digit day + imonth = streamGetInt('/'); // Two digit month + iyear = streamGetInt(','); // Four digit year + ihour = streamGetInt(':'); // Two digit hour + imin = streamGetInt(':'); // Two digit minute + secondWithSS = streamGetFloat(','); // 6 digit second with subseconds + + ilat = streamGetFloat(','); // Estimated latitude, in degrees + ilon = streamGetFloat(','); // Estimated longitude, in degrees + ialt = streamGetFloat(','); // Estimated altitude, in meters - only for + iaccuracy = streamGetFloat( + ','); // Maximum possible error, in meters (0 - 20000000) + ispeed = streamGetFloat(','); // Speed over ground m/s3 streamSkipUntil(','); // Course over ground in degree (0 deg - 360 deg) streamSkipUntil(','); // Vertical accuracy, in meters streamSkipUntil(','); // Sensor used for the position calculation - if (vsat != NULL) vsat = 0; // Number of satellites viewed not reported - if (usat != NULL) { // Number of satellite used to calculate the position - *usat = streamGetInt(','); - } else { - streamSkipUntil(','); - } - streamSkipUntil(','); // Antenna status + iusat = streamGetInt( + ','); // Number of satellite used to calculate the position + streamSkipUntil(','); // Antenna status streamSkipUntil('\n'); // Jamming status + // Set pointers + if (lat != NULL) *lat = ilat; + if (lon != NULL) *lon = ilon; + if (speed != NULL) *speed = ispeed; + if (alt != NULL) *alt = ialt; + if (vsat != NULL) *vsat = 0; // Number of satellites viewed not reported; + if (usat != NULL) *usat = iusat; + if (accuracy != NULL) *accuracy = iaccuracy; + if (iyear < 2000) iyear += 2000; + if (year != NULL) *year = iyear; + if (month != NULL) *month = imonth; + if (day != NULL) *day = iday; + if (hour != NULL) *hour = ihour; + if (minute != NULL) *minute = imin; + if (second != NULL) *second = static_cast(secondWithSS); + // final ok waitResponse(); - return true; } bool getGsmLocationImpl(float* lat, float* lon, float* accuracy = 0, @@ -577,7 +563,7 @@ class TinyGsmSaraR4 int* hour = 0, int* minute = 0, int* second = 0) { return getUbloxLocation(2, lat, lon, 0, 0, 0, 0, accuracy, year, month, day, hour, minute, second); - }; + } bool getGPSImpl(float* lat, float* lon, float* speed = 0, int* alt = 0, int* vsat = 0, int* usat = 0, float* accuracy = 0, int* year = 0, int* month = 0, int* day = 0, int* hour = 0, diff --git a/src/TinyGsmClientUBLOX.h b/src/TinyGsmClientUBLOX.h index 203d554..669ed43 100644 --- a/src/TinyGsmClientUBLOX.h +++ b/src/TinyGsmClientUBLOX.h @@ -412,14 +412,14 @@ class TinyGsmUBLOX if (waitResponse(10000L, GF(GSM_NL "+UGPS:")) != 1) { return false; } return waitResponse(10000L) == 1; } - String getUbloxLocationRaw(int8_t sensor) { + String inline getUbloxLocationRaw(int8_t sensor) { // AT+ULOC=,,,, // - 2: single shot position // - 0: use the last fix in the internal database and stop the GNSS // receiver // - 1: use the GNSS receiver for localization - // - 2: use cellular CellLocate® location information - // - 3: ?? use the combined GNSS receiver and CellLocate® service + // - 2: use cellular CellLocate location information + // - 3: ?? use the combined GNSS receiver and CellLocate service // information ?? - Docs show using sensor 3 and it's // documented for the +UTIME command but not for +ULOC // - 0: standard (single-hypothesis) response @@ -442,18 +442,18 @@ class TinyGsmUBLOX return getUbloxLocationRaw(1); } - bool getUbloxLocation(int8_t sensor, float* lat, float* lon, float* speed = 0, + bool inline getUbloxLocation(int8_t sensor, float* lat, float* lon, float* speed = 0, int* 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) { // AT+ULOC=,,,, // - 2: single shot position - // - 2: use cellular CellLocate® location information + // - 2: use cellular CellLocate location information // - 0: use the last fix in the internal database and stop the GNSS // receiver // - 1: use the GNSS receiver for localization - // - 3: ?? use the combined GNSS receiver and CellLocate® service + // - 3: ?? use the combined GNSS receiver and CellLocate service // information ?? - Docs show using sensor 3 and it's documented // for the +UTIME command but not for +ULOC // - 0: standard (single-hypothesis) response @@ -469,74 +469,60 @@ class TinyGsmUBLOX // , , , , , // + // init variables + float ilat = 0; + float ilon = 0; + float ispeed = 0; + int ialt = 0; + int iusat = 0; + float iaccuracy = 0; + int iyear = 0; + int imonth = 0; + int iday = 0; + int ihour = 0; + int imin = 0; + float secondWithSS = 0; + // Date & Time - char dtSBuff[7] = {'\0'}; - - stream.readBytes(dtSBuff, 2); // Two digit day - dtSBuff[2] = '\0'; // null terminate buffer - if (day != NULL) *day = atoi(dtSBuff); // Convert to int - streamSkipUntil('/'); // Throw out slash - - stream.readBytes(dtSBuff, 2); // Two digit month - dtSBuff[2] = '\0'; - if (month != NULL) *month = atoi(dtSBuff); - streamSkipUntil('/'); // Throw out slash - - stream.readBytes(dtSBuff, 4); // Four digit year - dtSBuff[4] = '\0'; - if (year != NULL) *year = atoi(dtSBuff); - streamSkipUntil(','); // Throw out comma - - stream.readBytes(dtSBuff, 2); // Two digit hour - dtSBuff[2] = '\0'; - if (hour != NULL) *hour = atoi(dtSBuff); - streamSkipUntil(':'); // Throw out colon - - stream.readBytes(dtSBuff, 2); // Two digit minute - dtSBuff[2] = '\0'; - if (minute != NULL) *minute = atoi(dtSBuff); - streamSkipUntil(':'); // Throw out colon - - stream.readBytes(dtSBuff, 6); // 6 digit second with subseconds - dtSBuff[6] = '\0'; - if (second != NULL) *second = atoi(dtSBuff); - // *secondWithSS = atof(dtSBuff); - streamSkipUntil(','); // Throw away the final comma - - *lat = streamGetFloat(','); // Estimated latitude, in degrees - *lon = streamGetFloat(','); // Estimated longitude, in degrees - - if (alt != NULL) { // Estimated altitude, in meters - only for GNSS - // positioning, 0 in case of CellLocate - *alt = streamGetFloat(','); - } else { - streamSkipUntil(','); - } - if (accuracy != NULL) { // Maximum possible error, in meters (0 - 20000000) - *accuracy = streamGetFloat(','); - } else { - streamSkipUntil(','); - } - if (speed != NULL) { // Speed over ground m/s3 - *speed = streamGetFloat(','); - } else { - streamSkipUntil(','); - } + iday = streamGetInt('/'); // Two digit day + imonth = streamGetInt('/'); // Two digit month + iyear = streamGetInt(','); // Four digit year + ihour = streamGetInt(':'); // Two digit hour + imin = streamGetInt(':'); // Two digit minute + secondWithSS = streamGetFloat(','); // 6 digit second with subseconds + + ilat = streamGetFloat(','); // Estimated latitude, in degrees + ilon = streamGetFloat(','); // Estimated longitude, in degrees + ialt = streamGetFloat(','); // Estimated altitude, in meters - only for + iaccuracy = streamGetFloat( + ','); // Maximum possible error, in meters (0 - 20000000) + ispeed = streamGetFloat(','); // Speed over ground m/s3 streamSkipUntil(','); // Course over ground in degree (0 deg - 360 deg) streamSkipUntil(','); // Vertical accuracy, in meters streamSkipUntil(','); // Sensor used for the position calculation - if (vsat != NULL) *vsat = 0; // Number of satellites viewed not reported - if (usat != NULL) { // Number of satellite used to calculate the position - *usat = streamGetInt(','); - } else { - streamSkipUntil(','); - } - streamSkipUntil(','); // Antenna status + iusat = streamGetInt( + ','); // Number of satellite used to calculate the position + streamSkipUntil(','); // Antenna status streamSkipUntil('\n'); // Jamming status + // Set pointers + if (lat != NULL) *lat = ilat; + if (lon != NULL) *lon = ilon; + if (speed != NULL) *speed = ispeed; + if (alt != NULL) *alt = ialt; + if (vsat != NULL) *vsat = 0; // Number of satellites viewed not reported; + if (usat != NULL) *usat = iusat; + if (accuracy != NULL) *accuracy = iaccuracy; + if (iyear < 2000) iyear += 2000; + if (year != NULL) *year = iyear; + if (month != NULL) *month = imonth; + if (day != NULL) *day = iday; + if (hour != NULL) *hour = ihour; + if (minute != NULL) *minute = imin; + if (second != NULL) *second = static_cast(secondWithSS); + // final ok waitResponse(); - return true; } bool getGsmLocationImpl(float* lat, float* lon, float* accuracy = 0, @@ -544,7 +530,7 @@ class TinyGsmUBLOX int* hour = 0, int* minute = 0, int* second = 0) { return getUbloxLocation(2, lat, lon, 0, 0, 0, 0, accuracy, year, month, day, hour, minute, second); - }; + } bool getGPSImpl(float* lat, float* lon, float* speed = 0, int* alt = 0, int* vsat = 0, int* usat = 0, float* accuracy = 0, int* year = 0, int* month = 0, int* day = 0, int* hour = 0, diff --git a/src/TinyGsmGSMLocation.tpp b/src/TinyGsmGSMLocation.tpp index 3518712..55203f4 100644 --- a/src/TinyGsmGSMLocation.tpp +++ b/src/TinyGsmGSMLocation.tpp @@ -93,45 +93,41 @@ class TinyGsmGSMLocation { if (thisModem().waitResponse(120000L, GF("+CLBS:0,")) != 1) { return false; } - *lat = thisModem().streamGetFloat(','); // Latitude - *lon = thisModem().streamGetFloat(','); // Longitude - if (accuracy != NULL) { // Positioning accuracy - *accuracy = thisModem().streamGetInt(','); - } else { - thisModem().streamSkipUntil(','); - } + + // init variables + float ilat = 0; + float ilon = 0; + float iaccuracy = 0; + int iyear = 0; + int imonth = 0; + int iday = 0; + int ihour = 0; + int imin = 0; + int isec = 0; + + ilat = thisModem().streamGetFloat(','); // Latitude + ilon = thisModem().streamGetFloat(','); // Longitude + iaccuracy = thisModem().streamGetInt(','); // Positioning accuracy // Date & Time - char dtSBuff[5] = {'\0'}; - thisModem().stream.readBytes(dtSBuff, 4); // Four digit year - dtSBuff[4] = '\0'; // null terminate buffer - if (year != NULL) *year = atoi(dtSBuff); // Convert to int - thisModem().streamSkipUntil('/'); // Throw out slash - - thisModem().stream.readBytes(dtSBuff, 2); // Two digit month - dtSBuff[2] = '\0'; - if (month != NULL) *month = atoi(dtSBuff); - thisModem().streamSkipUntil('/'); // Throw out slash - - thisModem().stream.readBytes(dtSBuff, 2); // Two digit day - dtSBuff[2] = '\0'; - if (day != NULL) *day = atoi(dtSBuff); - thisModem().streamSkipUntil(','); // Throw out comma - - thisModem().stream.readBytes(dtSBuff, 2); // Two digit hour - dtSBuff[2] = '\0'; - if (hour != NULL) *hour = atoi(dtSBuff); - thisModem().streamSkipUntil(':'); // Throw out colon - - thisModem().stream.readBytes(dtSBuff, 2); // Two digit minute - dtSBuff[2] = '\0'; - if (minute != NULL) *minute = atoi(dtSBuff); - thisModem().streamSkipUntil(':'); // Throw out colon - - thisModem().stream.readBytes(dtSBuff, 2); // Two digit second - dtSBuff[2] = '\0'; - if (second != NULL) *second = atoi(dtSBuff); - thisModem().streamSkipUntil('\n'); // Should be at the end of the line + iyear = thisModem().streamGetInt('/'); + imonth = thisModem().streamGetInt('/'); + iday = thisModem().streamGetInt(','); + ihour = thisModem().streamGetInt(':'); + imin = thisModem().streamGetInt(':'); + isec = thisModem().streamGetInt('\n'); + + // Set pointers + if (lat != NULL) *lat = ilat; + if (lon != NULL) *lon = ilon; + if (accuracy != NULL) *accuracy = iaccuracy; + if (iyear < 2000) iyear += 2000; + if (year != NULL) *year = iyear; + if (month != NULL) *month = imonth; + if (day != NULL) *day = iday; + if (hour != NULL) *hour = ihour; + if (minute != NULL) *minute = imin; + if (second != NULL) *second = isec; // Final OK thisModem().waitResponse(); diff --git a/src/TinyGsmModem.tpp b/src/TinyGsmModem.tpp index 33c252e..9823763 100644 --- a/src/TinyGsmModem.tpp +++ b/src/TinyGsmModem.tpp @@ -255,7 +255,21 @@ class TinyGsmModem { thisModem().streamWrite(tail...); } - int16_t inline streamGetInt(char lastChar) { + int16_t inline streamGetInt(int8_t numChars) { + char buf[6]; + size_t bytesRead = thisModem().stream.readBytes(buf, numChars); + if (bytesRead) { + buf[numChars] = '\0'; + int16_t res = atoi(buf); + return res; + } else { + return -9999; + } + } + + template + // calling with template only to prevent promotion of char to int + int16_t inline streamGetInt(T lastChar) { char buf[6]; size_t bytesRead = thisModem().stream.readBytesUntil( lastChar, buf, static_cast(6)); @@ -267,7 +281,21 @@ class TinyGsmModem { } } - float inline streamGetFloat(char lastChar) { + float inline streamGetFloat(int8_t numChars) { + char buf[12]; + size_t bytesRead = thisModem().stream.readBytes(buf, numChars); + if (bytesRead) { + buf[numChars] = '\0'; + int16_t res = atof(buf); + return res; + } else { + return static_cast(-9999); + } + } + + template + // calling with template only to prevent promotion of char to int + float inline streamGetFloat(T lastChar) { char buf[12]; size_t bytesRead = thisModem().stream.readBytesUntil( lastChar, buf, static_cast(12));