Browse Source

Redo GSM location and GPS stringlessly

Signed-off-by: Sara Damiano <sdamiano@stroudcenter.org>
v_master
Sara Damiano 5 years ago
parent
commit
3cc57881be
9 changed files with 409 additions and 179 deletions
  1. +10
    -0
      src/TinyGsmClientSIM5360.h
  2. +34
    -58
      src/TinyGsmClientSIM7000.h
  3. +64
    -29
      src/TinyGsmClientSIM7600.h
  4. +4
    -25
      src/TinyGsmClientSIM800.h
  5. +34
    -51
      src/TinyGsmClientSIM808.h
  6. +84
    -3
      src/TinyGsmClientSaraR4.h
  7. +73
    -1
      src/TinyGsmClientUBLOX.h
  8. +14
    -8
      src/TinyGsmGPS.tpp
  9. +92
    -4
      src/TinyGsmGSMLocation.tpp

+ 10
- 0
src/TinyGsmClientSIM5360.h View File

@ -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
*/ */


+ 34
- 58
src/TinyGsmClientSIM7000.h View File

@ -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) {
// String buffer = "";
int* vsat = 0, int* usat = 0, int* year = 0, int* month = 0,
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
if (streamGetInt(',') == 1) fix = true; // fix status
streamSkipUntil(','); // UTC date & Time
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 *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


+ 64
- 29
src/TinyGsmClientSIM7600.h View File

@ -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
if (streamGetInt(',') == 1)
fix = true; // TODO(?) Shouldn't this be 2=2D Fix or 3=3DFix?
streamSkipUntil(','); // GPS satellite valid numbers
streamSkipUntil(','); // GLONASS satellite valid numbers
streamSkipUntil(','); // BEIDOU satellite valid numbers
*lat = streamGetFloat(','); // Latitude
streamSkipUntil(','); // N/S Indicator, N=north or S=south
*lon = streamGetFloat(','); // Longitude
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??
uint8_t fixMode = streamGetInt(','); // mode 2=2D Fix or 3=3DFix
// TODO(?) Can 1 be returned
if (fixMode == 1 || fixMode == 2 || fixMode == 3) {
streamSkipUntil(','); // GPS satellite valid numbers
streamSkipUntil(','); // GLONASS satellite valid numbers
streamSkipUntil(','); // BEIDOU satellite valid numbers
*lat = streamGetFloat(','); // Latitude
streamSkipUntil(','); // N/S Indicator, N=north or S=south
*lon = streamGetFloat(','); // Longitude
streamSkipUntil(','); // E/W Indicator, E=east or W=west
// 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
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();
waitResponse();
return fix;
return true;
}
return false;
} }
/* /*


+ 4
- 25
src/TinyGsmClientSIM800.h View File

@ -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
*/ */


+ 34
- 51
src/TinyGsmClientSIM808.h View File

@ -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) {
// String buffer = "";
// char chr_buffer[12];
int* vsat = 0, int* usat = 0, int* year = 0, int* month = 0,
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
if (streamGetInt(',') == 1) fix = true; // fix status
streamSkipUntil(','); // UTC date & Time
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 *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_

+ 84
- 3
src/TinyGsmClientSaraR4.h View File

@ -425,15 +425,96 @@ class TinyGsmSaraR4
* Location functions * Location functions
*/ */
protected: protected:
String getGsmLocationImpl() {
sendAT(GF("+ULOC=2,3,0,120,1"));
if (waitResponse(30000L, GF(GSM_NL "+UULOC:")) != 1) { return ""; }
String getGsmLocationRawImpl() {
// 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 ""; }
// 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
*/ */


+ 73
- 1
src/TinyGsmClientUBLOX.h View File

@ -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
*/ */


+ 14
- 8
src/TinyGsmGPS.tpp View File

@ -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);
}
bool getGPS(float* lat, float* lon, float* speed = 0, int* alt = 0) {
return thisModem().getGPSImpl(lat, lon, speed, alt);
float lat = 0;
float lon = 0;
return thisModem().getGPSImpl(lat, lon, 0, 0, 0, 0, year, month, day, hour,
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,
int* second) TINY_GSM_ATTR_NOT_IMPLEMENTED;
bool getGPSImpl(float* lat, float* lon, float* speed = 0,
int* alt = 0) TINY_GSM_ATTR_NOT_IMPLEMENTED;
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) TINY_GSM_ATTR_NOT_IMPLEMENTED;
}; };


+ 92
- 4
src/TinyGsmGSMLocation.tpp View File

@ -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() {
thisModem().sendAT(GF("+CIPGSMLOC=1,1"));
if (thisModem().waitResponse(10000L, GF("+CIPGSMLOC:")) != 1) { return ""; }
// String getGsmLocationImpl() {
// thisModem().sendAT(GF("+CIPGSMLOC=1,1"));
// 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_

Loading…
Cancel
Save