mirror of
				https://github.com/KevinMidboe/TinyGSM.git
				synced 2025-10-29 18:00:18 +00:00 
			
		
		
		
	Redo GSM location and GPS stringlessly
Signed-off-by: Sara Damiano <sdamiano@stroudcenter.org>
This commit is contained in:
		| @@ -16,6 +16,7 @@ | |||||||
|  |  | ||||||
| #include "TinyGsmBattery.tpp" | #include "TinyGsmBattery.tpp" | ||||||
| #include "TinyGsmGPRS.tpp" | #include "TinyGsmGPRS.tpp" | ||||||
|  | #include "TinyGsmGSMLocation.tpp" | ||||||
| #include "TinyGsmModem.tpp" | #include "TinyGsmModem.tpp" | ||||||
| #include "TinyGsmSMS.tpp" | #include "TinyGsmSMS.tpp" | ||||||
| #include "TinyGsmTCP.tpp" | #include "TinyGsmTCP.tpp" | ||||||
| @@ -43,6 +44,7 @@ class TinyGsmSim5360 : public TinyGsmModem<TinyGsmSim5360>, | |||||||
|                                          TINY_GSM_MUX_COUNT>, |                                          TINY_GSM_MUX_COUNT>, | ||||||
|                        public TinyGsmSMS<TinyGsmSim5360>, |                        public TinyGsmSMS<TinyGsmSim5360>, | ||||||
|                        public TinyGsmTime<TinyGsmSim5360>, |                        public TinyGsmTime<TinyGsmSim5360>, | ||||||
|  |                        public TinyGsmGSMLocation<TinyGsmSim5360>, | ||||||
|                        public TinyGsmBattery<TinyGsmSim5360>, |                        public TinyGsmBattery<TinyGsmSim5360>, | ||||||
|                        public TinyGsmTemperature<TinyGsmSim5360> { |                        public TinyGsmTemperature<TinyGsmSim5360> { | ||||||
|   friend class TinyGsmModem<TinyGsmSim5360>; |   friend class TinyGsmModem<TinyGsmSim5360>; | ||||||
| @@ -51,6 +53,7 @@ class TinyGsmSim5360 : public TinyGsmModem<TinyGsmSim5360>, | |||||||
|                           TINY_GSM_MUX_COUNT>; |                           TINY_GSM_MUX_COUNT>; | ||||||
|   friend class TinyGsmSMS<TinyGsmSim5360>; |   friend class TinyGsmSMS<TinyGsmSim5360>; | ||||||
|   friend class TinyGsmTime<TinyGsmSim5360>; |   friend class TinyGsmTime<TinyGsmSim5360>; | ||||||
|  |   friend class TinyGsmGSMLocation<TinyGsmSim5360>; | ||||||
|   friend class TinyGsmBattery<TinyGsmSim5360>; |   friend class TinyGsmBattery<TinyGsmSim5360>; | ||||||
|   friend class TinyGsmTemperature<TinyGsmSim5360>; |   friend class TinyGsmTemperature<TinyGsmSim5360>; | ||||||
|  |  | ||||||
| @@ -401,6 +404,13 @@ class TinyGsmSim5360 : public TinyGsmModem<TinyGsmSim5360>, | |||||||
|  protected: |  protected: | ||||||
|   // Follows all messaging functions per template |   // Follows all messaging functions per template | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Location functions | ||||||
|  |    */ | ||||||
|  |  protected: | ||||||
|  |   // SIM5360 and SIM7100 can return a GSM-based location from CLBS as per the | ||||||
|  |   // template; SIM5320 doesn't not appear to be able to | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * Time functions |    * Time functions | ||||||
|    */ |    */ | ||||||
|   | |||||||
| @@ -17,7 +17,6 @@ | |||||||
| #include "TinyGsmBattery.tpp" | #include "TinyGsmBattery.tpp" | ||||||
| #include "TinyGsmGPRS.tpp" | #include "TinyGsmGPRS.tpp" | ||||||
| #include "TinyGsmGPS.tpp" | #include "TinyGsmGPS.tpp" | ||||||
| #include "TinyGsmGSMLocation.tpp" |  | ||||||
| #include "TinyGsmModem.tpp" | #include "TinyGsmModem.tpp" | ||||||
| #include "TinyGsmSMS.tpp" | #include "TinyGsmSMS.tpp" | ||||||
| #include "TinyGsmTCP.tpp" | #include "TinyGsmTCP.tpp" | ||||||
| @@ -43,7 +42,6 @@ class TinyGsmSim7000 : public TinyGsmModem<TinyGsmSim7000>, | |||||||
|                        public TinyGsmTCP<TinyGsmSim7000, READ_AND_CHECK_SIZE, |                        public TinyGsmTCP<TinyGsmSim7000, READ_AND_CHECK_SIZE, | ||||||
|                                          TINY_GSM_MUX_COUNT>, |                                          TINY_GSM_MUX_COUNT>, | ||||||
|                        public TinyGsmSMS<TinyGsmSim7000>, |                        public TinyGsmSMS<TinyGsmSim7000>, | ||||||
|                        public TinyGsmGSMLocation<TinyGsmSim7000>, |  | ||||||
|                        public TinyGsmGPS<TinyGsmSim7000>, |                        public TinyGsmGPS<TinyGsmSim7000>, | ||||||
|                        public TinyGsmTime<TinyGsmSim7000>, |                        public TinyGsmTime<TinyGsmSim7000>, | ||||||
|                        public TinyGsmBattery<TinyGsmSim7000> { |                        public TinyGsmBattery<TinyGsmSim7000> { | ||||||
| @@ -52,7 +50,6 @@ class TinyGsmSim7000 : public TinyGsmModem<TinyGsmSim7000>, | |||||||
|   friend class TinyGsmTCP<TinyGsmSim7000, READ_AND_CHECK_SIZE, |   friend class TinyGsmTCP<TinyGsmSim7000, READ_AND_CHECK_SIZE, | ||||||
|                           TINY_GSM_MUX_COUNT>; |                           TINY_GSM_MUX_COUNT>; | ||||||
|   friend class TinyGsmSMS<TinyGsmSim7000>; |   friend class TinyGsmSMS<TinyGsmSim7000>; | ||||||
|   friend class TinyGsmGSMLocation<TinyGsmSim7000>; |  | ||||||
|   friend class TinyGsmGPS<TinyGsmSim7000>; |   friend class TinyGsmGPS<TinyGsmSim7000>; | ||||||
|   friend class TinyGsmTime<TinyGsmSim7000>; |   friend class TinyGsmTime<TinyGsmSim7000>; | ||||||
|   friend class TinyGsmBattery<TinyGsmSim7000>; |   friend class TinyGsmBattery<TinyGsmSim7000>; | ||||||
| @@ -390,13 +387,6 @@ class TinyGsmSim7000 : public TinyGsmModem<TinyGsmSim7000>, | |||||||
|  protected: |  protected: | ||||||
|   // Follows all messaging functions per template |   // Follows all messaging functions per template | ||||||
|  |  | ||||||
|   /* |  | ||||||
|    * Location functions |  | ||||||
|    */ |  | ||||||
|  protected: |  | ||||||
|   // Can return a location from CIPGSMLOC as per the template |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * GPS location functions |    * GPS location functions | ||||||
|    */ |    */ | ||||||
| @@ -426,16 +416,45 @@ 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* vsat = 0, int* usat = 0, int* year = 0, int* month = 0, | ||||||
|     // String buffer = ""; |                   int* day = 0, int* hour = 0, int* minute = 0, | ||||||
|  |                   int* second = 0) { | ||||||
|     bool fix = false; |     bool fix = false; | ||||||
|  |  | ||||||
|     sendAT(GF("+CGNSINF")); |     sendAT(GF("+CGNSINF")); | ||||||
|     if (waitResponse(GF(GSM_NL "+CGNSINF:")) != 1) { return false; } |     if (waitResponse(GF(GSM_NL "+CGNSINF:")) != 1) { return false; } | ||||||
|  |  | ||||||
|     streamSkipUntil(',');                             // GNSS run status |     streamSkipUntil(',');                    // GNSS run status | ||||||
|     if (streamGetInt(',') == 1) fix = true;           // fix status |     if (streamGetInt(',') == 1) fix = true;  // fix status | ||||||
|     streamSkipUntil(',');                             // UTC date & Time |  | ||||||
|  |     // 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 |     *lat = streamGetFloat(',');                       // Latitude | ||||||
|     *lon = streamGetFloat(',');                       // Longitude |     *lon = streamGetFloat(',');                       // Longitude | ||||||
|     if (alt != NULL) *alt = streamGetFloat(',');      // MSL Altitude |     if (alt != NULL) *alt = streamGetFloat(',');      // MSL Altitude | ||||||
| @@ -459,49 +478,6 @@ class TinyGsmSim7000 : public TinyGsmModem<TinyGsmSim7000>, | |||||||
|  |  | ||||||
|     return fix; |     return fix; | ||||||
|   } |   } | ||||||
|   // get GPS time |  | ||||||
|   bool getGPSTimeImpl(int* year, int* month, int* day, int* hour, int* minute, |  | ||||||
|                       int* second) { |  | ||||||
|     bool fix = false; |  | ||||||
|     char chr_buffer[12]; |  | ||||||
|     sendAT(GF("+CGNSINF")); |  | ||||||
|     if (waitResponse(GF(GSM_NL "+CGNSINF:")) != 1) { return false; } |  | ||||||
|  |  | ||||||
|     for (int i = 0; i < 3; i++) { |  | ||||||
|       String buffer = stream.readStringUntil(','); |  | ||||||
|       buffer.toCharArray(chr_buffer, sizeof(chr_buffer)); |  | ||||||
|       switch (i) { |  | ||||||
|         case 0: |  | ||||||
|           // mode |  | ||||||
|           break; |  | ||||||
|         case 1: |  | ||||||
|           // fixstatus |  | ||||||
|           if (buffer.toInt() == 1) { fix = buffer.toInt(); } |  | ||||||
|           break; |  | ||||||
|         case 2: |  | ||||||
|           *year   = buffer.substring(0, 4).toInt(); |  | ||||||
|           *month  = buffer.substring(4, 6).toInt(); |  | ||||||
|           *day    = buffer.substring(6, 8).toInt(); |  | ||||||
|           *hour   = buffer.substring(8, 10).toInt(); |  | ||||||
|           *minute = buffer.substring(10, 12).toInt(); |  | ||||||
|           *second = buffer.substring(12, 14).toInt(); |  | ||||||
|           break; |  | ||||||
|  |  | ||||||
|         default: |  | ||||||
|           // if nothing else matches, do the default |  | ||||||
|           // default is optional |  | ||||||
|           break; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     streamSkipUntil('\n'); |  | ||||||
|     waitResponse(); |  | ||||||
|  |  | ||||||
|     if (fix) { |  | ||||||
|       return true; |  | ||||||
|     } else { |  | ||||||
|       return false; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * Time functions |    * Time functions | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ | |||||||
| #include "TinyGsmBattery.tpp" | #include "TinyGsmBattery.tpp" | ||||||
| #include "TinyGsmGPRS.tpp" | #include "TinyGsmGPRS.tpp" | ||||||
| #include "TinyGsmGPS.tpp" | #include "TinyGsmGPS.tpp" | ||||||
|  | #include "TinyGsmGSMLocation.tpp" | ||||||
| #include "TinyGsmModem.tpp" | #include "TinyGsmModem.tpp" | ||||||
| #include "TinyGsmSMS.tpp" | #include "TinyGsmSMS.tpp" | ||||||
| #include "TinyGsmTCP.tpp" | #include "TinyGsmTCP.tpp" | ||||||
| @@ -43,6 +44,7 @@ class TinyGsmSim7600 : public TinyGsmModem<TinyGsmSim7600>, | |||||||
|                        public TinyGsmTCP<TinyGsmSim7600, READ_AND_CHECK_SIZE, |                        public TinyGsmTCP<TinyGsmSim7600, READ_AND_CHECK_SIZE, | ||||||
|                                          TINY_GSM_MUX_COUNT>, |                                          TINY_GSM_MUX_COUNT>, | ||||||
|                        public TinyGsmSMS<TinyGsmSim7600>, |                        public TinyGsmSMS<TinyGsmSim7600>, | ||||||
|  |                        public TinyGsmGSMLocation<TinyGsmSim7600>, | ||||||
|                        public TinyGsmGPS<TinyGsmSim7600>, |                        public TinyGsmGPS<TinyGsmSim7600>, | ||||||
|                        public TinyGsmTime<TinyGsmSim7600>, |                        public TinyGsmTime<TinyGsmSim7600>, | ||||||
|                        public TinyGsmBattery<TinyGsmSim7600>, |                        public TinyGsmBattery<TinyGsmSim7600>, | ||||||
| @@ -53,6 +55,7 @@ class TinyGsmSim7600 : public TinyGsmModem<TinyGsmSim7600>, | |||||||
|                           TINY_GSM_MUX_COUNT>; |                           TINY_GSM_MUX_COUNT>; | ||||||
|   friend class TinyGsmSMS<TinyGsmSim7600>; |   friend class TinyGsmSMS<TinyGsmSim7600>; | ||||||
|   friend class TinyGsmGPS<TinyGsmSim7600>; |   friend class TinyGsmGPS<TinyGsmSim7600>; | ||||||
|  |   friend class TinyGsmGSMLocation<TinyGsmSim7600>; | ||||||
|   friend class TinyGsmTime<TinyGsmSim7600>; |   friend class TinyGsmTime<TinyGsmSim7600>; | ||||||
|   friend class TinyGsmBattery<TinyGsmSim7600>; |   friend class TinyGsmBattery<TinyGsmSim7600>; | ||||||
|   friend class TinyGsmTemperature<TinyGsmSim7600>; |   friend class TinyGsmTemperature<TinyGsmSim7600>; | ||||||
| @@ -85,7 +88,7 @@ class TinyGsmSim7600 : public TinyGsmModem<TinyGsmSim7600>, | |||||||
|     } |     } | ||||||
|  |  | ||||||
|    public: |    public: | ||||||
|     int connect(const char* host, uint16_t port, int timeout_s) { |     virtual int connect(const char* host, uint16_t port, int timeout_s) { | ||||||
|       stop(); |       stop(); | ||||||
|       TINY_GSM_YIELD(); |       TINY_GSM_YIELD(); | ||||||
|       rx.clear(); |       rx.clear(); | ||||||
| @@ -396,8 +399,7 @@ class TinyGsmSim7600 : public TinyGsmModem<TinyGsmSim7600>, | |||||||
|    * Location functions |    * Location functions | ||||||
|    */ |    */ | ||||||
|  protected: |  protected: | ||||||
|   String getGsmLocationImpl() TINY_GSM_ATTR_NOT_IMPLEMENTED; |   // Can return a GSM-based location from CLBS as per the template | ||||||
|  |  | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * GPS location functions |    * GPS location functions | ||||||
| @@ -427,39 +429,72 @@ 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* day = 0, int* hour = 0, int* minute = 0, | ||||||
|  |                   int* second = 0) { | ||||||
|     // String buffer = ""; |     // String buffer = ""; | ||||||
|     bool fix = false; |  | ||||||
|  |  | ||||||
|     sendAT(GF("+CGNSSINFO")); |     sendAT(GF("+CGNSSINFO")); | ||||||
|     if (waitResponse(GF(GSM_NL "+CGNSSINFO:")) != 1) { return false; } |     if (waitResponse(GF(GSM_NL "+CGNSSINFO:")) != 1) { return false; } | ||||||
|  |  | ||||||
|     // streamSkipUntil(','); // mode |     uint8_t fixMode = streamGetInt(',');  // mode 2=2D Fix or 3=3DFix | ||||||
|     if (streamGetInt(',') == 1) |                                           // TODO(?) Can 1 be returned | ||||||
|       fix = true;          // TODO(?) Shouldn't this be 2=2D Fix or 3=3DFix? |     if (fixMode == 1 || fixMode == 2 || fixMode == 3) { | ||||||
|     streamSkipUntil(',');  // GPS satellite valid numbers |       streamSkipUntil(',');        // GPS satellite valid numbers | ||||||
|     streamSkipUntil(',');  // GLONASS satellite valid numbers |       streamSkipUntil(',');        // GLONASS satellite valid numbers | ||||||
|     streamSkipUntil(',');  // BEIDOU satellite valid numbers |       streamSkipUntil(',');        // BEIDOU satellite valid numbers | ||||||
|     *lat = streamGetFloat(',');  // Latitude |       *lat = streamGetFloat(',');  // Latitude | ||||||
|     streamSkipUntil(',');        // N/S Indicator, N=north or S=south |       streamSkipUntil(',');        // N/S Indicator, N=north or S=south | ||||||
|     *lon = streamGetFloat(',');  // Longitude |       *lon = streamGetFloat(',');  // Longitude | ||||||
|     streamSkipUntil(',');        // E/W Indicator, E=east or W=west |       streamSkipUntil(',');        // E/W Indicator, E=east or W=west | ||||||
|     streamSkipUntil(',');        // Date. Output format is ddmmyy |  | ||||||
|     streamSkipUntil(',');        // UTC Time. Output format is hhmmss.s |  | ||||||
|     if (alt != NULL) |  | ||||||
|       *alt = streamGetFloat(',');  // MSL Altitude. Unit is meters |  | ||||||
|     if (speed != NULL) |  | ||||||
|       *speed = streamGetFloat(',');  // Speed Over Ground. Unit is knots. |  | ||||||
|     streamSkipUntil(',');            // Course. Degrees. |  | ||||||
|     streamSkipUntil(',');   // After set, will report GPS every x seconds |  | ||||||
|     streamSkipUntil(',');   // Position Dilution Of Precision |  | ||||||
|     streamSkipUntil(',');   // Horizontal Dilution Of Precision |  | ||||||
|     streamSkipUntil(',');   // Vertical Dilution Of Precision |  | ||||||
|     streamSkipUntil('\n');  // TODO(?) is one more field reported?? |  | ||||||
|  |  | ||||||
|     waitResponse(); |       // Date. Output format is ddmmyy | ||||||
|  |       char dtSBuff[5] = {'\0'}; | ||||||
|  |       stream.readBytes(dtSBuff, 2);           // Two digit day | ||||||
|  |       dtSBuff[2] = '\0';                      // null terminate buffer | ||||||
|  |       if (day != NULL) *day = atoi(dtSBuff);  // Convert to int | ||||||
|  |  | ||||||
|     return fix; |       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 | ||||||
|  |  | ||||||
|  |       // 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) | ||||||
|  |         *alt = streamGetFloat(',');  // MSL Altitude. Unit is meters | ||||||
|  |       if (speed != NULL) | ||||||
|  |         *speed = streamGetFloat(',');  // Speed Over Ground. Unit is knots. | ||||||
|  |       streamSkipUntil(',');            // Course. Degrees. | ||||||
|  |       streamSkipUntil(',');   // After set, will report GPS every x seconds | ||||||
|  |       streamSkipUntil(',');   // Position Dilution Of Precision | ||||||
|  |       streamSkipUntil(',');   // Horizontal Dilution Of Precision | ||||||
|  |       streamSkipUntil(',');   // Vertical Dilution Of Precision | ||||||
|  |       streamSkipUntil('\n');  // TODO(?) is one more field reported?? | ||||||
|  |  | ||||||
|  |       waitResponse(); | ||||||
|  |  | ||||||
|  |       return true; | ||||||
|  |     } | ||||||
|  |     return false; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|   | |||||||
| @@ -170,8 +170,7 @@ class TinyGsmSim800 | |||||||
|  |  | ||||||
|     // Enable Local Time Stamp for getting network time |     // Enable Local Time Stamp for getting network time | ||||||
|     sendAT(GF("+CLTS=1")); |     sendAT(GF("+CLTS=1")); | ||||||
|     if (waitResponse(10000L) != 1) { return false; |     if (waitResponse(10000L) != 1) { return false; } | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // Enable battery checks |     // Enable battery checks | ||||||
|     sendAT(GF("+CBATCHK=1")); |     sendAT(GF("+CBATCHK=1")); | ||||||
| @@ -408,30 +407,10 @@ class TinyGsmSim800 | |||||||
|    * Location functions |    * Location functions | ||||||
|    */ |    */ | ||||||
|  protected: |  protected: | ||||||
|   // Can return a location from CIPGSMLOC as per the template |   // Depending on the exacty model and firmware revision, should return a | ||||||
|  |   // GSM-based location from CLBS as per the template | ||||||
|  |   // TODO(?):  Check number of digits in year (2 or 4) | ||||||
|  |  | ||||||
|   String getGsmLocation() { |  | ||||||
|     sendAT(GF("+CIPGSMLOC=1,1")); |  | ||||||
|     if (waitResponse(10000L, GF(GSM_NL "+CIPGSMLOC:")) != 1) { |  | ||||||
|       return ""; |  | ||||||
|     } |  | ||||||
|     String res = stream.readStringUntil('\n'); |  | ||||||
|     waitResponse(); |  | ||||||
|     res.trim(); |  | ||||||
|     return res; |  | ||||||
|   } |  | ||||||
|    |  | ||||||
|   String getBaseStationGsmLocation() { |  | ||||||
|     sendAT(GF("+CLBS=1,1")); |  | ||||||
|     if (waitResponse(10000L, GF(GSM_NL "+CLBS:")) != 1) { |  | ||||||
|       return ""; |  | ||||||
|     } |  | ||||||
|     String res = stream.readStringUntil('\n'); |  | ||||||
|     waitResponse(); |  | ||||||
|     res.trim(); |  | ||||||
|     return res; |  | ||||||
|   } |  | ||||||
|    |  | ||||||
|   /* |   /* | ||||||
|    * GPS location functions |    * GPS location functions | ||||||
|    */ |    */ | ||||||
|   | |||||||
| @@ -57,17 +57,45 @@ 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* vsat = 0, int* usat = 0, int* year = 0, int* month = 0, | ||||||
|     // String buffer = ""; |                   int* day = 0, int* hour = 0, int* minute = 0, | ||||||
|     // char chr_buffer[12]; |                   int* second = 0) { | ||||||
|     bool fix = false; |     bool fix = false; | ||||||
|  |  | ||||||
|     sendAT(GF("+CGNSINF")); |     sendAT(GF("+CGNSINF")); | ||||||
|     if (waitResponse(GF(GSM_NL "+CGNSINF:")) != 1) { return false; } |     if (waitResponse(GF(GSM_NL "+CGNSINF:")) != 1) { return false; } | ||||||
|  |  | ||||||
|     streamSkipUntil(',');                             // GNSS run status |     streamSkipUntil(',');                    // GNSS run status | ||||||
|     if (streamGetInt(',') == 1) fix = true;           // fix status |     if (streamGetInt(',') == 1) fix = true;  // fix status | ||||||
|     streamSkipUntil(',');                             // UTC date & Time |  | ||||||
|  |     // 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 |     *lat = streamGetFloat(',');                       // Latitude | ||||||
|     *lon = streamGetFloat(',');                       // Longitude |     *lon = streamGetFloat(',');                       // Longitude | ||||||
|     if (alt != NULL) *alt = streamGetFloat(',');      // MSL Altitude |     if (alt != NULL) *alt = streamGetFloat(',');      // MSL Altitude | ||||||
| @@ -91,51 +119,6 @@ class TinyGsmSim808 : public TinyGsmSim800, public TinyGsmGPS<TinyGsmSim808> { | |||||||
|  |  | ||||||
|     return fix; |     return fix; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // get GPS time |  | ||||||
|   // works only with SIM808 V2 |  | ||||||
|   bool getGPSTimeImpl(int* year, int* month, int* day, int* hour, int* minute, |  | ||||||
|                       int* second) { |  | ||||||
|     bool fix = false; |  | ||||||
|     char chr_buffer[12]; |  | ||||||
|     sendAT(GF("+CGNSINF")); |  | ||||||
|     if (waitResponse(GF(GSM_NL "+CGNSINF:")) != 1) { return false; } |  | ||||||
|  |  | ||||||
|     for (int i = 0; i < 3; i++) { |  | ||||||
|       String buffer = stream.readStringUntil(','); |  | ||||||
|       buffer.toCharArray(chr_buffer, sizeof(chr_buffer)); |  | ||||||
|       switch (i) { |  | ||||||
|         case 0: |  | ||||||
|           // mode |  | ||||||
|           break; |  | ||||||
|         case 1: |  | ||||||
|           // fixstatus |  | ||||||
|           if (buffer.toInt() == 1) { fix = buffer.toInt(); } |  | ||||||
|           break; |  | ||||||
|         case 2: |  | ||||||
|           *year   = buffer.substring(0, 4).toInt(); |  | ||||||
|           *month  = buffer.substring(4, 6).toInt(); |  | ||||||
|           *day    = buffer.substring(6, 8).toInt(); |  | ||||||
|           *hour   = buffer.substring(8, 10).toInt(); |  | ||||||
|           *minute = buffer.substring(10, 12).toInt(); |  | ||||||
|           *second = buffer.substring(12, 14).toInt(); |  | ||||||
|           break; |  | ||||||
|  |  | ||||||
|         default: |  | ||||||
|           // if nothing else matches, do the default |  | ||||||
|           // default is optional |  | ||||||
|           break; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     streamSkipUntil('\n'); |  | ||||||
|     waitResponse(); |  | ||||||
|  |  | ||||||
|     if (fix) { |  | ||||||
|       return true; |  | ||||||
|     } else { |  | ||||||
|       return false; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif  // SRC_TINYGSMCLIENTSIM808_H_ | #endif  // SRC_TINYGSMCLIENTSIM808_H_ | ||||||
|   | |||||||
| @@ -425,15 +425,96 @@ class TinyGsmSaraR4 | |||||||
|    * Location functions |    * Location functions | ||||||
|    */ |    */ | ||||||
|  protected: |  protected: | ||||||
|   String getGsmLocationImpl() { |   String getGsmLocationRawImpl() { | ||||||
|     sendAT(GF("+ULOC=2,3,0,120,1")); |     // AT+ULOC=<mode>,<sensor>,<response_type>,<timeout>,<accuracy> | ||||||
|     if (waitResponse(30000L, GF(GSM_NL "+UULOC:")) != 1) { return ""; } |     // <mode> - 2: single shot position | ||||||
|  |     // <sensor> - 2: use cellular CellLocate® location information | ||||||
|  |     // <response_type> - 0: standard (single-hypothesis) response | ||||||
|  |     // <timeout> - Timeout period in seconds | ||||||
|  |     // <accuracy> - Target accuracy in meters (1 - 999999) | ||||||
|  |     sendAT(GF("+ULOC=2,2,0,120,1")); | ||||||
|  |     // wait for first "OK" | ||||||
|  |     if (waitResponse(10000L) != 1) { return ""; } | ||||||
|  |     // wait for the final result - wait full timeout time | ||||||
|  |     if (waitResponse(120000L, GF(GSM_NL "+UULOC:")) != 1) { return ""; } | ||||||
|     String res = stream.readStringUntil('\n'); |     String res = stream.readStringUntil('\n'); | ||||||
|     waitResponse(); |     waitResponse(); | ||||||
|     res.trim(); |     res.trim(); | ||||||
|     return res; |     return res; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   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) { | ||||||
|  |     // AT+ULOC=<mode>,<sensor>,<response_type>,<timeout>,<accuracy> | ||||||
|  |     // <mode> - 2: single shot position | ||||||
|  |     // <sensor> - 2: use cellular CellLocate® location information | ||||||
|  |     // <response_type> - 0: standard (single-hypothesis) response | ||||||
|  |     // <timeout> - Timeout period in seconds | ||||||
|  |     // <accuracy> - Target accuracy in meters (1 - 999999) | ||||||
|  |     sendAT(GF("+ULOC=2,2,0,120,1")); | ||||||
|  |     // wait for first "OK" | ||||||
|  |     if (waitResponse(10000L) != 1) { return false; } | ||||||
|  |     // wait for the final result - wait full timeout time | ||||||
|  |     if (waitResponse(120000L, GF(GSM_NL "+UULOC:")) != 1) { return false; } | ||||||
|  |  | ||||||
|  |     // +UULOC: <date>, <time>, <lat>, <long>, <alt>, <uncertainty>, <speed>, | ||||||
|  |     // <direction>, <vertical_acc>, <sensor_used>, <SV_used>, <antenna_status>, | ||||||
|  |     // <jamming_status> | ||||||
|  |  | ||||||
|  |     // 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 (accuracy != NULL) { | ||||||
|  |       *accuracy = streamGetInt(','); | ||||||
|  |     }                      // Maximum possible error, in meters (0 - 20000000) | ||||||
|  |     streamSkipUntil(',');  // 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 | ||||||
|  |     streamSkipUntil(',');  // Number of satellite used to calculate the position | ||||||
|  |     streamSkipUntil(',');  // Antenna status | ||||||
|  |     streamSkipUntil('\n');  // Jamming status | ||||||
|  |  | ||||||
|  |     // final ok | ||||||
|  |     waitResponse(); | ||||||
|  |  | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * GPS location functions |    * GPS location functions | ||||||
|    */ |    */ | ||||||
|   | |||||||
| @@ -390,7 +390,7 @@ class TinyGsmUBLOX | |||||||
|    * Location functions |    * Location functions | ||||||
|    */ |    */ | ||||||
|  protected: |  protected: | ||||||
|   String getGsmLocationImpl() { |   String getGsmLocationRawImpl() { | ||||||
|     // 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 | ||||||
| @@ -408,6 +408,78 @@ class TinyGsmUBLOX | |||||||
|     return res; |     return res; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   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) { | ||||||
|  |     // AT+ULOC=<mode>,<sensor>,<response_type>,<timeout>,<accuracy> | ||||||
|  |     // <mode> - 2: single shot position | ||||||
|  |     // <sensor> - 2: use cellular CellLocate® location information | ||||||
|  |     // <response_type> - 0: standard (single-hypothesis) response | ||||||
|  |     // <timeout> - Timeout period in seconds | ||||||
|  |     // <accuracy> - Target accuracy in meters (1 - 999999) | ||||||
|  |     sendAT(GF("+ULOC=2,2,0,120,1")); | ||||||
|  |     // wait for first "OK" | ||||||
|  |     if (waitResponse(10000L) != 1) { return false; } | ||||||
|  |     // wait for the final result - wait full timeout time | ||||||
|  |     if (waitResponse(120000L, GF(GSM_NL "+UULOC:")) != 1) { return false; } | ||||||
|  |  | ||||||
|  |     // +UULOC: <date>, <time>, <lat>, <long>, <alt>, <uncertainty>, <speed>, | ||||||
|  |     // <direction>, <vertical_acc>, <sensor_used>, <SV_used>, <antenna_status>, | ||||||
|  |     // <jamming_status> | ||||||
|  |  | ||||||
|  |     // 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 (accuracy != NULL) { | ||||||
|  |       *accuracy = streamGetInt(','); | ||||||
|  |     }                      // Maximum possible error, in meters (0 - 20000000) | ||||||
|  |     streamSkipUntil(',');  // 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 | ||||||
|  |     streamSkipUntil(',');  // Number of satellite used to calculate the position | ||||||
|  |     streamSkipUntil(',');  // Antenna status | ||||||
|  |     streamSkipUntil('\n');  // Jamming status | ||||||
|  |  | ||||||
|  |     // final ok | ||||||
|  |     waitResponse(); | ||||||
|  |  | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * Time functions |    * Time functions | ||||||
|    */ |    */ | ||||||
|   | |||||||
| @@ -28,12 +28,18 @@ class TinyGsmGPS { | |||||||
|   String getGPSraw() { |   String getGPSraw() { | ||||||
|     return thisModem().getGPSrawImpl(); |     return thisModem().getGPSrawImpl(); | ||||||
|   } |   } | ||||||
|  |   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* day = 0, int* hour = 0, int* minute = 0, int* second = 0) { | ||||||
|  |     return thisModem().getGPSImpl(lat, lon, speed, alt, vsat, usat, 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) { | ||||||
|     return thisModem().getGPSTimeImpl(year, month, day, hour, minute, second); |     float lat = 0; | ||||||
|   } |     float lon = 0; | ||||||
|   bool getGPS(float* lat, float* lon, float* speed = 0, int* alt = 0) { |     return thisModem().getGPSImpl(lat, lon, 0, 0, 0, 0, year, month, day, hour, | ||||||
|     return thisModem().getGPSImpl(lat, lon, speed, alt); |                                   minute, second); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
| @@ -54,10 +60,10 @@ class TinyGsmGPS { | |||||||
|   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   getGPSTimeImpl(int* year, int* month, int* day, int* hour, int* minute, |   bool   getGPSImpl(float* lat, float* lon, float* speed = 0, int* alt = 0, | ||||||
|                         int* second) TINY_GSM_ATTR_NOT_IMPLEMENTED; |                     int* vsat = 0, int* usat = 0, int* year = 0, int* month = 0, | ||||||
|   bool   getGPSImpl(float* lat, float* lon, float* speed = 0, |                     int* day = 0, int* hour = 0, int* minute = 0, | ||||||
|                     int* alt = 0) TINY_GSM_ATTR_NOT_IMPLEMENTED; |                     int* second = 0) TINY_GSM_ATTR_NOT_IMPLEMENTED; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,8 +19,27 @@ class TinyGsmGSMLocation { | |||||||
|   /* |   /* | ||||||
|    * Location functions |    * Location functions | ||||||
|    */ |    */ | ||||||
|  |   String getGsmLocationRaw() { | ||||||
|  |     return thisModem().getGsmLocationRawImpl(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   String getGsmLocation() { |   String getGsmLocation() { | ||||||
|     return thisModem().getGsmLocationImpl(); |     return thisModem().getGsmLocationRawImpl(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   bool getGsmLocation(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 thisModem().getGsmLocationImpl(lat, lon, accuracy, year, month, day, | ||||||
|  |                                           hour, minute, second); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   bool getGsmLocationTime(int* year, int* month, int* day, int* hour, | ||||||
|  |                           int* minute, int* second) { | ||||||
|  |     float lat = 0; | ||||||
|  |     float lon = 0; | ||||||
|  |     return thisModem().getGsmLocation(lat, lon, 0, year, month, day, hour, | ||||||
|  |                                       minute, second); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
| @@ -36,16 +55,85 @@ class TinyGsmGSMLocation { | |||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * Location functions |    * Location functions | ||||||
|  |    * Template is based on SIMCOM commands | ||||||
|    */ |    */ | ||||||
|  protected: |  protected: | ||||||
|   String getGsmLocationImpl() { |   // String getGsmLocationImpl() { | ||||||
|     thisModem().sendAT(GF("+CIPGSMLOC=1,1")); |   //   thisModem().sendAT(GF("+CIPGSMLOC=1,1")); | ||||||
|     if (thisModem().waitResponse(10000L, GF("+CIPGSMLOC:")) != 1) { return ""; } |   //   if (thisModem().waitResponse(10000L, GF("+CIPGSMLOC:")) != 1) { return | ||||||
|  |   //   ""; } String res = thisModem().stream.readStringUntil('\n'); | ||||||
|  |   //   thisModem().waitResponse(); | ||||||
|  |   //   res.trim(); | ||||||
|  |   //   return res; | ||||||
|  |   // } | ||||||
|  |  | ||||||
|  |   String getGsmLocationRawImpl() { | ||||||
|  |     // AT+CLBS=<type>,<cid> | ||||||
|  |     // <type> 1 = location using 3 cell's information | ||||||
|  |     //        3 = get number of times location has been accessed | ||||||
|  |     //        4 = Get longitude latitude and date time | ||||||
|  |     thisModem().sendAT(GF("+CLBS=1,1")); | ||||||
|  |     // Should get a location code of "0" indicating success | ||||||
|  |     if (thisModem().waitResponse(120000L, GF("+CLBS:0,")) != 1) { return ""; } | ||||||
|     String res = thisModem().stream.readStringUntil('\n'); |     String res = thisModem().stream.readStringUntil('\n'); | ||||||
|     thisModem().waitResponse(); |     thisModem().waitResponse(); | ||||||
|     res.trim(); |     res.trim(); | ||||||
|     return res; |     return res; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   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) { | ||||||
|  |     // AT+CLBS=<type>,<cid> | ||||||
|  |     // <type> 1 = location using 3 cell's information | ||||||
|  |     //        3 = get number of times location has been accessed | ||||||
|  |     //        4 = Get longitude latitude and date time | ||||||
|  |     thisModem().sendAT(GF("+CLBS=4,1")); | ||||||
|  |     // Should get a location code of "0" indicating success | ||||||
|  |     if (thisModem().waitResponse(120000L, GF("+CLBS:0,")) != 1) { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     *lat = thisModem().streamGetFloat(',');  // Latitude | ||||||
|  |     *lon = thisModem().streamGetFloat(',');  // Longitude | ||||||
|  |     if (accuracy != NULL) | ||||||
|  |       *accuracy = 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 | ||||||
|  |  | ||||||
|  |     // Final OK | ||||||
|  |     thisModem().waitResponse(); | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif  // SRC_TINYGSMGSMLOCATION_H_ | #endif  // SRC_TINYGSMGSMLOCATION_H_ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user