Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Parsing GPS data using microcontroller (Phillips)(

Status
Not open for further replies.

SHIFA

Newbie level 2
Joined
Feb 28, 2011
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,312
Hello!
I am doing a project where...we 've connect a Garmin GPS receiver via MAX 232 to Microcontroller and further microcontroller to PC...I've to write a program to recieve the GPS data..NMEA format i.e GPRMC as UTC time, Latitude, Longitude, speed n serially transmit it out via serial port (not to display it on LCD or LED)........i'm nt that good at microcontroller serial programing in C..! Plzz if anybody could help me...??

below is my half done program...I want to knw if this is the right way of doin it??

#include <stdio.h>
#include <stdlib.h>
#include <reg51.h>


//void delay(int);

unsigned char data_type[5] = "GPRMC", a[6], Longitude[],UTC[],Lattitude[];
unsigned char temp[5];
unsigned int chk, i;

void getchar(void)
{
while(RI==0);
data_req=SBUF;
RI = 0;
}

void main(void)
{

TMOD = 0x20; // 8-bit autoreload for timer 1
TH1 = 0xFD; // baud rate of 9600
SCON = 0x50; // 8-bit UART mode and receiver enabled

TR1 = 1; // start timer 1
//IE = 0x90; // enable to serial port

// data_type[0]='G';
// data_type[1]='P';
// data_type[2]='R';
// data_type[3]='M';
// data_type[4]='C';

while (1)
{
while(RI==0);
a[0]=SBUF;
RI = 0;


if (a[0] == '$')
{
int i = 0;
for (i=0;i<=4;i++)
{
while(RI==0);
a=SBUF;
RI = 0;;

if (a != data_type)
{
chk=0;
}
else
{
chk=1; }
}

}
}


if (chk==1)
{
i=0;
for (i=0;i<7;i++)
{
a= _getkey();
UTC=a;
}
a= _getkey();

for(i=0;i<=10;i++)
{
a= _getkey();
Lattitude=a;
}
i=0;
for(i=0;i<=12;i++)
{
a= _getkey();
Longitude=a;
}
}
}
i=0;
for(i=1;i<=2;i++)
{
SBUF= UTC;
while(TI==0);
TI=0;
}
} }

---------- Post added at 00:26 ---------- Previous post was at 00:23 ----------

This is wat i received by directly connecting GPS to PC
$GPRMC,102537,A,1301.5790,N,07733.7577,E,000.0,000.0,190211,001.8,W*6F
$GPGGA,102537,1301.5790,N,07733.7577,E,1,11,0.8,949.2,M,-91.3,M,,*62
$GPGSA,A,3,03,06,11,14,16,18,19,24,30,31,32,,1.1,0.8,0.8*32
$GPGSV,3,1,12,03,12,223,42,06,15,211,40,11,12,309,38,14,32,015,25*7C
$GPGSV,3,2,12,16,09,189,26,18,27,099,25,19,14,254,38,24,12,320,42*7D
$GPGSV,3,3,12,30,20,175,21,31,84,218,39,32,06,316,36,21,04,149,00*79
$PGRME,11.0,M,53.0,M,54.1,M*18
$PGRMB,,,,,K,,N,N*01
$PGRMM,WGS 84*06

A C program should parse this data into its constituents....Plzzz Help...!!
 

I found the simplest way to decode NMEA strings was to use the string tokenizer strtok()
strtok - C++ Reference

e.g. to decode a $GPGGA string (PIC24 C30 code but should work on any modern system)
Code:
// decode GPS $GPGGA string
int GPSdecode(char data[], char output[], long int *time, long int *latitude, long int *longitude, long int*satelites)
	{
      int i,j;
      char *tok;
      //char output[100]={0};
      //printf("\n\nGPS: %s\n", data);
      if(!strstr(data,"GGA")){  return 0; }
      //continue;
      if((tok = strtok(data, ","))==NULL)  return 0;     /* find first token */
      //printf("token 1 %s ", tok);
      if((tok = strtok(NULL, ","))==NULL)  return 0;     /* get next token */
      strcpy(output,tok);
      for(i=0;output[i] != 0; i++)
        if(output[i]=='.') output[i]=0;
      *time=atol(output);
     //printf("token 2 %s %s %ld\n", tok, output, *time);
      if((tok = strtok(NULL, ","))==NULL)  return 0;     /* get next token */
      // remove . from the latitude/longitude value
      strcpy(output,tok);
      for(i=0;output[i] != 0; i++)
        if(output[i]=='.')
          for(j=i;output[j] != 0; j++)
             output[j]=output[j+1];
      *latitude=atol(output);
      //printf("token 3 %s %s\n", tok, output);
       if((tok = strtok(NULL, ","))==NULL)  return 0;     /* get next token */
      //printf("token 4 %s", tok);
      if(tok[0]=='S') *latitude= -*latitude;
      if((tok = strtok(NULL, ","))==NULL)  return 0;     /* get next token */
      //printf("token 5 %s ", tok);
       // remove . from the latitude/longitude value
      strcpy(output,tok);
      for(i=0;output[i] != 0; i++)
        if(output[i]=='.')
          for(j=i;output[j] != 0; j++)
             output[j]=output[j+1];
      *longitude=atol(output);
      if((tok = strtok(NULL, ","))==NULL)  return 0;     /* get next token */
      if(tok[0]=='W') *longitude = -*longitude;
       if((tok = strtok(NULL, ","))==NULL)  return 0;     /* get next token */
      if((tok = strtok(NULL, ","))==NULL)  return 0;     /* get next token */
      //printf("token %s\n", tok);
      *satelites=atol(tok);
      sprintf(output, "time %02ld:%02ld:%02ld   latitude %10ld longitude %10ld satelites %2ld           ", *time/10000, (*time %10000)/100, *time%100, *latitude, *longitude, *satelites);
      //printf("time  %ld:%ld:%ld   latitude %ld longitude %ld satelites %ld\n", *time/10000, (*time %10000)/100, *time%100, *latitude, *longitude, *satelites);
      printf("\n%s\n",output);
}
 

Why reinvent the wheel?

There are several NMEA sentence parsers available, many open source, Source Forge is a good starting point:

NMEA Library


Also with the source readily available, you can customize for your particular application.

Hope this helps in your quest.
 

Thankyou for ur reply...... I actually want a C program as this is my final year project... I want to simulate the program first in keil n then Put it in p89v51RD2...!!
I knw we get a software to parse the NMEA data......But as v r asked to write program I need help..!
@horace1....Thanks..a this was helpful..!!
 

hi
this ia a code for extracting nmea data but problem is taht when we are runing this program on proteus ,on lcd iam getting nothing .... the MICROCONTROLLER WE ARE USING IS ATMEGA128 .


Code:
#include<avr/io.h>
#include<avr/interrupt.h>
#include <util/delay.h>

#define RS 0	// bit 0 of Port
#define RW 1	// bit 1 of Port
#define E  2	// bit 2 of Port
#define DATA_BUS PORTD
#define DATA_DDR DDRD
#define CTRL_BUS PORTC
#define CTRL_DDR DDRC

char info[70];
unsigned int check=0,i;
char test[6]={"$GPRMC"};
char comma_position[13];

void delay(unsigned int z) // For delay when LCD Starts
{	unsigned int x;
	for(x=0 ; x<z ; x++)
		_delay_ms(10);
} //Delay Function Ends 

int ready()
{ //For checking that the LCD is ready or not?
	delay(10); return 1;
} //Ready Function Ends

void LCD_Pulse_E(int t){
	CTRL_BUS |= 0b00000100 ;  // E = 1; 
	delay(t);
	CTRL_BUS &= 0b11111011 ;  // E = 0; 
	delay(t);
}

// LCD COMMAND SENDING FUNCTION
int LCD_Command(unsigned char COMMAND){
       ready();
	   DATA_BUS = COMMAND;
	   CTRL_BUS=(0<<RS)|(0<<RW)|(1<<E);    //CTRL_BUS = 0b11111000;
	   //LCD_Pulse_E(1);
	   delay(1);
       CTRL_BUS=(0<<E);
    return 1;
}

// LCD DATA SENDING FUNCTION
void lcd_data(unsigned char item)
{
    PORTB = item;
    PORTA=(0<<RS)|(0<<RW)|(1<<E);
    delay(1);
    PORTA=(0<<E);
    return ;
}

int LCD_Show(unsigned char CHARACTER){
		ready();
		DATA_BUS = CHARACTER;
		CTRL_BUS = 0b11111001 ;
		// RS=1; RW=0;
		LCD_Pulse_E(1); return 1;
}

int LCD_Initialize()
{
	LCD_Command(0x38); // 8 data lines, two lines, Font 5x7. 
	LCD_Command(0x0F); // Display=ON, Curson=ON, Cursor Blonking=ON 
	LCD_Command(0x01); // Clear display and return cursor to the home position
	LCD_Command(0x06); // During read/write operation only cursor (not text)
	// should move right. 
	LCD_Command(0x80); // Cursor at Line 1, Position 0
	return 1; 
}

// LCD STRING SENDING FUNCTION 

void  LCD_Print(char*str)
	{
	unsigned char i='\0';
	while(str[i]!=0)
	{
	LCD_Show(str[i]);
	i++;
	}
	return ;
	}

//WHENEVER BIT IS RECIVED RUN THIS ISR
 
ISR(UART_RXC)
    {	

    info[check++]=UDR1;      //Read UDR
    if(check<7)
    {
        if(info[check-1]!=test[check-1])
        check=0;
    }
    
    }

// SERIAL PORT SETTING
void serial()
   {
   UCSR1B= (1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1)|(1<<UDRIE1); //Turn on the transmission and reception circuitry
   //UCSR1C= (1<<UCSZ11)|(1<<UCSZ1O)|(1<<URSEL1);
    UCSR1C = (0<<USBS1)|(3<<UCSZ10);
   UBRR1L= 0x67;
   }
//finding comma
void find_comma()
{
    unsigned int i,count=0;
    for(i=0;i<70;i++)
    {    
        if(info[i]==',')
        {
            comma_position[count++]=i;
        }
    }
}

//Shape of degree symbol

void lcd_shape()                
{
    LCD_Command(64);
    lcd_data(10);
    lcd_data(17);
    lcd_data(17);
    lcd_data(10);
    lcd_data(0);
    lcd_data(0);
    lcd_data(0);
    lcd_data(0);
}

//Extracting latitudes
void lcd_latitude()
{
    unsigned int c3=comma_position[2];
    lcd_shape();
    LCD_Command(0x01);                 //Clear LCD display
    LCD_Command(0x84);                 //Move cursor to position 6 of line 1
    LCD_Print("LATITUDE");         //Showing latitude
    LCD_Command(0xC0);                 //Begining of second line  
    lcd_data(info[c3+1]);
    lcd_data(info[c3+2]);
    lcd_data(0);
    lcd_data(info[c3+3]);
    lcd_data(info[c3+4]);
    lcd_data(info[c3+5]);
    lcd_data(info[c3+6]);
    lcd_data(info[c3+7]);
    lcd_data(info[c3+8]);
    lcd_data(info[c3+9]);
    lcd_data(0x27);             //ASCII of minute sign(')
    lcd_data(info[c3+10]);
    lcd_data(info[c3+11]);
    delay(250);
} 

//Extracting longitudes
void lcd_longitude()
{
    unsigned int c5=comma_position[4];
    LCD_Command(0x01);                 //Clear LCD display
    LCD_Command(0x84);                 //Move cursor to position 4 of line 1
    LCD_Print("LONGITUDE");         //Showing longitude
    LCD_Command(0xC0);                 //Begining of second line  
    lcd_data(info[c5+1]);
    lcd_data(info[c5+2]);
    lcd_data(info[c5+3]);
    lcd_data(0);
    lcd_data(info[c5+4]);
    lcd_data(info[c5+5]);
    lcd_data(info[c5+6]);
    lcd_data(info[c5+7]);
    lcd_data(info[c5+8]);
    lcd_data(info[c5+9]);
    lcd_data(info[c5+10]);
    lcd_data(0x27);               //ASCII of minute sign(')
    lcd_data(info[c5+11]);
    lcd_data(info[c5+12]);
    delay(250);
}


void compare()
{  
    UCSR1B=(0<<RXCIE1);       
    find_comma();
    lcd_latitude();
    lcd_longitude();
    check=0;
    UCSR1B=(1<<RXCIE1);
}

int main()
   {
	DATA_DDR = 0xFF;
	CTRL_DDR = 0xFF;
	CTRL_BUS = 0;
	DATA_BUS = 0;
	unsigned char data1;
    serial();
	sei();         //ENABLE GOBAL INTERRUPT
	
	
for(;;)
	{
		delay(500); 		// wait for LCD to Start
		LCD_Initialize();	
	
		//for(data1='A' ; data1 <='N' ; data1++){
			delay(50);
		
		LCD_Print("$GPRMC,092750.000,A,5321.6802,N,00630.3372,W,0.02,31.66,280511,,,A*43");
		//}
		
	}
while(1)
    {
        if(check==69)
       compare();
    }

	return 0;
}
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top