CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug Reports on this forum. Send them to support@ccsinfo.com

GPRMC GPS message decode

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
PICoHolic



Joined: 04 Jan 2005
Posts: 215

View user's profile Send private message

GPRMC GPS message decode
PostPosted: Tue Jul 12, 2011 5:44 am     Reply with quote

Code:

///////////////////////////////////////////////////////////////////////////////
#include <string.h>
#include <stdlib.h>
///////////////////////////////////////////////////////////////////////////////
typedef struct _DateTimeInfo
{
   int8 Day;
   int8 Month;
   int8 Year;
   int8 Hour;
   int8 Minute;
   int8 Second;
} DateTimeInfo;
////////////////////////////////////////
typedef struct _GPRMCInfo
{
   char Valid;
   DateTimeInfo DT;
   float Latitude;
   char N_S;
   float Longitude;
   char E_W;
   float Speed;
} GPRMCInfo;
///////////////////////////////////////////////////////////////////////////////
//copy string (pos n to pos m) from s2 to s1
char* StrnmCpy(char *s1, char *s2, size_t n, size_t m)
{
   int8 i;
   char *s;
   
   for (s=s1, i=n, s2+=n; i<=m; i++)
      *s++ = *s2++;
   *s = '\0';
   
   return s1;
}
///////////////////////////////////////////////////////////////////////////////
// find c in s starting from pos st
int8 StrFnd(char *s, char c, size_t st)
{
   int8 l;
   
   for (l=st, s+=st ; *s != '\0' ; l++, s++)
      if (*s == c)
         return l;
   return -1;
}
///////////////////////////////////////////////////////////////////////////////
void GPRMC_decode(char *GPRMCStr, GPRMCInfo *RMCInfo)
{
   int8 p1, p2;
   char TempStr[16];
   
   p1 = StrFnd(GPRMCStr, ',', 0);      //find first comma
   if (p1 == 6)
   {
      //check for valid packet:
      if ( (StrFnd(GPRMCStr, 'A', p1+1) == 18) && (GPRMCStr[0]=='$')) //valid?
      {
         RMCInfo->Valid = 'A';
         
         //Get time
         p1 = StrFnd(GPRMCStr, ',', 0);      //find first comma
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma
         RMCInfo->DT.Hour = atoi(StrnmCpy(TempStr, GPRMCStr, p1+1, p1+2));   //hour
         RMCInfo->DT.Minute = atoi(StrnmCpy(TempStr, GPRMCStr, p1+3, p1+4)); //min
         RMCInfo->DT.Second = atoi(StrnmCpy(TempStr, GPRMCStr, p1+5, p1+6)); //sec
         
         //Get latitude & direction
         p1 = StrFnd(GPRMCStr, ',', p2+1);   //find next comma
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma
         RMCInfo->Latitude = atof(StrnmCpy(TempStr, GPRMCStr, p1+1, p2-1));
         RMCInfo->N_S = GPRMCStr[p2+1];
         
         //Get longitude & direction
         p1 = StrFnd(GPRMCStr, ',', p2+1);   //find next comma
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma
         RMCInfo->Longitude = atof(StrnmCpy(TempStr, GPRMCStr, p1+1, p2-1));
         RMCInfo->E_W = GPRMCStr[p2+1];
         
         //Get speed
         p1 = StrFnd(GPRMCStr, ',', p2+1);   //find next comma
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma
         RMCInfo->Speed = atof(StrnmCpy(TempStr, GPRMCStr, p1+1, p2-1));
         
         //Get date
         p1 = StrFnd(GPRMCStr, ',', p2+1);   //find next comma
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma
         RMCInfo->DT.Day = atoi(StrnmCpy(TempStr, GPRMCStr, p1+1, p1+2));  //dd
         RMCInfo->DT.Month = atoi(StrnmCpy(TempStr, GPRMCStr, p1+3, p1+4));//mm
         RMCInfo->DT.year = atoi(StrnmCpy(TempStr, GPRMCStr, p1+5, p1+6)); //yy
      }
      else                                //not valid
      {
         RMCInfo->Valid = 'V';
      }
   }
}
///////////////////////////////////////////////////////////////////////////////
drx2k



Joined: 31 Mar 2010
Posts: 10

View user's profile Send private message

example
PostPosted: Sun Jun 03, 2012 11:59 pm     Reply with quote

how to use this code?
PICoHolic



Joined: 04 Jan 2005
Posts: 215

View user's profile Send private message

Usage
PostPosted: Thu Aug 02, 2012 5:27 am     Reply with quote

Interrupt routine for UART:

Code:

char GPSData[128];
unsigned int8 GPSDataPtr=0;
char c;
int8 GPSDataReady = FALSE;
int8 GPSmsgCount = 0;

#INT_RDA
void RDA_isr(void)
{
   c = getc();
   switch (c)
   {
      case '$':
         GPSDataPtr = 0;
      break;
     
      case '\n':
         GPSDataReady = TRUE;
      break;
   }
   
   GPSData[GPSDataPtr++ & 0x7F] = c;
     
}


Somewhere in main():
Code:

if (GPSDataReady)
      {
         GPRMC_decode(GPSData, &MyGPRMCInfo);
         if (MyGPRMCInfo.Valid == 'A')
         {
               #ifdef DEBUG_MODE
                     printf("\n\rTime: %d:%d:%d\n\r", MyGPRMCInfo.DT.Hour, MyGPRMCInfo.DT.Minute, MyGPRMCInfo.DT.Second);
                     printf("Date: %d/%d/%d\n\r", MyGPRMCInfo.DT.Day, MyGPRMCInfo.DT.Month, MyGPRMCInfo.DT.Year);
                     printf("Latitude: %f %c\n\r", MyGPRMCInfo.Latitude, MyGPRMCInfo.N_S);
                     printf("Longitude: %f %c\n\r", MyGPRMCInfo.Longitude, MyGPRMCInfo.E_W);
                     printf("Speed: %f knots\n\r", MyGPRMCInfo.Speed);
                     printf("Data saved!\n\r");
               #endif
         }
         GPSDataReady = FALSE;
      }
lan ahmad



Joined: 23 Jul 2012
Posts: 13

View user's profile Send private message

PostPosted: Sun Oct 07, 2012 11:23 am     Reply with quote

Undefined Indentifier MyGPRMCInfo?

what is MyGPRMCInfo?
PICoHolic



Joined: 04 Jan 2005
Posts: 215

View user's profile Send private message

PostPosted: Sun Oct 07, 2012 12:55 pm     Reply with quote

It's a variable of type GPRMCInfo (the structure above)
Code:
GPRMCInfo MyGPRMCInfo;
lan ahmad



Joined: 23 Jul 2012
Posts: 13

View user's profile Send private message

PostPosted: Fri Dec 14, 2012 10:58 am     Reply with quote

PICoHolic wrote:
It's a variable of type GPRMCInfo (the structure above)
Code:
GPRMCInfo MyGPRMCInfo;


how i can define it?where?
PICoHolic



Joined: 04 Jan 2005
Posts: 215

View user's profile Send private message

PostPosted: Sat Dec 15, 2012 3:37 am     Reply with quote

It's already defined above!!

Just declare it before you use it!
Jhonny



Joined: 30 Jan 2011
Posts: 16

View user's profile Send private message

PostPosted: Sun Feb 09, 2014 8:01 am     Reply with quote

PICoHolic wrote:
It's already defined above!!
Just declare it before you use it!


Dear Picoholic! Please describe for me exactly where and how to declare this "MyGPRMCInfo." The source would be great, but unfortunately, the compiler writes error:
"Undefined identifier MyGPRMCInfo" - Because of this, unfortunately can not use the code. (Please understand, I'm a beginner!) Thank you very much for your help! Embarassed
PICoHolic



Joined: 04 Jan 2005
Posts: 215

View user's profile Send private message

PostPosted: Sun Feb 09, 2014 12:52 pm     Reply with quote

I have already answered that. Scroll up.
Code:

GPRMCInfo MyGPRMCInfo;
PCM programmer



Joined: 06 Sep 2003
Posts: 20292

View user's profile Send private message

PostPosted: Sun Feb 09, 2014 1:31 pm     Reply with quote

He wants to know where to put the declaration. Since the demonstration
code above is said to be "somewhere in main", then he can put the
declaration at the start of main(). That's all he wants to know.
Code:
void main()
{
GPRMCInfo MyGPRMCInfo;

.
.
.


}
Jhonny



Joined: 30 Jan 2011
Posts: 16

View user's profile Send private message

PostPosted: Mon Feb 10, 2014 7:55 am     Reply with quote

Dear PCM programmer! That's right, you say! That's exactly what I wanted. Thank you very much for your help and for PICoHolic! Wink
PICoHolic



Joined: 04 Jan 2005
Posts: 215

View user's profile Send private message

PostPosted: Mon Feb 10, 2014 9:09 am     Reply with quote

Dear Jhonny, glad it works.

PS: in order to write a program in C for a microcontroller, a minimum knowledge in C language is required. Declaring a variable before using it is an extremely basic thing to know. Am I mistaken?

After all CCS forum is not a C language forum, it's a microcontroller programming forum using CCS C compiler. C language should be a prerequisite.

Cheers!
JAM2014



Joined: 24 Apr 2014
Posts: 87

View user's profile Send private message

PostPosted: Fri Jun 08, 2018 10:40 am     Reply with quote

Hi All,

Here is a modified version of PICoHolic's NMEA parsing routines that adds the NMEA checksum to the GPRMC structure.

Code:

///////////////////////////////////////////////////////////////////////////////
#include <string.h>
#include <stdlib.h>
///////////////////////////////////////////////////////////////////////////////
typedef struct _DateTimeInfo
{
   int8 Day;
   int8 Month;
   int8 Year;
   int8 Hour;
   int8 Minute;
   int8 Second;
} DateTimeInfo;
////////////////////////////////////////
typedef struct _GPRMCInfo
{
   char Valid;
   DateTimeInfo DT;
   float Latitude;
   char N_S;
   float Longitude;
   char E_W;
   float Speed;
   int8 Checksum;
} GPRMCInfo;
///////////////////////////////////////////////////////////////////////////////
//copy string (pos n to pos m) from s2 to s1
char* StrnmCpy(char *s1, char *s2, size_t n, size_t m)
{
   int8 i;
   char *s;
   
   for (s=s1, i=n, s2+=n; i<=m; i++)
      *s++ = *s2++;
   *s = '\0';
   
   return s1;
}
///////////////////////////////////////////////////////////////////////////////
// find c in s starting from pos st
int8 StrFnd(char *s, char c, size_t st)
{
   int8 l;
   
   for (l=st, s+=st ; *s != '\0' ; l++, s++)
      if (*s == c)
         return l;
   return -1;
}
///////////////////////////////////////////////////////////////////////////////
void GPRMC_decode(char *GPRMCStr, GPRMCInfo *RMCInfo)
{
   int8 p1, p2;
   int8 TempVal;
   char TempStr[16];
   
   p1 = StrFnd(GPRMCStr, ',', 0);      //find first comma
   if (p1 == 6)
   {
      //check for valid packet:
      if ( (StrFnd(GPRMCStr, 'A', p1+1) == 18) && (GPRMCStr[0]=='$')) //valid?
      {
         RMCInfo->Valid = 'A';
         
         //Get time
         p1 = StrFnd(GPRMCStr, ',', 0);      //find first comma
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma
         RMCInfo->DT.Hour = atoi(StrnmCpy(TempStr, GPRMCStr, p1+1, p1+2));   //hour
         RMCInfo->DT.Minute = atoi(StrnmCpy(TempStr, GPRMCStr, p1+3, p1+4)); //min
         RMCInfo->DT.Second = atoi(StrnmCpy(TempStr, GPRMCStr, p1+5, p1+6)); //sec
         
         //Get latitude & direction
         p1 = StrFnd(GPRMCStr, ',', p2+1);   //find next comma
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma
         RMCInfo->Latitude = atof(StrnmCpy(TempStr, GPRMCStr, p1+1, p2-1));
         RMCInfo->N_S = GPRMCStr[p2+1];
         
         //Get longitude & direction
         p1 = StrFnd(GPRMCStr, ',', p2+1);   //find next comma
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma
         RMCInfo->Longitude = atof(StrnmCpy(TempStr, GPRMCStr, p1+1, p2-1));
         RMCInfo->E_W = GPRMCStr[p2+1];
         
         //Get speed
         p1 = StrFnd(GPRMCStr, ',', p2+1);   //find next comma
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma
         RMCInfo->Speed = atof(StrnmCpy(TempStr, GPRMCStr, p1+1, p2-1));
         
         //Get date
         p1 = StrFnd(GPRMCStr, ',', p2+1);   //find next comma
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma
         RMCInfo->DT.Day = atoi(StrnmCpy(TempStr, GPRMCStr, p1+1, p1+2));  //dd
         RMCInfo->DT.Month = atoi(StrnmCpy(TempStr, GPRMCStr, p1+3, p1+4));//mm
         RMCInfo->DT.year = atoi(StrnmCpy(TempStr, GPRMCStr, p1+5, p1+6)); //yy

       //Get checksum
       p1 = StrFnd(GPRMCStr, '*', 0);   //find first asterisk
       TempStr[0]='0';
       TempStr[1]='x';
       StrnmCpy(TempStr+2, GPRMCStr, p1+1, p1+2);
       RMCInfo->Checksum = atoi(TempStr);
      }
      else                                //not valid
      {
         RMCInfo->Valid = 'V';
      }
   }
}
///////////////////////////////////////////////////////////////////////////////


Jack
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group