Skip to main content
antonius
Associate III
April 30, 2019
Question

GPRMC date ?

  • April 30, 2019
  • 7 replies
  • 2430 views

Dear Member

I tried to get date from GPRMC, but not getting any response:

code :

sscanf(str,"$GPRMC,%s,%2hhd%2hhd%2hhd,%c,%f,%c,%f,%c,%f,%c,%f,%f,%2hhd%2hhd%2hhd,%f,%c,%c,*%2s\r\n",&GPS.GPRMC.xxRMC,&GPS.GPRMC.UTC_Hour,&GPS.GPRMC.UTC_Min,&GPS.GPRMC.UTC_Sec,&GPS.GPRMC.status,&GPS.GPRMC.Latitude,&GPS.GPRMC.NS_Indicator,&GPS.GPRMC.Longitude,&GPS.GPRMC.EW_Indicator,&GPS.GPRMC.spd,&GPS.GPRMC.cog,&GPS.GPRMC.UTC_Day,&GPS.GPRMC.UTC_Month,&GPS.GPRMC.UTC_Year,&GPS.GPRMC.mv,&GPS.GPRMC.mvEW,&GPS.GPRMC.posMode,&GPS.GPRMC.CheckSum);

Am I missing something here ?

Thanks

    This topic has been closed for replies.

    7 replies

    Tesla DeLorean
    Guru
    April 30, 2019

    What does sscanf() actually return?

    You're going to need to debug your own code.

    Suggest you test on a PC, where you feed it test strings, prove that works.

    Make sure the compiler/library you are using supports sscanf() properly.

    The use of 32-bit floats for latitude/longitude is not advisable.

    I probably would not parse it this way, NMEA can have empty fields and variable formatting.

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    antonius
    antoniusAuthor
    Associate III
    May 1, 2019

    I got :

    $GPRMC,112421.00,A,3208.00557,S,11559.30809,E,0.060,,010519,,,A*67

    I try to print it

    the code :

    str=strstr((char*)GPS.rxBuffer,"$GPRMC,");
    		if(str!=NULL)
    		{
    				memset(&GPS.GPRMC,0,sizeof(GPS.GPRMC)); //for the date page 55 u-blox6-GPS-GLONASS----
    			sscanf(str,"$GPRMC,%2hhd%2hhd%2hhd.%3hd,%c,%f,%c,%f,%c,%f,%f,%2u%2u%2u,%f,%c,%c,*%2s\r\n",
    			&GPS.GPRMC.UTC_Hour,&GPS.GPRMC.UTC_Min,&GPS.GPRMC.UTC_Sec,&GPS.GPRMC.UTC_MicroSec,
    			&GPS.GPRMC.status,&GPS.GPRMC.Latitude,&GPS.GPRMC.NS_Indicator,&GPS.GPRMC.Longitude,
    			&GPS.GPRMC.EW_Indicator,&GPS.GPRMC.spd,&GPS.GPRMC.cog,&GPS.GPRMC.UTC_Day,
    			&GPS.GPRMC.UTC_Month,&GPS.GPRMC.UTC_Year,&GPS.GPRMC.mv,&GPS.GPRMC.mvEW,
    			&GPS.GPRMC.posMode,&GPS.GPRMC.CheckSum);
    			
     printf(str);printf("\r\n");
    			printf("======================GPRMC PARSING =================\r\n");
    			printf("Course over ground value: %lf degree \r\n",GPS.GPRMC.cog);
    			printf("Date : %2u-%2u-%2u \r\n",GPS.GPRMC.UTC_Day,GPS.GPRMC.UTC_Month,GPS.GPRMC.UTC_Year);
    			printf("====================== D O N E !=================\r\n");
    		}

    but I got 0-0-0 on date value,

    What's missing here ??

    Thanks

    Tesla DeLorean
    Guru
    May 1, 2019

    How many fields does sscanf() report successfully parsing?

    Does it support the format methods you're using?

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    antonius
    antoniusAuthor
    Associate III
    May 2, 2019

    it works well on this :

    if( (HAL_GetTick()-GPS.LastTime>50) && (GPS.rxIndex>0))

       {

          char   *str,*str2;

          #if (_GPS_DEBUG==1)

          printf("%s",GPS.rxBuffer);

          #endif

          str=strstr((char*)GPS.rxBuffer,"$GPGGA,");

          if(str!=NULL)

          {

             memset(&GPS.GPGGA,0,sizeof(GPS.GPGGA));

             sscanf(str,"$GPGGA,%2hhd%2hhd%2hhd.%3hd,%f,%c,%f,%c,%hhd,%hhd,%f,%f,%c,%hd,%s,*%2s\r\n",&GPS.GPGGA.UTC_Hour,&GPS.GPGGA.UTC_Min,&GPS.GPGGA.UTC_Sec,&GPS.GPGGA.UTC_MicroSec,&GPS.GPGGA.Latitude,&GPS.GPGGA.NS_Indicator,&GPS.GPGGA.Longitude,&GPS.GPGGA.EW_Indicator,&GPS.GPGGA.PositionFixIndicator,&GPS.GPGGA.SatellitesUsed,&GPS.GPGGA.HDOP,&GPS.GPGGA.MSL_Altitude,&GPS.GPGGA.MSL_Units,&GPS.GPGGA.AgeofDiffCorr,GPS.GPGGA.DiffRefStationID,GPS.GPGGA.CheckSum);

    .................

       memset(&GPS.GPVTG,0,sizeof(GPS.GPVTG));

             sscanf(str,"$GPVTG,%f,%c,%f,%c,%f,%c,%f,%c,%f,*%2s\r\n",

             &GPS.GPVTG.cogt,&GPS.GPVTG.T,&GPS.GPVTG.cogm,&GPS.GPVTG.M,

             &GPS.GPVTG.knots,&GPS.GPVTG.N,&GPS.GPVTG.kph,&GPS.GPVTG.K,

             &GPS.GPVTG.posMode,&GPS.GPVTG.CheckSum);

           printf(str);printf("\r\n");

         printf("======================GPVTG PARSING =================\r\n");

             printf("Course over ground value: %f degree \r\n",GPS.GPVTG.cogt);

             printf("Speed in km/h          : %f km/h \r\n",GPS.GPVTG.kph);

             printf("====================== D O N E !=================\r\n");

    }

    it doesn't work with the bold area.... is it related with ==> if( (HAL_GetTick()-GPS.LastTime>50) && (GPS.rxIndex>0))) ?

    or I can not use sscanf with those many fields ??

    Thanks

    antonius
    antoniusAuthor
    Associate III
    May 1, 2019

    Perhaps, my stack is not enough ?

    antonius
    antoniusAuthor
    Associate III
    May 1, 2019
    typedef struct
    {
     
    	
    	uint8_t			UTC_Hour;
    	uint8_t			UTC_Min;
    	uint8_t			UTC_Sec;
    	uint16_t		UTC_MicroSec;
    	
    	char status;
     float Latitude;
    	double			LatitudeDecimal;
    	char				NS_Indicator;
    	float				Longitude;
    	double			LongitudeDecimal;
    	char				EW_Indicator;
    	float spd;
     float cog;
    	
    	int			UTC_Day;
    	int			UTC_Month;
    	int			UTC_Year;
    	
    	float mv;
    	char mvEW;
    	char posMode;
    	
     char				CheckSum[2];	
    	
    }GPRMC_t;

    antonius
    antoniusAuthor
    Associate III
    May 3, 2019

    I got from printf on line 10

    $GPVTG,,T,,M,0.074,N,0.138,K,A*2A
     
    $GPGGA,070050.00,3208.00548,S,11559.30824,E,1,10,0.82,36.0,M,-30.6,M,,*51
     
    $GPGSA,A,3,23,26,06,09,22,01,03,16,19,07,,,1.52,0.82,1.28*05
     
    $GPGSV,5,1,17,01,21,009,23,02,01,214,,03,52,084,37,04,40,264,31*7B
     
    $GPGSV,5,2,17,06,33,233,35,07,40,341,25,09,54,244,28,11,04,005,*79
     
    $GPGSV,5,3,17,16,15,089,12,17,06,297,,19,09,273,27,22,32,066,32*76
     
    $GPGSV,5,4,17,23,60,164,35,26,12,117,21,30,09,332,19,42,41,046,*7E
     
    $GPGSV,5,5,17,50,41,046,*4D
     
    $GPGLL,3208.00548,S,11559.30824,E,070050.00,A,A*72
     
    $GPRMC,070051.00,A,3208.00541,S,11559.30818,E,0.146,,030519,,,A*61
     
    $GPVTG,,T,,M,0.146,N,0.271,K,A*24
     
    $GPGGA,070051.00,3208.00541,S,11559.30818,E,1,10,0.82,36.1,M,-30.6,M,,
     

    antonius
    antoniusAuthor
    Associate III
    May 3, 2019

    This what I got from function ProcessNMEALine((char*)GPS.rxBuffer)

    DecodeNMEA
     
    $GPRMC,074341.00,A,3208.00668,S,11559.30844,E,0.029,,030519,,,A*6E
     
    $GPVTG,,T,,M,0.029,N,0.055,K,A*28
     
    $GPGGA,074341.00,3208.00668,S,11559.30844,E,1,10,0.79,32.5,M,-30.6,M,,*54
     
    $GPGSA,A,3,23,02,26,06,09,22,03,16,07,30,,,1.46,0.79,1.23*07
     
    $GPGSV,4,1,15,01,03,012,,02,14,225,25,03,38,061,31,04,50,239,31*7A
     
    $GPGSV,4,2,15,06,41,255,36,07,62,333,32,09,60,209,42,16,20,108,28*7A
     
    $GPGSV,4,3,15,19,00,290,,22,17,053,20,23,49,137,35,26,09,134,20*7D
     
    $GPGSV,4,4,15,30,27,326,37,42,41,046,,50,41,046,*4B
     
    $GPGLL,3208.00668,S,11559.30844,E,074341.00,A,A*72
     
    $GPRMC,074342.00,A,3208.00667,S,11559.30843,E,0.057,,030519,,,A*6C
     
    $GPVTG,,T,,M,0.057,N,0.106,K,A*26
     
    $GPGGA,074342.00,3208.00667,S,11559.30843,E,1,10,0.79,32.6,M,-30.6,M,,*5C
     
    $GPGSA,A,3,23,02,26,06,09,22,03,16,07
     
    Fields 13
     
    #00 : $GPRMC
     
    #01 : 074341.00
     
    #02 : A
     
    #03 : 3208.00668
     
    #04 : S
     
    #05 : 11559.30844
     
    #06 : E
     
    #07 : 0.029
     
    #08 : 
     
    #09 : 030519
     
    #10 : 
     
    #11 : 
     
    #12 : A
     
     

    Vangelis Fortounas
    Associate II
    May 3, 2019

    Hi,

    scanf works for fixed length and format messages.

    Depending on sentence validity or fix validity or state (A or V , 2D,3D,etc) the sentences may change length by omitting fields and change signs.

    Also for different versions of NMEA output the decimal part of Latitude and Longitude can vary from 2 to 5 digits.

    An option is to feed raw data to a State Machine and by byte per byte process to extract Talker, Command, Data fields, Checksum or other proprietary data. Using an atoi function can convert arithmetical fields to numbers.