From 45309cc02d17e47fe751637e5135071acffca6d0 Mon Sep 17 00:00:00 2001 From: Stanley Huang Date: Mon, 25 May 2015 15:05:42 +1000 Subject: Add GSM location API --- libraries/SIM800/SIM800.cpp | 56 ++++++++++++++++++------- libraries/SIM800/SIM800.h | 30 +++++++++++-- libraries/SIM800/examples/GPRSTest/GPRSTest.ino | 36 +++++++++------- 3 files changed, 89 insertions(+), 33 deletions(-) (limited to 'libraries') diff --git a/libraries/SIM800/SIM800.cpp b/libraries/SIM800/SIM800.cpp index 310d3ff..6f328c4 100644 --- a/libraries/SIM800/SIM800.cpp +++ b/libraries/SIM800/SIM800.cpp @@ -21,6 +21,7 @@ bool CGPRS_SIM800::init() if (sendCommand("AT")) { sendCommand("AT+IPR=115200"); sendCommand("ATE0"); + sendCommand("AT+CFUN=1", 10000); return true; } return false; @@ -61,9 +62,9 @@ byte CGPRS_SIM800::setup(const char* apn) if (!sendCommand(0)) return 4; - for (byte n = 0; n < 10 && !(success = (sendCommand("AT+SAPBR=1,1") != 0)); n++) - delay(500); - + sendCommand("AT+SAPBR=1,1", 10000); + sendCommand("AT+SAPBR=2,1", 10000); + if (!success) return 5; @@ -109,6 +110,33 @@ int CGPRS_SIM800::getSignalQuality() return 0; } } + +bool CGPRS_SIM800::getLocation(GSM_LOCATION* loc) +{ + if (sendCommand("AT+CIPGSMLOC=1,1", 10000)) do { + char *p; + if (!(p = strchr(buffer, ':'))) break; + if (!(p = strchr(p, ','))) break; + loc->lon = atof(++p); + if (!(p = strchr(p, ','))) break; + loc->lat = atof(++p); + if (!(p = strchr(p, ','))) break; + loc->year = atoi(++p) - 2000; + if (!(p = strchr(p, '/'))) break; + loc->month = atoi(++p); + if (!(p = strchr(p, '/'))) break; + loc->day = atoi(++p); + if (!(p = strchr(p, ','))) break; + loc->hour = atoi(++p); + if (!(p = strchr(p, ':'))) break; + loc->minute = atoi(++p); + if (!(p = strchr(p, ':'))) break; + loc->second = atoi(++p); + return true; + } while(0); + return false; +} + void CGPRS_SIM800::httpUninit() { sendCommand("AT+HTTPTERM"); @@ -139,8 +167,8 @@ bool CGPRS_SIM800::httpConnect(const char* url, const char* args) // Starts GET action simser.println("AT+HTTPACTION=0"); httpState = HTTP_CONNECTING; - bytesRecv = 0; - checkTimer = millis(); + m_bytesRecv = 0; + m_checkTimer = millis(); } else { httpState = HTTP_ERROR; } @@ -161,8 +189,8 @@ void CGPRS_SIM800::httpRead() { simser.println("AT+HTTPREAD"); httpState = HTTP_READING; - bytesRecv = 0; - checkTimer = millis(); + m_bytesRecv = 0; + m_checkTimer = millis(); } // check if HTTP connection is established // return 0 for in progress, -1 for error, number of http payload bytes on success @@ -170,7 +198,7 @@ int CGPRS_SIM800::httpIsRead() { byte ret = checkbuffer("+HTTPREAD: ", "Error", 10000) == 1; if (ret == 1) { - bytesRecv = 0; + m_bytesRecv = 0; // read the rest data sendCommand(0, 100, "\r\n"); int bytes = atoi(buffer); @@ -270,13 +298,13 @@ byte CGPRS_SIM800::checkbuffer(const char* expected1, const char* expected2, uns { while (simser.available()) { char c = simser.read(); - if (bytesRecv >= sizeof(buffer) - 1) { + if (m_bytesRecv >= sizeof(buffer) - 1) { // buffer full, discard first half - bytesRecv = sizeof(buffer) / 2 - 1; - memcpy(buffer, buffer + sizeof(buffer) / 2, bytesRecv); + m_bytesRecv = sizeof(buffer) / 2 - 1; + memcpy(buffer, buffer + sizeof(buffer) / 2, m_bytesRecv); } - buffer[bytesRecv++] = c; - buffer[bytesRecv] = 0; + buffer[m_bytesRecv++] = c; + buffer[m_bytesRecv] = 0; if (strstr(buffer, expected1)) { return 1; } @@ -284,7 +312,7 @@ byte CGPRS_SIM800::checkbuffer(const char* expected1, const char* expected2, uns return 2; } } - return (millis() - checkTimer < timeout) ? 0 : 3; + return (millis() - m_checkTimer < timeout) ? 0 : 3; } void CGPRS_SIM800::purgeSerial() diff --git a/libraries/SIM800/SIM800.h b/libraries/SIM800/SIM800.h index 9751302..c7de892 100644 --- a/libraries/SIM800/SIM800.h +++ b/libraries/SIM800/SIM800.h @@ -27,6 +27,17 @@ typedef enum { HTTP_ERROR, } HTTP_STATES; +typedef struct { + float lat; + float lon; + uint8_t year; /* year past 2000, e.g. 15 for 2015 */ + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t minute; + uint8_t second; +} GSM_LOCATION; + class CGPRS_SIM800 { public: CGPRS_SIM800():httpState(HTTP_DISABLED) {} @@ -35,18 +46,31 @@ public: bool getOperatorName(); bool checkSMS(); int getSignalQuality(); - void httpUninit(); + bool getLocation(GSM_LOCATION* loc); + // initialize HTTP connection bool httpInit(); + // terminate HTTP connection + void httpUninit(); + // connect to HTTP server bool httpConnect(const char* url, const char* args = 0); // check if HTTP connection is established // return 0 for in progress, 1 for success, 2 for error byte httpIsConnected(); + // read data from HTTP connection void httpRead(); // check if HTTP connection is established // return 0 for in progress, -1 for error, number of http payload bytes on success int httpIsRead(); + // send AT command and check for expected response byte sendCommand(const char* cmd, unsigned int timeout = 2000, const char* expected = 0); + // send AT command and check for two possible responses byte sendCommand(const char* cmd, const char* expected1, const char* expected2, unsigned int timeout = 2000); + // toggle low-power mode + bool sleep(bool enabled) + { + return sendCommand(enabled ? "AT+CFUN=0" : "AT+CFUN=1"); + } + // check if there is available serial data bool available() { return simser.available(); @@ -56,7 +80,7 @@ public: private: byte checkbuffer(const char* expected1, const char* expected2 = 0, unsigned int timeout = 2000); void purgeSerial(); - byte bytesRecv; - uint32_t checkTimer; + byte m_bytesRecv; + uint32_t m_checkTimer; }; diff --git a/libraries/SIM800/examples/GPRSTest/GPRSTest.ino b/libraries/SIM800/examples/GPRSTest/GPRSTest.ino index e752166..3555bbf 100644 --- a/libraries/SIM800/examples/GPRSTest/GPRSTest.ino +++ b/libraries/SIM800/examples/GPRSTest/GPRSTest.ino @@ -10,7 +10,6 @@ #define APN "connect" static const char* url = "http://arduinodev.com/datetime.php"; - CGPRS_SIM800 gprs; uint32_t count = 0; uint32_t errors = 0; @@ -50,17 +49,6 @@ void setup() con.print(ret); con.println("dB"); } - -#if 0 - sendCommand("AT+CSQ"); - lcd.println("Dialing..."); - if (sendCommand("ATD + +61402533012;", 10000)) { - lcd.println(buffer); - } - if (sendCommand("ATH")) - lcd.println(buffer); - delay(1000); -#endif gprs.sendCommand("AT+CMGF=1"); // sets the SMS mode to text gprs.sendCommand("AT+CPMS=\"SM\",\"SM\",\"SM\""); // selects the memory @@ -76,7 +64,6 @@ void setup() void loop() { - count++; char mydata[16]; sprintf(mydata, "t=%lu", millis()); @@ -85,6 +72,7 @@ void loop() con.print('?'); con.println(mydata); gprs.httpConnect(url, mydata); + count++; while (gprs.httpIsConnected() == 0) { // can do something here while waiting con.write('.'); @@ -93,26 +81,42 @@ void loop() } } if (gprs.httpState == HTTP_ERROR) { - con.println("error"); + con.println("Connect error"); errors++; delay(3000); return; } + con.println(); gprs.httpRead(); int ret; while ((ret = gprs.httpIsRead()) == 0) { // can do something here while waiting } if (gprs.httpState == HTTP_ERROR) { - con.println("error"); + con.println("Read error"); errors++; delay(3000); return; } // now we have received payload - con.print("\n[Payload]"); + con.print("[Payload]"); con.println(gprs.buffer); + + // show position + GSM_LOCATION loc; + if (gprs.getLocation(&loc)) { + con.print("LAT:"); + con.print(loc.lat, 6); + con.print(" LON:"); + con.print(loc.lon, 6); + con.print(" TIME:"); + con.print(loc.hour); + con.print(':'); + con.print(loc.minute); + con.print(':'); + con.println(loc.second); + } // show stats con.print("Total Requests:"); -- cgit v1.2.3