diff --git a/DFRobot_sim808.cpp b/DFRobot_sim808.cpp index d052e62..1150f5a 100644 --- a/DFRobot_sim808.cpp +++ b/DFRobot_sim808.cpp @@ -57,7 +57,7 @@ DFRobot_SIM808::DFRobot_SIM808(SoftwareSerial *mySerial) sim808_init(mySerial, 0); } -bool DFRobot_SIM808::init(void) +bool DFRobot_SIM808::init(boolean simcheck) { //閿熸枻鎷烽敓绱窽鎸囬敓鏂ゆ嫹閿熻鍑ゆ嫹閿熸枻鎷锋晥 if(!sim808_check_with_cmd("AT\r\n","OK\r\n",CMD)){ @@ -72,7 +72,7 @@ bool DFRobot_SIM808::init(void) } //閿熸枻鎷烽敓绲奍M閿熸枻鎷风姸鎬� - if(!checkSIMStatus()) { + if(simcheck && !checkSIMStatus()) { return false; } return true; @@ -894,14 +894,26 @@ bool DFRobot_SIM808::getLocation(const __FlashStringHelper *apn, float *longitud return false; } +bool DFRobot_SIM808::setTestGPS(bool test) { + + if (test) { + if(!sim808_check_with_cmd("AT+CGNSTST=1\r\n", "OK\r\n", CMD)) { + return false; + } + } else { + if(!sim808_check_with_cmd("AT+CGNSTST=0\r\n", "OK\r\n", CMD)) { + return false; + } + } + return true; +} + bool DFRobot_SIM808::attachGPS() { if(!sim808_check_with_cmd("AT+CGNSPWR=1\r\n", "OK\r\n", CMD)) { return false; } - if(!sim808_check_with_cmd("AT+CGNSTST=1\r\n", "OK\r\n", CMD)) { - return false; - } + return true; } @@ -1012,9 +1024,122 @@ int32_t DFRobot_SIM808::parseDecimal(const char *term) GPSdata.month = (date / 100) % 100; GPSdata.day = date / 10000; } + +char *DFRobot_SIM808::strtok_new(char * string, char const * delimiter){ + static char *source = NULL; + char *p, *riturn = 0; + if(string != NULL) source = string; + if(source == NULL) return NULL; + + if((p = strpbrk (source, delimiter)) != NULL) { + *p = 0; + riturn = source; + source = ++p; + } +return riturn; +} + +bool DFRobot_SIM808::getGPS() { + + + // +CGNSINF: ,, ,,, + // ,, , ,, + // ,, ,,, , + // ,,,, + char temp[sizeof(cgnsinf)]; + + sim808_send_cmd("AT+CGNSINF\r\n"); + sim808_read_buffer(temp, sizeof(cgnsinf)-1); + temp[sizeof(temp)-1] = '\0'; + + strncpy(cgnsinf, temp, sizeof(temp)); + + char *tok; + + if((tok=strstr(temp,"+CGNSINF:")) == NULL) + return false; // not expected response + + strncpy(cgnsinf, tok, sizeof(temp)); + + tok = strtok_new(tok, ","); + if (! tok) return false; + + char *status = strtok_new(NULL, ","); + if (! status) return false; + + + + char *datetime = strtok_new(NULL, ","); + if (! datetime) return false; + char date[5]; + memset(date,0,strlen(date)); + strncpy(date, datetime, 4); + GPSdata. year = atoi(date); + memset(date,0,strlen(date)); + strncpy(date, datetime+4, 2); + GPSdata.month = atoi(date); + memset(date,0,strlen(date)); + strncpy(date, datetime+6, 2); + GPSdata.day = atoi(date); + + uint32_t newTime = (uint32_t)parseDecimal(datetime + 8); + getTime(newTime); + + char *lat = strtok_new(NULL, ","); + if (! lat) return false; + GPSdata.lat = atof(lat); + + char *lon = strtok_new(NULL, ","); + if (! lon) return false; + GPSdata.lon = atof(lon); + + char *alt = strtok_new(NULL, ","); + if (! alt) return false; + GPSdata.altitude = atof(alt); + + char *speed = strtok_new(NULL, ","); + if (! speed) return false; + GPSdata.speed_kph = atof(speed)* 1.852; + + char *heading = strtok_new(NULL, ","); + if (! heading) return false; + GPSdata.heading = atof(heading); + + // skip + strtok_new(NULL, ","); strtok_new(NULL, ","); + + char *hdop = strtok_new(NULL, ","); + if (! hdop) return false; + GPSStatus.horizontal_pres = atof(hdop); + + char *pdop = strtok_new(NULL, ","); + if (! pdop) return false; + GPSStatus.position_pres = atof(pdop); + + char *vdop = strtok_new(NULL, ","); + if (! vdop) return false; + GPSStatus.vertical_pres = atof(vdop); + + // skip + strtok_new(NULL, ","); + + char *sat_in_view = strtok_new(NULL, ","); + if (! sat_in_view) return false; + GPSStatus.sat_in_view = atoi(sat_in_view); + + char *sat_used = strtok_new(NULL, ","); + if (! sat_used) return false; + GPSStatus.sat_used = atoi(sat_used); + + char *sat_glonass = strtok_new(NULL, ","); + if (! sat_glonass) return false; + GPSStatus.sat_glonass = atof(sat_glonass); + + + return true; +} - -bool DFRobot_SIM808::getGPS() +bool DFRobot_SIM808::getGPSTestData() { if(!getGPRMC()) //没有得到$GPRMC字符串开头的GPS信息 return false; @@ -1056,10 +1181,10 @@ bool DFRobot_SIM808::getGPS() float latitude = atof(latp); float longitude = atof(longp); - GPSdata.lat = latitude/100; + GPSdata.lat = latitude; // convert longitude from minutes to decimal - GPSdata.lon= longitude/100; + GPSdata.lon= longitude; // only grab speed if needed //<7> 地面速率(000.0~999.9节,前面的0也将被传输) // if (speed_kph != NULL) { @@ -1104,7 +1229,10 @@ void DFRobot_SIM808::latitudeConverToDMS() latDMS.degrees = (int)GPSdata.lat; temp = (GPSdata.lat - latDMS.degrees)*60; latDMS.minutes = (int)temp; - latDMS.seconeds = (temp - latDMS.minutes)*60; + latDMS.seconds = (temp - latDMS.minutes)*60; + if (latDMS.minutes < 0) latDMS.minutes = -latDMS.minutes; + if (latDMS.seconds < 0) latDMS.seconds = -latDMS.seconds; + } void DFRobot_SIM808::LongitudeConverToDMS() @@ -1113,6 +1241,8 @@ void DFRobot_SIM808::LongitudeConverToDMS() longDMS.degrees = (int)GPSdata.lon; temp = (GPSdata.lon - longDMS.degrees)*60; longDMS.minutes = (int)temp; - longDMS.seconeds = (temp - longDMS.minutes)*60; + longDMS.seconds = (temp - longDMS.minutes)*60; + if (longDMS.minutes < 0) longDMS.minutes = -longDMS.minutes; + if (longDMS.seconds < 0) longDMS.seconds = -longDMS.seconds; } diff --git a/DFRobot_sim808.h b/DFRobot_sim808.h index e3e8382..def3a6d 100644 --- a/DFRobot_sim808.h +++ b/DFRobot_sim808.h @@ -64,10 +64,11 @@ class DFRobot_SIM808 * @return true if connected, false otherwise */ - bool init(void); + bool init(boolean simcheck = true); /** check if DFRobot_SIM808 module is powered on or not + * @param simcheck checks if SIM is OK, (GPS works without SIM) * @returns * true on success * false on error @@ -326,7 +327,10 @@ class DFRobot_SIM808 //Open or Close GPS bool attachGPS(); bool detachGPS(); - + bool getGPS(); + + // set GPS test node + bool setTestGPS(bool test); // Parse a (potentially negative) number with up to 2 decimal digits -xxxx.yy void getTime(uint32_t time); @@ -340,7 +344,7 @@ class DFRobot_SIM808 bool getGPRMC(); //get GPS signal - bool getGPS(); + bool getGPSTestData(); SoftwareSerial *gprsSerial; @@ -361,20 +365,34 @@ class DFRobot_SIM808 float speed_kph; float heading; float altitude; - }GPSdata; + } GPSdata; + + struct gspstatus { + uint8_t status; + uint8_t sat_in_view; + uint8_t sat_used; + uint8_t sat_glonass; + //,, + float horizontal_pres; + float position_pres; + float vertical_pres; + } GPSStatus; struct DMSData{ int degrees; int minutes; - float seconeds; + float seconds; }latDMS,longDMS; + char cgnsinf[128]; private: + byte serialFlag; bool checkSIMStatus(void); uint32_t str_to_ip(const char* str); static DFRobot_SIM808* inst; uint32_t _ip; char ip_string[16]; //XXX.YYY.ZZZ.WWW + \0 + char *strtok_new(char * string, char const * delimiter); }; #endif diff --git a/SIM808_QueryGPS/SIM808_QueryGPS.ino b/SIM808_QueryGPS/SIM808_QueryGPS.ino new file mode 100644 index 0000000..e3e4b71 --- /dev/null +++ b/SIM808_QueryGPS/SIM808_QueryGPS.ino @@ -0,0 +1,115 @@ +/* +### Get GPS data +1. This example is used to test SIM808 GPS/GPRS/GSM Shield's reading GPS data. +2. Open the SIM808_GetGPS example or copy these code to your project +3. Download and dial the function switch to Arduino +4. open serial helper +4. Place it outside, waiting for a few minutes and then it will send GPS data to serial + +create on 2016/09/23, version: 1.0 +by jason + +*/ +#include +#include + +// Arduino Uno Wifi Rev2 +#define PIN_TX 1 +#define PIN_RX 0 +SoftwareSerial simSerial(PIN_TX,PIN_RX); +DFRobot_SIM808 sim808(&simSerial);//Connect RX,TX,PWR, + +//DFRobot_SIM808 sim808(&Serial); + +void setup() { + // Arduino Uno Wifi Rev2 has a hardware Serial + // and talks to the dfrobot board using digital pins 0,1 + simSerial.begin(9600); + Serial.begin(9600); + + //******** Initialize sim808 module ************* + while(!sim808.init(false)) { + delay(1000); + Serial.print("Sim808 init error\r\n"); + } + + //************* Turn on the GPS power************ + if( sim808.attachGPS()) + Serial.println("Open the GPS power success"); + else + Serial.println("Open the GPS power failure"); + +} + +void loop() { + Serial.println("\n\n"); + //************** Get GPS data ******************* + + if (sim808.getGPS()) { + Serial.print(sim808.GPSdata.year); + Serial.print("/"); + Serial.print(sim808.GPSdata.month); + Serial.print("/"); + Serial.print(sim808.GPSdata.day); + Serial.print(" "); + Serial.print(sim808.GPSdata.hour); + Serial.print(":"); + Serial.print(sim808.GPSdata.minute); + Serial.print(":"); + Serial.print(sim808.GPSdata.second); + Serial.print(":"); + Serial.println(sim808.GPSdata.centisecond); + + Serial.print("latitude :"); + Serial.println(sim808.GPSdata.lat,6); + + sim808.latitudeConverToDMS(); + Serial.print("latitude :"); + Serial.print(sim808.latDMS.degrees); + Serial.print(167); + Serial.print(sim808.latDMS.minutes); + Serial.print("\'"); + Serial.print(sim808.latDMS.seconds,6); + Serial.println("\""); + Serial.print("longitude :"); + Serial.println(sim808.GPSdata.lon,6); + sim808.LongitudeConverToDMS(); + Serial.print("longitude :"); + Serial.print(sim808.longDMS.degrees); + Serial.print(167); + Serial.print(sim808.longDMS.minutes); + Serial.print("\'"); + Serial.print(sim808.longDMS.seconds,6); + Serial.println("\""); + + Serial.print("speed_kph :"); + Serial.println(sim808.GPSdata.speed_kph); + Serial.print("heading :"); + Serial.println(sim808.GPSdata.heading); + + Serial.print("pressions (h,v,p):"); + Serial.print(sim808.GPSStatus.horizontal_pres); + Serial.print(","); + Serial.print(sim808.GPSStatus.vertical_pres); + Serial.print(","); + Serial.println(sim808.GPSStatus.position_pres); + + Serial.print("satellites (inview, used, Glonass):"); + Serial.print(sim808.GPSStatus.sat_in_view); + Serial.print(","); + Serial.print(sim808.GPSStatus.sat_used); + Serial.print(","); + Serial.println(sim808.GPSStatus.sat_glonass); + + Serial.print("CGNSINF:"); + for (int i=0; i < sizeof(sim808.cgnsinf)-1; i++) { + if (sim808.cgnsinf[i]<32) sim808.cgnsinf[i] = ' '; + } + Serial.println(sim808.cgnsinf); + + } else { + Serial.println("getGPS failed"); + delay(1000); + } + +}