|
|
View previous topic :: View next topic |
Author |
Message |
PICoHolic
Joined: 04 Jan 2005 Posts: 224
|
GPRMC GPS message decode |
Posted: Tue Jul 12, 2011 5:44 am |
|
|
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
|
example |
Posted: Sun Jun 03, 2012 11:59 pm |
|
|
how to use this code? |
|
|
PICoHolic
Joined: 04 Jan 2005 Posts: 224
|
Usage |
Posted: Thu Aug 02, 2012 5:27 am |
|
|
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
|
|
Posted: Sun Oct 07, 2012 11:23 am |
|
|
Undefined Indentifier MyGPRMCInfo?
what is MyGPRMCInfo? |
|
|
PICoHolic
Joined: 04 Jan 2005 Posts: 224
|
|
Posted: Sun Oct 07, 2012 12:55 pm |
|
|
It's a variable of type GPRMCInfo (the structure above)
Code: | GPRMCInfo MyGPRMCInfo; |
|
|
|
lan ahmad
Joined: 23 Jul 2012 Posts: 13
|
|
Posted: Fri Dec 14, 2012 10:58 am |
|
|
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: 224
|
|
Posted: Sat Dec 15, 2012 3:37 am |
|
|
It's already defined above!!
Just declare it before you use it! |
|
|
Jhonny
Joined: 30 Jan 2011 Posts: 16
|
|
Posted: Sun Feb 09, 2014 8:01 am |
|
|
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! |
|
|
PICoHolic
Joined: 04 Jan 2005 Posts: 224
|
|
Posted: Sun Feb 09, 2014 12:52 pm |
|
|
I have already answered that. Scroll up.
Code: |
GPRMCInfo MyGPRMCInfo;
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Feb 09, 2014 1:31 pm |
|
|
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
|
|
Posted: Mon Feb 10, 2014 7:55 am |
|
|
Dear PCM programmer! That's right, you say! That's exactly what I wanted. Thank you very much for your help and for PICoHolic! |
|
|
PICoHolic
Joined: 04 Jan 2005 Posts: 224
|
|
Posted: Mon Feb 10, 2014 9:09 am |
|
|
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: 138
|
|
Posted: Fri Jun 08, 2018 10:40 am |
|
|
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 |
|
|
|
|
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
|