mirror of
				https://github.com/KevinMidboe/TinyGSM.git
				synced 2025-10-29 18:00:18 +00:00 
			
		
		
		
	Add accuracy to GPS output, implent it for ublox
Signed-off-by: Sara Damiano <sdamiano@stroudcenter.org>
This commit is contained in:
		| @@ -401,9 +401,9 @@ void loop() { | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #if TINY_GSM_TEST_BATTERY && defined TINY_GSM_MODEM_HAS_BATTERY | #if TINY_GSM_TEST_BATTERY && defined TINY_GSM_MODEM_HAS_BATTERY | ||||||
|   uint8_t chargeState = -99; |   uint8_t  chargeState = -99; | ||||||
|   int8_t percent = -99; |   int8_t   percent     = -99; | ||||||
|   uint16_t milliVolts = -9999; |   uint16_t milliVolts  = -9999; | ||||||
|   modem.getBattStats(chargeState, percent, milliVolts); |   modem.getBattStats(chargeState, percent, milliVolts); | ||||||
|   DBG("Battery charge state:", chargeState); |   DBG("Battery charge state:", chargeState); | ||||||
|   DBG("Battery charge 'percent':", percent); |   DBG("Battery charge 'percent':", percent); | ||||||
|   | |||||||
| @@ -405,7 +405,7 @@ class TinyGsmSim5360 : public TinyGsmModem<TinyGsmSim5360>, | |||||||
|   // Follows all messaging functions per template |   // Follows all messaging functions per template | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * Location functions |    * GSM Location functions | ||||||
|    */ |    */ | ||||||
|  protected: |  protected: | ||||||
|   // SIM5360 and SIM7100 can return a GSM-based location from CLBS as per the |   // SIM5360 and SIM7100 can return a GSM-based location from CLBS as per the | ||||||
|   | |||||||
| @@ -384,7 +384,7 @@ class TinyGsmSim7000 : public TinyGsmModem<TinyGsmSim7000>, | |||||||
|   // Follows all messaging functions per template |   // Follows all messaging functions per template | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * GPS location functions |    * GPS/GNSS/GLONASS location functions | ||||||
|    */ |    */ | ||||||
|  protected: |  protected: | ||||||
|   // enable GPS |   // enable GPS | ||||||
| @@ -412,9 +412,9 @@ class TinyGsmSim7000 : public TinyGsmModem<TinyGsmSim7000>, | |||||||
|  |  | ||||||
|   // get GPS informations |   // get GPS informations | ||||||
|   bool getGPSImpl(float* lat, float* lon, float* speed = 0, int* alt = 0, |   bool getGPSImpl(float* lat, float* lon, float* speed = 0, int* alt = 0, | ||||||
|                   int* vsat = 0, int* usat = 0, int* year = 0, int* month = 0, |                   int* vsat = 0, int* usat = 0, float* accuracy = 0, | ||||||
|                   int* day = 0, int* hour = 0, int* minute = 0, |                   int* year = 0, int* month = 0, int* day = 0, int* hour = 0, | ||||||
|                   int* second = 0) { |                   int* minute = 0, int* second = 0) { | ||||||
|     bool fix = false; |     bool fix = false; | ||||||
|  |  | ||||||
|     sendAT(GF("+CGNSINF")); |     sendAT(GF("+CGNSINF")); | ||||||
| @@ -459,9 +459,10 @@ class TinyGsmSim7000 : public TinyGsmModem<TinyGsmSim7000>, | |||||||
|     streamSkipUntil(',');                             // Fix Mode |     streamSkipUntil(',');                             // Fix Mode | ||||||
|     streamSkipUntil(',');                             // Reserved1 |     streamSkipUntil(',');                             // Reserved1 | ||||||
|     streamSkipUntil(',');  // Horizontal Dilution Of Precision |     streamSkipUntil(',');  // Horizontal Dilution Of Precision | ||||||
|     streamSkipUntil(',');  // Position Dilution Of Precision |     if (accuracy != NULL) | ||||||
|     streamSkipUntil(',');  // Vertical Dilution Of Precision |       *accuracy = streamGetFloat(',');  // Position Dilution Of Precision | ||||||
|     streamSkipUntil(',');  // Reserved2 |     streamSkipUntil(',');               // Vertical Dilution Of Precision | ||||||
|  |     streamSkipUntil(',');               // Reserved2 | ||||||
|     if (vsat != NULL) *vsat = streamGetInt(',');  // GNSS Satellites in View |     if (vsat != NULL) *vsat = streamGetInt(',');  // GNSS Satellites in View | ||||||
|     if (usat != NULL) *usat = streamGetInt(',');  // GNSS Satellites Used |     if (usat != NULL) *usat = streamGetInt(',');  // GNSS Satellites Used | ||||||
|     streamSkipUntil(',');                         // GLONASS Satellites Used |     streamSkipUntil(',');                         // GLONASS Satellites Used | ||||||
|   | |||||||
| @@ -396,13 +396,13 @@ class TinyGsmSim7600 : public TinyGsmModem<TinyGsmSim7600>, | |||||||
|   // Follows all messaging functions per template |   // Follows all messaging functions per template | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * Location functions |    * GSM Location functions | ||||||
|    */ |    */ | ||||||
|  protected: |  protected: | ||||||
|   // Can return a GSM-based location from CLBS as per the template |   // Can return a GSM-based location from CLBS as per the template | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * GPS location functions |    * GPS/GNSS/GLONASS location functions | ||||||
|    */ |    */ | ||||||
|  protected: |  protected: | ||||||
|   // enable GPS |   // enable GPS | ||||||
| @@ -430,9 +430,9 @@ class TinyGsmSim7600 : public TinyGsmModem<TinyGsmSim7600>, | |||||||
|  |  | ||||||
|   // get GPS informations |   // get GPS informations | ||||||
|   bool getGPSImpl(float* lat, float* lon, float* speed = 0, int* alt = 0, |   bool getGPSImpl(float* lat, float* lon, float* speed = 0, int* alt = 0, | ||||||
|                   int* vsat = 0, int* usat = 0, int* year = 0, int* month = 0, |                   int* vsat = 0, int* usat = 0, float* accuracy = 0, | ||||||
|                   int* day = 0, int* hour = 0, int* minute = 0, |                   int* year = 0, int* month = 0, int* day = 0, int* hour = 0, | ||||||
|                   int* second = 0) { |                   int* minute = 0, int* second = 0) { | ||||||
|     // String buffer = ""; |     // String buffer = ""; | ||||||
|  |  | ||||||
|     sendAT(GF("+CGNSSINFO")); |     sendAT(GF("+CGNSSINFO")); | ||||||
| @@ -450,7 +450,7 @@ class TinyGsmSim7600 : public TinyGsmModem<TinyGsmSim7600>, | |||||||
|       streamSkipUntil(',');        // E/W Indicator, E=east or W=west |       streamSkipUntil(',');        // E/W Indicator, E=east or W=west | ||||||
|  |  | ||||||
|       // Date. Output format is ddmmyy |       // Date. Output format is ddmmyy | ||||||
|       char dtSBuff[5] = {'\0'}; |       char dtSBuff[7] = {'\0'}; | ||||||
|       stream.readBytes(dtSBuff, 2);           // Two digit day |       stream.readBytes(dtSBuff, 2);           // Two digit day | ||||||
|       dtSBuff[2] = '\0';                      // null terminate buffer |       dtSBuff[2] = '\0';                      // null terminate buffer | ||||||
|       if (day != NULL) *day = atoi(dtSBuff);  // Convert to int |       if (day != NULL) *day = atoi(dtSBuff);  // Convert to int | ||||||
| @@ -484,10 +484,11 @@ class TinyGsmSim7600 : public TinyGsmModem<TinyGsmSim7600>, | |||||||
|       if (speed != NULL) |       if (speed != NULL) | ||||||
|         *speed = streamGetFloat(',');  // Speed Over Ground. Unit is knots. |         *speed = streamGetFloat(',');  // Speed Over Ground. Unit is knots. | ||||||
|       streamSkipUntil(',');            // Course. Degrees. |       streamSkipUntil(',');            // Course. Degrees. | ||||||
|       streamSkipUntil(',');   // After set, will report GPS every x seconds |       streamSkipUntil(',');  // After set, will report GPS every x seconds | ||||||
|       streamSkipUntil(',');   // Position Dilution Of Precision |       if (accuracy != NULL) | ||||||
|       streamSkipUntil(',');   // Horizontal Dilution Of Precision |         *accuracy = streamGetFloat(',');  // Position Dilution Of Precision | ||||||
|       streamSkipUntil(',');   // Vertical Dilution Of Precision |       streamSkipUntil(',');               // Horizontal Dilution Of Precision | ||||||
|  |       streamSkipUntil(',');               // Vertical Dilution Of Precision | ||||||
|       streamSkipUntil('\n');  // TODO(?) is one more field reported?? |       streamSkipUntil('\n');  // TODO(?) is one more field reported?? | ||||||
|  |  | ||||||
|       waitResponse(); |       waitResponse(); | ||||||
|   | |||||||
| @@ -404,7 +404,7 @@ class TinyGsmSim800 | |||||||
|   // Follows all messaging functions per template |   // Follows all messaging functions per template | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * Location functions |    * GSM Location functions | ||||||
|    */ |    */ | ||||||
|  protected: |  protected: | ||||||
|   // Depending on the exacty model and firmware revision, should return a |   // Depending on the exacty model and firmware revision, should return a | ||||||
| @@ -412,7 +412,7 @@ class TinyGsmSim800 | |||||||
|   // TODO(?):  Check number of digits in year (2 or 4) |   // TODO(?):  Check number of digits in year (2 or 4) | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * GPS location functions |    * GPS/GNSS/GLONASS location functions | ||||||
|    */ |    */ | ||||||
|  protected: |  protected: | ||||||
|   // No functions of this type supported |   // No functions of this type supported | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ class TinyGsmSim808 : public TinyGsmSim800, public TinyGsmGPS<TinyGsmSim808> { | |||||||
|  |  | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * GPS location functions |    * GPS/GNSS/GLONASS location functions | ||||||
|    */ |    */ | ||||||
|  protected: |  protected: | ||||||
|   // enable GPS |   // enable GPS | ||||||
| @@ -57,9 +57,9 @@ class TinyGsmSim808 : public TinyGsmSim800, public TinyGsmGPS<TinyGsmSim808> { | |||||||
|   // get GPS informations |   // get GPS informations | ||||||
|   // works only with ans SIM808 V2 |   // works only with ans SIM808 V2 | ||||||
|   bool getGPSImpl(float* lat, float* lon, float* speed = 0, int* alt = 0, |   bool getGPSImpl(float* lat, float* lon, float* speed = 0, int* alt = 0, | ||||||
|                   int* vsat = 0, int* usat = 0, int* year = 0, int* month = 0, |                   int* vsat = 0, int* usat = 0, float* accuracy = 0, | ||||||
|                   int* day = 0, int* hour = 0, int* minute = 0, |                   int* year = 0, int* month = 0, int* day = 0, int* hour = 0, | ||||||
|                   int* second = 0) { |                   int* minute = 0, int* second = 0) { | ||||||
|     bool fix = false; |     bool fix = false; | ||||||
|  |  | ||||||
|     sendAT(GF("+CGNSINF")); |     sendAT(GF("+CGNSINF")); | ||||||
| @@ -104,7 +104,8 @@ class TinyGsmSim808 : public TinyGsmSim800, public TinyGsmGPS<TinyGsmSim808> { | |||||||
|     streamSkipUntil(',');                             // Fix Mode |     streamSkipUntil(',');                             // Fix Mode | ||||||
|     streamSkipUntil(',');                             // Reserved1 |     streamSkipUntil(',');                             // Reserved1 | ||||||
|     streamSkipUntil(',');  // Horizontal Dilution Of Precision |     streamSkipUntil(',');  // Horizontal Dilution Of Precision | ||||||
|     streamSkipUntil(',');  // Position Dilution Of Precision |     if (accuracy != NULL) | ||||||
|  |       *accuracy = streamGetFloat(',');  // Position Dilution Of Precision | ||||||
|     streamSkipUntil(',');  // Vertical Dilution Of Precision |     streamSkipUntil(',');  // Vertical Dilution Of Precision | ||||||
|     streamSkipUntil(',');  // Reserved2 |     streamSkipUntil(',');  // Reserved2 | ||||||
|     if (vsat != NULL) *vsat = streamGetInt(',');  // GNSS Satellites in View |     if (vsat != NULL) *vsat = streamGetInt(',');  // GNSS Satellites in View | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ | |||||||
|  |  | ||||||
| #include "TinyGsmBattery.tpp" | #include "TinyGsmBattery.tpp" | ||||||
| #include "TinyGsmGPRS.tpp" | #include "TinyGsmGPRS.tpp" | ||||||
|  | #include "TinyGsmGPS.tpp" | ||||||
| #include "TinyGsmGSMLocation.tpp" | #include "TinyGsmGSMLocation.tpp" | ||||||
| #include "TinyGsmModem.tpp" | #include "TinyGsmModem.tpp" | ||||||
| #include "TinyGsmSMS.tpp" | #include "TinyGsmSMS.tpp" | ||||||
| @@ -46,6 +47,7 @@ class TinyGsmSaraR4 | |||||||
|       public TinyGsmSSL<TinyGsmSaraR4>, |       public TinyGsmSSL<TinyGsmSaraR4>, | ||||||
|       public TinyGsmBattery<TinyGsmSaraR4>, |       public TinyGsmBattery<TinyGsmSaraR4>, | ||||||
|       public TinyGsmGSMLocation<TinyGsmSaraR4>, |       public TinyGsmGSMLocation<TinyGsmSaraR4>, | ||||||
|  |       public TinyGsmGPS<TinyGsmSaraR4>, | ||||||
|       public TinyGsmSMS<TinyGsmSaraR4>, |       public TinyGsmSMS<TinyGsmSaraR4>, | ||||||
|       public TinyGsmTemperature<TinyGsmSaraR4>, |       public TinyGsmTemperature<TinyGsmSaraR4>, | ||||||
|       public TinyGsmTime<TinyGsmSaraR4> { |       public TinyGsmTime<TinyGsmSaraR4> { | ||||||
| @@ -56,6 +58,7 @@ class TinyGsmSaraR4 | |||||||
|   friend class TinyGsmSSL<TinyGsmSaraR4>; |   friend class TinyGsmSSL<TinyGsmSaraR4>; | ||||||
|   friend class TinyGsmBattery<TinyGsmSaraR4>; |   friend class TinyGsmBattery<TinyGsmSaraR4>; | ||||||
|   friend class TinyGsmGSMLocation<TinyGsmSaraR4>; |   friend class TinyGsmGSMLocation<TinyGsmSaraR4>; | ||||||
|  |   friend class TinyGsmGPS<TinyGsmSaraR4>; | ||||||
|   friend class TinyGsmSMS<TinyGsmSaraR4>; |   friend class TinyGsmSMS<TinyGsmSaraR4>; | ||||||
|   friend class TinyGsmTemperature<TinyGsmSaraR4>; |   friend class TinyGsmTemperature<TinyGsmSaraR4>; | ||||||
|   friend class TinyGsmTime<TinyGsmSaraR4>; |   friend class TinyGsmTime<TinyGsmSaraR4>; | ||||||
| @@ -422,17 +425,40 @@ class TinyGsmSaraR4 | |||||||
|                            size_t len) TINY_GSM_ATTR_NOT_IMPLEMENTED; |                            size_t len) TINY_GSM_ATTR_NOT_IMPLEMENTED; | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * Location functions |    * GSM/GPS/GNSS/GLONASS Location functions | ||||||
|  |    * NOTE:  u-blox modules use the same function to get location data from both | ||||||
|  |    * GSM tower triangulation and from dedicated GPS/GNSS/GLONASS receivers.  The | ||||||
|  |    * only difference in which sensor the data is requested from. | ||||||
|    */ |    */ | ||||||
|  protected: |  protected: | ||||||
|   String getGsmLocationRawImpl() { |   bool enableGPSImpl() { | ||||||
|  |     // AT+UGPS=<mode>[,<aid_mode>[,<GNSS_systems>]] | ||||||
|  |     // <mode> - 0: GNSS receiver powered off, 1: on | ||||||
|  |     // <aid_mode> - 0: no aiding (default) | ||||||
|  |     // <GNSS_systems> - 3: GPS + SBAS (default) | ||||||
|  |     sendAT(GF("+UGPS=1,0,3")); | ||||||
|  |     if (waitResponse(10000L, GF(GSM_NL "+UGPS:")) != 1) { return false; } | ||||||
|  |     return waitResponse(10000L) == 1; | ||||||
|  |   } | ||||||
|  |   bool disableGPSImpl() { | ||||||
|  |     sendAT(GF("+UGPS=0")); | ||||||
|  |     if (waitResponse(10000L, GF(GSM_NL "+UGPS:")) != 1) { return false; } | ||||||
|  |     return waitResponse(10000L) == 1; | ||||||
|  |   } | ||||||
|  |   String getUbloxLocationRaw(int8_t sensor) { | ||||||
|     // AT+ULOC=<mode>,<sensor>,<response_type>,<timeout>,<accuracy> |     // AT+ULOC=<mode>,<sensor>,<response_type>,<timeout>,<accuracy> | ||||||
|     // <mode> - 2: single shot position |     // <mode> - 2: single shot position | ||||||
|     // <sensor> - 2: use cellular CellLocate® location information |     // <sensor> - 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 | ||||||
|  |     //          information ?? - Docs show using sensor 3 and it's | ||||||
|  |     //          documented for the +UTIME command but not for +ULOC | ||||||
|     // <response_type> - 0: standard (single-hypothesis) response |     // <response_type> - 0: standard (single-hypothesis) response | ||||||
|     // <timeout> - Timeout period in seconds |     // <timeout> - Timeout period in seconds | ||||||
|     // <accuracy> - Target accuracy in meters (1 - 999999) |     // <accuracy> - Target accuracy in meters (1 - 999999) | ||||||
|     sendAT(GF("+ULOC=2,2,0,120,1")); |     sendAT(GF("+ULOC=2,"), sensor, GF(",0,120,1")); | ||||||
|     // wait for first "OK" |     // wait for first "OK" | ||||||
|     if (waitResponse(10000L) != 1) { return ""; } |     if (waitResponse(10000L) != 1) { return ""; } | ||||||
|     // wait for the final result - wait full timeout time |     // wait for the final result - wait full timeout time | ||||||
| @@ -442,21 +468,35 @@ class TinyGsmSaraR4 | |||||||
|     res.trim(); |     res.trim(); | ||||||
|     return res; |     return res; | ||||||
|   } |   } | ||||||
|  |   String getGsmLocationRawImpl() { | ||||||
|  |     return getUbloxLocationRaw(2); | ||||||
|  |   } | ||||||
|  |   String getGPSrawImpl() { | ||||||
|  |     return getUbloxLocationRaw(1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   bool getGsmLocationImpl(float* lat, float* lon, float* accuracy = 0, |   bool getUbloxLocation(int8_t sensor, float* lat, float* lon, float* speed = 0, | ||||||
|                           int* year = 0, int* month = 0, int* day = 0, |                         int* alt = 0, int* vsat = 0, int* usat = 0, | ||||||
|                           int* hour = 0, int* minute = 0, int* second = 0) { |                         float* accuracy = 0, int* year = 0, int* month = 0, | ||||||
|  |                         int* day = 0, int* hour = 0, int* minute = 0, | ||||||
|  |                         int* second = 0) { | ||||||
|     // AT+ULOC=<mode>,<sensor>,<response_type>,<timeout>,<accuracy> |     // AT+ULOC=<mode>,<sensor>,<response_type>,<timeout>,<accuracy> | ||||||
|     // <mode> - 2: single shot position |     // <mode> - 2: single shot position | ||||||
|     // <sensor> - 2: use cellular CellLocate® location information |     // <sensor> - 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 | ||||||
|  |     //          information ?? - Docs show using sensor 3 and it's documented | ||||||
|  |     //          for the +UTIME command but not for +ULOC | ||||||
|     // <response_type> - 0: standard (single-hypothesis) response |     // <response_type> - 0: standard (single-hypothesis) response | ||||||
|     // <timeout> - Timeout period in seconds |     // <timeout> - Timeout period in seconds | ||||||
|     // <accuracy> - Target accuracy in meters (1 - 999999) |     // <accuracy> - Target accuracy in meters (1 - 999999) | ||||||
|     sendAT(GF("+ULOC=2,2,0,120,1")); |     sendAT(GF("+ULOC=2,"), sensor, GF(",0,120,1")); | ||||||
|     // wait for first "OK" |     // wait for first "OK" | ||||||
|     if (waitResponse(10000L) != 1) { return false; } |     if (waitResponse(10000L) != 1) { return false; } | ||||||
|     // wait for the final result - wait full timeout time |     // wait for the final result - wait full timeout time | ||||||
|     if (waitResponse(120000L, GF(GSM_NL "+UULOC:")) != 1) { return false; } |     if (waitResponse(120000L, GF(GSM_NL "+UULOC: ")) != 1) { return false; } | ||||||
|  |  | ||||||
|     // +UULOC: <date>, <time>, <lat>, <long>, <alt>, <uncertainty>, <speed>, |     // +UULOC: <date>, <time>, <lat>, <long>, <alt>, <uncertainty>, <speed>, | ||||||
|     // <direction>, <vertical_acc>, <sensor_used>, <SV_used>, <antenna_status>, |     // <direction>, <vertical_acc>, <sensor_used>, <SV_used>, <antenna_status>, | ||||||
| @@ -498,14 +538,20 @@ class TinyGsmSaraR4 | |||||||
|  |  | ||||||
|     *lat = streamGetFloat(',');  // Estimated latitude, in degrees |     *lat = streamGetFloat(',');  // Estimated latitude, in degrees | ||||||
|     *lon = streamGetFloat(',');  // Estimated longitude, in degrees |     *lon = streamGetFloat(',');  // Estimated longitude, in degrees | ||||||
|  |     if (alt != NULL) | ||||||
|  |       *alt = streamGetFloat(',');  // Estimated altitude, in meters - only for | ||||||
|  |                                    // GNSS positioning, 0 in case of CellLocate | ||||||
|     if (accuracy != NULL) { |     if (accuracy != NULL) { | ||||||
|       *accuracy = streamGetInt(','); |       *accuracy = streamGetFloat(','); | ||||||
|     }                      // Maximum possible error, in meters (0 - 20000000) |     }  // Maximum possible error, in meters (0 - 20000000) | ||||||
|     streamSkipUntil(',');  // Speed over ground m/s3 |     if (speed != NULL) *speed = streamGetFloat(',');  // Speed over ground m/s3 | ||||||
|     streamSkipUntil(',');  // Course over ground in degree (0 deg - 360 deg) |     streamSkipUntil(',');  // Course over ground in degree (0 deg - 360 deg) | ||||||
|     streamSkipUntil(',');  // Vertical accuracy, in meters |     streamSkipUntil(',');  // Vertical accuracy, in meters | ||||||
|     streamSkipUntil(',');  // Sensor used for the position calculation |     streamSkipUntil(',');  // Sensor used for the position calculation | ||||||
|     streamSkipUntil(',');  // Number of satellite used to calculate the position |     streamSkipUntil(',');  // Number of satellite used to calculate the position | ||||||
|  |     if (usat != NULL) | ||||||
|  |       *usat = streamGetInt( | ||||||
|  |           ',');            // Number of satellite used to calculate the position | ||||||
|     streamSkipUntil(',');  // Antenna status |     streamSkipUntil(',');  // Antenna status | ||||||
|     streamSkipUntil('\n');  // Jamming status |     streamSkipUntil('\n');  // Jamming status | ||||||
|  |  | ||||||
| @@ -514,12 +560,19 @@ class TinyGsmSaraR4 | |||||||
|  |  | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|  |   bool getGsmLocationImpl(float* lat, float* lon, float* accuracy = 0, | ||||||
|   /* |                           int* year = 0, int* month = 0, int* day = 0, | ||||||
|    * GPS location functions |                           int* hour = 0, int* minute = 0, int* second = 0) { | ||||||
|    */ |     return getUbloxLocation(2, lat, lon, 0, 0, 0, 0, accuracy, year, month, day, | ||||||
|  protected: |                             hour, minute, second); | ||||||
|   // No functions of this type supported |   }; | ||||||
|  |   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, | ||||||
|  |                   int* minute = 0, int* second = 0) { | ||||||
|  |     return getUbloxLocation(1, lat, lon, speed, alt, vsat, usat, accuracy, year, | ||||||
|  |                             month, day, hour, minute, second); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * Time functions |    * Time functions | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ | |||||||
| #include "TinyGsmBattery.tpp" | #include "TinyGsmBattery.tpp" | ||||||
| #include "TinyGsmCalling.tpp" | #include "TinyGsmCalling.tpp" | ||||||
| #include "TinyGsmGPRS.tpp" | #include "TinyGsmGPRS.tpp" | ||||||
|  | #include "TinyGsmGPS.tpp" | ||||||
| #include "TinyGsmGSMLocation.tpp" | #include "TinyGsmGSMLocation.tpp" | ||||||
| #include "TinyGsmModem.tpp" | #include "TinyGsmModem.tpp" | ||||||
| #include "TinyGsmSMS.tpp" | #include "TinyGsmSMS.tpp" | ||||||
| @@ -47,6 +48,7 @@ class TinyGsmUBLOX | |||||||
|       public TinyGsmCalling<TinyGsmUBLOX>, |       public TinyGsmCalling<TinyGsmUBLOX>, | ||||||
|       public TinyGsmSMS<TinyGsmUBLOX>, |       public TinyGsmSMS<TinyGsmUBLOX>, | ||||||
|       public TinyGsmGSMLocation<TinyGsmUBLOX>, |       public TinyGsmGSMLocation<TinyGsmUBLOX>, | ||||||
|  |       public TinyGsmGPS<TinyGsmUBLOX>, | ||||||
|       public TinyGsmTime<TinyGsmUBLOX>, |       public TinyGsmTime<TinyGsmUBLOX>, | ||||||
|       public TinyGsmBattery<TinyGsmUBLOX> { |       public TinyGsmBattery<TinyGsmUBLOX> { | ||||||
|   friend class TinyGsmModem<TinyGsmUBLOX>; |   friend class TinyGsmModem<TinyGsmUBLOX>; | ||||||
| @@ -57,6 +59,7 @@ class TinyGsmUBLOX | |||||||
|   friend class TinyGsmCalling<TinyGsmUBLOX>; |   friend class TinyGsmCalling<TinyGsmUBLOX>; | ||||||
|   friend class TinyGsmSMS<TinyGsmUBLOX>; |   friend class TinyGsmSMS<TinyGsmUBLOX>; | ||||||
|   friend class TinyGsmGSMLocation<TinyGsmUBLOX>; |   friend class TinyGsmGSMLocation<TinyGsmUBLOX>; | ||||||
|  |   friend class TinyGsmGPS<TinyGsmUBLOX>; | ||||||
|   friend class TinyGsmTime<TinyGsmUBLOX>; |   friend class TinyGsmTime<TinyGsmUBLOX>; | ||||||
|   friend class TinyGsmBattery<TinyGsmUBLOX>; |   friend class TinyGsmBattery<TinyGsmUBLOX>; | ||||||
|  |  | ||||||
| @@ -163,7 +166,7 @@ class TinyGsmUBLOX | |||||||
|   /* |   /* | ||||||
|    * Basic functions |    * Basic functions | ||||||
|    */ |    */ | ||||||
|  |  protected: | ||||||
|   bool initImpl(const char* pin = NULL) { |   bool initImpl(const char* pin = NULL) { | ||||||
|     DBG(GF("### TinyGSM Version:"), TINYGSM_VERSION); |     DBG(GF("### TinyGSM Version:"), TINYGSM_VERSION); | ||||||
|  |  | ||||||
| @@ -197,6 +200,7 @@ class TinyGsmUBLOX | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   // only difference in implementation is the warning on the wrong type | ||||||
|   String getModemNameImpl() { |   String getModemNameImpl() { | ||||||
|     sendAT(GF("+CGMI")); |     sendAT(GF("+CGMI")); | ||||||
|     String res1; |     String res1; | ||||||
| @@ -246,7 +250,7 @@ class TinyGsmUBLOX | |||||||
|     return waitResponse(40000L) == 1; |     return waitResponse(40000L) == 1; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   bool sleepEnableImpl(bool enable = true) TINY_GSM_ATTR_NOT_IMPLEMENTED; |   bool sleepEnableImpl(bool enable = true) TINY_GSM_ATTR_NOT_AVAILABLE; | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * Generic network functions |    * Generic network functions | ||||||
| @@ -365,6 +369,7 @@ class TinyGsmUBLOX | |||||||
|    * SIM card functions |    * SIM card functions | ||||||
|    */ |    */ | ||||||
|  protected: |  protected: | ||||||
|  |   // This uses "CGSN" instead of "GSN" | ||||||
|   String getIMEIImpl() { |   String getIMEIImpl() { | ||||||
|     sendAT(GF("+CGSN")); |     sendAT(GF("+CGSN")); | ||||||
|     if (waitResponse(GF(GSM_NL)) != 1) { return ""; } |     if (waitResponse(GF(GSM_NL)) != 1) { return ""; } | ||||||
| @@ -387,17 +392,40 @@ class TinyGsmUBLOX | |||||||
|   // Can follow all template functions |   // Can follow all template functions | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * Location functions |    * GSM/GPS/GNSS/GLONASS Location functions | ||||||
|  |    * NOTE:  u-blox modules use the same function to get location data from both | ||||||
|  |    * GSM tower triangulation and from dedicated GPS/GNSS/GLONASS receivers.  The | ||||||
|  |    * only difference in which sensor the data is requested from. | ||||||
|    */ |    */ | ||||||
|  protected: |  protected: | ||||||
|   String getGsmLocationRawImpl() { |   bool enableGPSImpl() { | ||||||
|  |     // AT+UGPS=<mode>[,<aid_mode>[,<GNSS_systems>]] | ||||||
|  |     // <mode> - 0: GNSS receiver powered off, 1: on | ||||||
|  |     // <aid_mode> - 0: no aiding (default) | ||||||
|  |     // <GNSS_systems> - 3: GPS + SBAS (default) | ||||||
|  |     sendAT(GF("+UGPS=1,0,3")); | ||||||
|  |     if (waitResponse(10000L, GF(GSM_NL "+UGPS:")) != 1) { return false; } | ||||||
|  |     return waitResponse(10000L) == 1; | ||||||
|  |   } | ||||||
|  |   bool disableGPSImpl() { | ||||||
|  |     sendAT(GF("+UGPS=0")); | ||||||
|  |     if (waitResponse(10000L, GF(GSM_NL "+UGPS:")) != 1) { return false; } | ||||||
|  |     return waitResponse(10000L) == 1; | ||||||
|  |   } | ||||||
|  |   String getUbloxLocationRaw(int8_t sensor) { | ||||||
|     // AT+ULOC=<mode>,<sensor>,<response_type>,<timeout>,<accuracy> |     // AT+ULOC=<mode>,<sensor>,<response_type>,<timeout>,<accuracy> | ||||||
|     // <mode> - 2: single shot position |     // <mode> - 2: single shot position | ||||||
|     // <sensor> - 2: use cellular CellLocate® location information |     // <sensor> - 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 | ||||||
|  |     //          information ?? - Docs show using sensor 3 and it's | ||||||
|  |     //          documented for the +UTIME command but not for +ULOC | ||||||
|     // <response_type> - 0: standard (single-hypothesis) response |     // <response_type> - 0: standard (single-hypothesis) response | ||||||
|     // <timeout> - Timeout period in seconds |     // <timeout> - Timeout period in seconds | ||||||
|     // <accuracy> - Target accuracy in meters (1 - 999999) |     // <accuracy> - Target accuracy in meters (1 - 999999) | ||||||
|     sendAT(GF("+ULOC=2,2,0,120,1")); |     sendAT(GF("+ULOC=2,"), sensor, GF(",0,120,1")); | ||||||
|     // wait for first "OK" |     // wait for first "OK" | ||||||
|     if (waitResponse(10000L) != 1) { return ""; } |     if (waitResponse(10000L) != 1) { return ""; } | ||||||
|     // wait for the final result - wait full timeout time |     // wait for the final result - wait full timeout time | ||||||
| @@ -407,21 +435,35 @@ class TinyGsmUBLOX | |||||||
|     res.trim(); |     res.trim(); | ||||||
|     return res; |     return res; | ||||||
|   } |   } | ||||||
|  |   String getGsmLocationRawImpl() { | ||||||
|  |     return getUbloxLocationRaw(2); | ||||||
|  |   } | ||||||
|  |   String getGPSrawImpl() { | ||||||
|  |     return getUbloxLocationRaw(1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   bool getGsmLocationImpl(float* lat, float* lon, float* accuracy = 0, |   bool getUbloxLocation(int8_t sensor, float* lat, float* lon, float* speed = 0, | ||||||
|                           int* year = 0, int* month = 0, int* day = 0, |                         int* alt = 0, int* vsat = 0, int* usat = 0, | ||||||
|                           int* hour = 0, int* minute = 0, int* second = 0) { |                         float* accuracy = 0, int* year = 0, int* month = 0, | ||||||
|  |                         int* day = 0, int* hour = 0, int* minute = 0, | ||||||
|  |                         int* second = 0) { | ||||||
|     // AT+ULOC=<mode>,<sensor>,<response_type>,<timeout>,<accuracy> |     // AT+ULOC=<mode>,<sensor>,<response_type>,<timeout>,<accuracy> | ||||||
|     // <mode> - 2: single shot position |     // <mode> - 2: single shot position | ||||||
|     // <sensor> - 2: use cellular CellLocate® location information |     // <sensor> - 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 | ||||||
|  |     //          information ?? - Docs show using sensor 3 and it's documented | ||||||
|  |     //          for the +UTIME command but not for +ULOC | ||||||
|     // <response_type> - 0: standard (single-hypothesis) response |     // <response_type> - 0: standard (single-hypothesis) response | ||||||
|     // <timeout> - Timeout period in seconds |     // <timeout> - Timeout period in seconds | ||||||
|     // <accuracy> - Target accuracy in meters (1 - 999999) |     // <accuracy> - Target accuracy in meters (1 - 999999) | ||||||
|     sendAT(GF("+ULOC=2,2,0,120,1")); |     sendAT(GF("+ULOC=2,"), sensor, GF(",0,120,1")); | ||||||
|     // wait for first "OK" |     // wait for first "OK" | ||||||
|     if (waitResponse(10000L) != 1) { return false; } |     if (waitResponse(10000L) != 1) { return false; } | ||||||
|     // wait for the final result - wait full timeout time |     // wait for the final result - wait full timeout time | ||||||
|     if (waitResponse(120000L, GF(GSM_NL "+UULOC:")) != 1) { return false; } |     if (waitResponse(120000L, GF(GSM_NL "+UULOC: ")) != 1) { return false; } | ||||||
|  |  | ||||||
|     // +UULOC: <date>, <time>, <lat>, <long>, <alt>, <uncertainty>, <speed>, |     // +UULOC: <date>, <time>, <lat>, <long>, <alt>, <uncertainty>, <speed>, | ||||||
|     // <direction>, <vertical_acc>, <sensor_used>, <SV_used>, <antenna_status>, |     // <direction>, <vertical_acc>, <sensor_used>, <SV_used>, <antenna_status>, | ||||||
| @@ -463,14 +505,20 @@ class TinyGsmUBLOX | |||||||
|  |  | ||||||
|     *lat = streamGetFloat(',');  // Estimated latitude, in degrees |     *lat = streamGetFloat(',');  // Estimated latitude, in degrees | ||||||
|     *lon = streamGetFloat(',');  // Estimated longitude, in degrees |     *lon = streamGetFloat(',');  // Estimated longitude, in degrees | ||||||
|  |     if (alt != NULL) | ||||||
|  |       *alt = streamGetFloat(',');  // Estimated altitude, in meters - only for | ||||||
|  |                                    // GNSS positioning, 0 in case of CellLocate | ||||||
|     if (accuracy != NULL) { |     if (accuracy != NULL) { | ||||||
|       *accuracy = streamGetInt(','); |       *accuracy = streamGetFloat(','); | ||||||
|     }                      // Maximum possible error, in meters (0 - 20000000) |     }  // Maximum possible error, in meters (0 - 20000000) | ||||||
|     streamSkipUntil(',');  // Speed over ground m/s3 |     if (speed != NULL) *speed = streamGetFloat(',');  // Speed over ground m/s3 | ||||||
|     streamSkipUntil(',');  // Course over ground in degree (0 deg - 360 deg) |     streamSkipUntil(',');  // Course over ground in degree (0 deg - 360 deg) | ||||||
|     streamSkipUntil(',');  // Vertical accuracy, in meters |     streamSkipUntil(',');  // Vertical accuracy, in meters | ||||||
|     streamSkipUntil(',');  // Sensor used for the position calculation |     streamSkipUntil(',');  // Sensor used for the position calculation | ||||||
|     streamSkipUntil(',');  // Number of satellite used to calculate the position |     streamSkipUntil(',');  // Number of satellite used to calculate the position | ||||||
|  |     if (usat != NULL) | ||||||
|  |       *usat = streamGetInt( | ||||||
|  |           ',');            // Number of satellite used to calculate the position | ||||||
|     streamSkipUntil(',');  // Antenna status |     streamSkipUntil(',');  // Antenna status | ||||||
|     streamSkipUntil('\n');  // Jamming status |     streamSkipUntil('\n');  // Jamming status | ||||||
|  |  | ||||||
| @@ -479,6 +527,19 @@ class TinyGsmUBLOX | |||||||
|  |  | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|  |   bool getGsmLocationImpl(float* lat, float* lon, float* accuracy = 0, | ||||||
|  |                           int* year = 0, int* month = 0, int* day = 0, | ||||||
|  |                           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, | ||||||
|  |                   int* minute = 0, int* second = 0) { | ||||||
|  |     return getUbloxLocation(1, lat, lon, speed, alt, vsat, usat, accuracy, year, | ||||||
|  |                             month, day, hour, minute, second); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * Time functions |    * Time functions | ||||||
| @@ -527,12 +588,13 @@ class TinyGsmUBLOX | |||||||
|  protected: |  protected: | ||||||
|   bool modemConnect(const char* host, uint16_t port, uint8_t* mux, |   bool modemConnect(const char* host, uint16_t port, uint8_t* mux, | ||||||
|                     bool ssl = false, int timeout_s = 120) { |                     bool ssl = false, int timeout_s = 120) { | ||||||
|     uint32_t timeout_ms = ((uint32_t)timeout_s) * 1000; |     uint32_t timeout_ms  = ((uint32_t)timeout_s) * 1000; | ||||||
|  |     uint32_t startMillis = millis(); | ||||||
|  |  | ||||||
|  |     // create a socket | ||||||
|     sendAT(GF("+USOCR=6"));  // create a socket |     sendAT(GF("+USOCR=6"));  // create a socket | ||||||
|     if (waitResponse(GF(GSM_NL "+USOCR:")) != |     // reply is +USOCR: ## of socket created | ||||||
|         1) {  // reply is +USOCR: ## of socket created |     if (waitResponse(GF(GSM_NL "+USOCR:")) != 1) { return false; } | ||||||
|       return false; |  | ||||||
|     } |  | ||||||
|     *mux = streamGetInt('\n'); |     *mux = streamGetInt('\n'); | ||||||
|     waitResponse(); |     waitResponse(); | ||||||
|  |  | ||||||
| @@ -542,9 +604,12 @@ class TinyGsmUBLOX | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Enable NODELAY |     // Enable NODELAY | ||||||
|     // NOTE:  No delay allows data to go out faster, at the cost of using |     // AT+USOSO=<socket>,<level>,<opt_name>,<opt_val>[,<opt_val2>] | ||||||
|     // additional data from your cellular plan sendAT(GF("+USOSO="), *mux, |     // <level> - 0 for IP, 6 for TCP, 65535 for socket level options | ||||||
|     // GF(",6,1,1")); waitResponse(); |     // <opt_name> TCP/1 = no delay (do not delay send to coalesce packets) | ||||||
|  |     // NOTE:  Enabling this may increase data plan usage | ||||||
|  |     // sendAT(GF("+USOSO="), *mux, GF(",6,1,1")); | ||||||
|  |     // waitResponse(); | ||||||
|  |  | ||||||
|     // Enable KEEPALIVE, 30 sec |     // Enable KEEPALIVE, 30 sec | ||||||
|     // sendAT(GF("+USOSO="), *mux, GF(",6,2,30000")); |     // sendAT(GF("+USOSO="), *mux, GF(",6,2,30000")); | ||||||
| @@ -552,7 +617,7 @@ class TinyGsmUBLOX | |||||||
|  |  | ||||||
|     // connect on the allocated socket |     // connect on the allocated socket | ||||||
|     sendAT(GF("+USOCO="), *mux, ",\"", host, "\",", port); |     sendAT(GF("+USOCO="), *mux, ",\"", host, "\",", port); | ||||||
|     int rsp = waitResponse(timeout_ms); |     int rsp = waitResponse(timeout_ms - (millis() - startMillis)); | ||||||
|     return (1 == rsp); |     return (1 == rsp); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ template <class modemType> | |||||||
| class TinyGsmGPS { | class TinyGsmGPS { | ||||||
|  public: |  public: | ||||||
|   /* |   /* | ||||||
|    * GPS location functions |    * GPS/GNSS/GLONASS location functions | ||||||
|    */ |    */ | ||||||
|   bool enableGPS() { |   bool enableGPS() { | ||||||
|     return thisModem().enableGPSImpl(); |     return thisModem().enableGPSImpl(); | ||||||
| @@ -29,17 +29,18 @@ class TinyGsmGPS { | |||||||
|     return thisModem().getGPSrawImpl(); |     return thisModem().getGPSrawImpl(); | ||||||
|   } |   } | ||||||
|   bool getGPS(float* lat, float* lon, float* speed = 0, int* alt = 0, |   bool getGPS(float* lat, float* lon, float* speed = 0, int* alt = 0, | ||||||
|               int* vsat = 0, int* usat = 0, int* year = 0, int* month = 0, |               int* vsat = 0, int* usat = 0, float* accuracy = 0, int* year = 0, | ||||||
|               int* day = 0, int* hour = 0, int* minute = 0, int* second = 0) { |               int* month = 0, int* day = 0, int* hour = 0, int* minute = 0, | ||||||
|     return thisModem().getGPSImpl(lat, lon, speed, alt, vsat, usat, year, month, |               int* second = 0) { | ||||||
|                                   day, hour, minute, second); |     return thisModem().getGPSImpl(lat, lon, speed, alt, vsat, usat, accuracy, | ||||||
|  |                                   year, month, day, hour, minute, second); | ||||||
|   } |   } | ||||||
|   bool getGPSTime(int* year, int* month, int* day, int* hour, int* minute, |   bool getGPSTime(int* year, int* month, int* day, int* hour, int* minute, | ||||||
|                   int* second) { |                   int* second) { | ||||||
|     float lat = 0; |     float lat = 0; | ||||||
|     float lon = 0; |     float lon = 0; | ||||||
|     return thisModem().getGPSImpl(lat, lon, 0, 0, 0, 0, year, month, day, hour, |     return thisModem().getGPSImpl(lat, lon, 0, 0, 0, 0, 0, year, month, day, | ||||||
|                                   minute, second); |                                   hour, minute, second); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
| @@ -54,15 +55,16 @@ class TinyGsmGPS { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * GPS location functions |    * GPS/GNSS/GLONASS location functions | ||||||
|    */ |    */ | ||||||
|  |  | ||||||
|   bool   enableGPSImpl() TINY_GSM_ATTR_NOT_IMPLEMENTED; |   bool   enableGPSImpl() TINY_GSM_ATTR_NOT_IMPLEMENTED; | ||||||
|   bool   disableGPSImpl() TINY_GSM_ATTR_NOT_IMPLEMENTED; |   bool   disableGPSImpl() TINY_GSM_ATTR_NOT_IMPLEMENTED; | ||||||
|   String getGPSrawImpl() TINY_GSM_ATTR_NOT_IMPLEMENTED; |   String getGPSrawImpl() TINY_GSM_ATTR_NOT_IMPLEMENTED; | ||||||
|   bool   getGPSImpl(float* lat, float* lon, float* speed = 0, int* alt = 0, |   bool   getGPSImpl(float* lat, float* lon, float* speed = 0, int* alt = 0, | ||||||
|                     int* vsat = 0, int* usat = 0, int* year = 0, int* month = 0, |                     int* vsat = 0, int* usat = 0, float* accuracy = 0, | ||||||
|                     int* day = 0, int* hour = 0, int* minute = 0, |                     int* year = 0, int* month = 0, int* day = 0, int* hour = 0, | ||||||
|  |                     int* minute = 0, | ||||||
|                     int* second = 0) TINY_GSM_ATTR_NOT_IMPLEMENTED; |                     int* second = 0) TINY_GSM_ATTR_NOT_IMPLEMENTED; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ template <class modemType> | |||||||
| class TinyGsmGSMLocation { | class TinyGsmGSMLocation { | ||||||
|  public: |  public: | ||||||
|   /* |   /* | ||||||
|    * Location functions |    * GSM Location functions | ||||||
|    */ |    */ | ||||||
|   String getGsmLocationRaw() { |   String getGsmLocationRaw() { | ||||||
|     return thisModem().getGsmLocationRawImpl(); |     return thisModem().getGsmLocationRawImpl(); | ||||||
| @@ -54,7 +54,7 @@ class TinyGsmGSMLocation { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * Location functions |    * GSM Location functions | ||||||
|    * Template is based on SIMCOM commands |    * Template is based on SIMCOM commands | ||||||
|    */ |    */ | ||||||
|  protected: |  protected: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user