Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
10 years, 3 months ago.
Get timestamp via GPS
Is it possible to get the timestamp via GPS for the C27-G35-0?
I've tried it with another library like MODGPS, but it seems not to be fit for the C027. https://mbed.org/cookbook/MODGPS
Thank you for your help in advance.
Question relating to:
1 Answer
10 years, 3 months ago.
Fairly easy. Turn on the GPS and parse the Serial data you are getting.
Look for a line starting with "$GPRMC," and then pull out the time and date fields.
The format is (not actually code but tagged as code used to keep the spaces and new lines):
$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A Where: RMC Recommended Minimum sentence C 123519 Fix taken at 12:35:19 UTC A Status A=active or V=Void. 4807.038,N Latitude 48 deg 07.038' N 01131.000,E Longitude 11 deg 31.000' E 022.4 Speed over the ground in knots 084.4 Track angle in degrees True 230394 Date - 23rd of March 1994 003.1,W Magnetic Variation
See http://www.gpsinformation.org/dale/nmea.htm#nmea for more detail.
If you set an update rate faster than 1Hz then the time will have some decimal places for the fraction of the second e.g. 123519.100
Some fields may be blank or different lengths so count the commas to keep track of where you are in the line.
If you need more accurate time stamping then you need to use the PPS signal from the GPS. By first syncing to the GPS time and then increasing the PPS rate to 1kHz and counting pulses you can timestamp to the ms.
I've worked out this problem in two ways. See the second one under the comment "Alternative". However, you need a function that converts the timedate into a unix timestamp.
unsigned long unixTimestamp(int year, int month, int day, int hour, int min, int sec) { const short days_since_beginning_of_year[12] = {0,31,59,90,120,151,181,212,243,273,304,334}; int leap_years = ((year-1)-1968)/4 - ((year-1)-1900)/100 + ((year-1)-1600)/400; long days_since_1970 = (year-1970)*365 + leap_years + days_since_beginning_of_year[month-1] + day-1; if ( (month>2) && (year%4==0 && (year%100!=0 || year%400==0)) ) days_since_1970 += 1; /* +leap day, if year is a leap year */ return sec + 60 * ( min + 60 * (hour + 24*days_since_1970) ); } int main(void) { ... while ((ret = gps.getMessage(buf, sizeof(buf))) > 0) { int len = LENGTH(ret); //GET TIME & DATE if(strstr(buf,"$GPRMC")) { //GET TIME; char cGETtime[7]; char cGETdate[7]; memcpy( cGETtime, &buf[7], 6 ); cGETtime[6] = '\0'; int end = len; int pos = 14; int countcomma=1; // GET DATE while ( pos < end ) { if( buf[pos] == ',' ) countcomma++; if( countcomma == 9 ) { pos++; memcpy( cGETdate, &buf[pos], 6 ); cGETdate[6] = '\0'; break; } pos++; } struct tm settm; settm.tm_hour = 10 * (cGETtime[0] - '0') + cGETtime[1] - '0'; // '0' = 30; '1' = 31 => e.g. cGETtime[0]= '1' => '1'-'0' = 31-30 = 1 settm.tm_min = 10 * (cGETtime[2] - '0') + cGETtime[3] - '0'; settm.tm_sec = 10 * (cGETtime[4] - '0') + cGETtime[5] - '0'; settm.tm_mday = 10 * (cGETdate[0] - '0') + cGETdate[1] - '0'; settm.tm_mon = 10 * (cGETdate[2] - '0') + cGETdate[3] - '0' -1; //0-11 settm.tm_year = 10 * (cGETdate[4] - '0') + cGETdate[5] - '0'; settm.tm_isdst = -1; printf("Date: %02d:%02d:%02d %02d.%02d.%02d \r\n", settm.tm_hour, settm.tm_min,settm.tm_sec, settm.tm_mday, settm.tm_mon + 1, settm.tm_year); //----Alternative: GET TIME&DATE via getNmeaItem double dgetdate, dgettime; gps.getNmeaItem(9,buf,len,dgetdate); gps.getNmeaItem(1,buf,len,dgettime); printf("\r\n %f %f \r\n",dgetdate,dgettime); //---- //convert datetime to unix timestamp unsigned long ltime = unixTimestamp(settm.tm_year+2000,settm.tm_mon+1 ,settm.tm_mday, settm.tm_hour, settm.tm_min,settm.tm_sec); printf("timestamp: %u \r\n",ltime); } } ...