GPS module Interfacing with PIC18F4550

Overview of GPS

Global Positioning System (GPS) makes use of signals sent by satellites in space and ground stations on Earth to accurately determine their position on Earth.

Radio Frequency signals sent from satellites and ground stations are received by the GPS. GPS makes use of these signals to determine its exact position.

The GPS itself does not need to transmit any information.

The signals received from the satellites and ground stations contain timestamps of the time when the signals were transmitted. By calculating the time difference between the time the signal was transmitted and the time the signal was received, and using the speed of the signal, the distance between the satellites and the GPS can be determined using a simple formula for distance using speed and time.

Using information from 3 or more satellites, the exact position of the GPS can be triangulated.

For more information about GPS and how to use it, refer to the topic GPS Receiver Module in the sensors and modules section.

The GPS receiver module uses USART communication to communicate with the controller or PC terminal.

For information about USART in PIC18F4550 and how to use it, refer to the topic USART in PIC18F4550 in the PIC inside section.

This is the picture of GPS Receiver Module
GPS Receiver Module

 

Connection Diagram GPS to PIC18F4550

This is the picture of GPS Receiver Interfacing with PIC microcontroller
GPS Receiver Interfacing with PIC18F4550 

 

Get Lat, Long, Alt, and UTC using PIC18F4550 

Now let’s interface the GPS receiver module with PIC18F4550 and display the Time, Latitude, Longitude, and Altitude on the LCD20x4 display.

In this interfacing, the PIC18F4550 microcontroller will read data serially from the GPS receiver using USART communication with a 9600 Baud rate.

Then parse the “$GPGGA” string to extract information regarding time, latitude, longitude, and altitude.

 

GPS Code for PIC18F4550

/*
    GPS Information extraction using PIC18F4550 
    http://www.electronicwings.com
*/

#include<pic18f4550.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include "Configuration_Header_File.h"
#include "LCD_20x4_H_file.h"
#include "USART_Header_File.h"

unsigned long int get_gpstime();
float get_latitude(unsigned char);
float get_longitude(unsigned char);
float get_altitude(unsigned char);
void convert_time_to_UTC(unsigned long int);
float convert_to_degrees(float);

#define GGA_Buffer_Size 80
#define GGA_Pointers_Size 20

char GGA_Buffer[GGA_Buffer_Size];              /* to store GGA string */
char GGA_CODE[3];

unsigned char N_S, E_W;                        /* for getting direction polarity */
unsigned char GGA_Pointers[GGA_Pointers_Size]; /* to store instances of ',' */
char CommaCounter;
char Data_Buffer[15];
volatile unsigned int GGA_Index;
volatile unsigned char	IsItGGAString	= 0;

void main(void) {
	unsigned long int Time;
	float Latitude,Longitude,Altitude;
	char GPS_Buffer[15];
    
	OSCCON = 0x72;      /* use internal osc. of 8MHz Freq. */
	LCD_Init();
	INTCONbits.GIE=1;   /* enable Global Interrupt */
	INTCONbits.PEIE=1;  /* enable Peripheral Interrupt */
	PIE1bits.RCIE=1;    /* enable Receive Interrupt */
	USART_Init(9600);
	
	while(1){
	memset(GPS_Buffer,0,15);
	LCD_String_xy(1,0,"UTC Time: ");
	Time = get_gpstime();            /* Extract Time */
	convert_time_to_UTC(Time);       /* convert time to UTC */
	LCD_String(Data_Buffer);
	LCD_String("  ");
		
	LCD_String_xy(2,0,"Lat: ");
	Latitude = get_latitude(GGA_Pointers[0]); 	/* Extract Latitude */
	Latitude = convert_to_degrees(Latitude);  	/* convert raw latitude in degree decimal*/
	sprintf(GPS_Buffer,"%.05f",Latitude);		/* convert float value to string */
	LCD_String(GPS_Buffer);            			/* display latitude in degree */
	memset(GPS_Buffer,0,15);
		
	LCD_String_xy(3,0,"Long: ");
	Longitude = get_longitude(GGA_Pointers[2]);	/* Extract Latitude */
	Longitude = convert_to_degrees(Longitude);	/* convert raw longitude in degree decimal*/
	sprintf(GPS_Buffer,"%.05f",Longitude);		/* convert float value to string */
	LCD_String(GPS_Buffer);            			/* display latitude in degree */
	memset(GPS_Buffer,0,15);
			
	LCD_String_xy(4,0,"Alt: ");
	Altitude = get_altitude(GGA_Pointers[7]); 	/* Extract Latitude */
	sprintf(GPS_Buffer,"%.2f",Altitude);		/* convert float value to string */
	LCD_String(GPS_Buffer);            			/* display latitude in degree */

	}
}

unsigned long int get_gpstime(){
	unsigned char index;
	unsigned char Time_Buffer[15];
	unsigned long int _Time;
	
	/* parse Time in GGA string stored in buffer */
	for(index = 0;GGA_Buffer[index]!=','; index++){		
		Time_Buffer[index] = GGA_Buffer[index];
	}
	_Time= atol(Time_Buffer);        /* convert string of Time to integer */
	return _Time;                    /* return integer raw value of Time */        
}

float get_latitude(char lat_pointer){
	unsigned char lat_index = lat_pointer+1;	/* index pointing to the latitude */
	unsigned char index = 0;
	char Lat_Buffer[15];
	float _latitude;

	/* parse Latitude in GGA string stored in buffer */
	for(;GGA_Buffer[lat_index]!=',';lat_index++){
		Lat_Buffer[index]= GGA_Buffer[lat_index];
		index++;
	}
	lat_index++;
	N_S = GGA_Buffer[lat_index];
	_latitude = atof(Lat_Buffer);     /* convert string of latitude to float */
	return _latitude;                 /* return float raw value of Latitude */
}

float get_longitude(unsigned char long_pointer){
	unsigned char long_index;
	unsigned char index = long_pointer+1;		/* index pointing to the longitude */
	char Long_Buffer[15];
	float _longitude;
	long_index=0;
	
	/* parse Longitude in GGA string stored in buffer */
	for( ; GGA_Buffer[index]!=','; index++){
		Long_Buffer[long_index]= GGA_Buffer[index];
		long_index++;
	}
	long_index++;
	E_W = GGA_Buffer[long_index];
	_longitude = atof(Long_Buffer);    /* convert string of longitude to float */
	return _longitude;                 /* return float raw value of Longitude */
}

float get_altitude(unsigned char alt_pointer){
	unsigned char alt_index;
	unsigned char index = alt_pointer+1;		/* index pointing to the altitude */
	char Alt_Buffer[12];
	float _Altitude;
	alt_index=0;
	
	/* parse Altitude in GGA string stored in buffer */
	for( ; GGA_Buffer[index]!=','; index++){
		Alt_Buffer[alt_index]= GGA_Buffer[index];
		alt_index++;
	}
	_Altitude = atof(Alt_Buffer);   /* convert string of altitude to float */ 
	return _Altitude;					/* return float raw value of Altitude */
}

void convert_time_to_UTC(unsigned long int UTC_Time)
{
	unsigned int hour, min, sec;
		
	hour = (UTC_Time / 10000);                  	/* extract hour from integer */
	min = (UTC_Time % 10000) / 100;             	/* extract minute from integer */
	sec = (UTC_Time % 10000) % 100;             	/* extract second from integer*/

	sprintf(Data_Buffer, "%d:%d:%d", hour,min,sec); /* store UTC time in buffer */
	
}

float convert_to_degrees(float NMEA_lat_long){
	
	float minutes, dec_deg, decimal;
	int degrees;
	float position;

	degrees = (int)(NMEA_lat_long/100.00);
	minutes = NMEA_lat_long - degrees*100.00;
	dec_deg = minutes / 60.00;
	decimal = degrees + dec_deg;
	if (N_S == 'S' || E_W == 'W') { // return negative
		decimal *= -1;
    }	
	/* convert raw latitude/longitude into degree format */
	return decimal;
}

void interrupt Serial_ISR()   
{
	 
	if(RCIF){
		GIE  = 0;							/* Disable global interrupt */
		unsigned char received_char = RCREG;
        if(RCSTAbits.OERR){                 /* check if any overrun occur due to continuous reception */           
            CREN = 0;
            NOP();
            CREN=1;
        }
        
		if(received_char =='$'){     	    /* check for '$' */
			GGA_Index = 0;
			IsItGGAString = 0;
			CommaCounter = 0;
		}
		else if(IsItGGAString == 1){        /* if true save GGA info. into buffer */
			if(received_char == ',' ) GGA_Pointers[CommaCounter++] = GGA_Index;    /* store instances of ',' in buffer */
			GGA_Buffer[GGA_Index++] = received_char;
        }
		else if(GGA_CODE[0] == 'G' && GGA_CODE[1] == 'G' && GGA_CODE[2] == 'A'){ /* check for GGA string */
			IsItGGAString = 1;
			GGA_CODE[0] = 0; GGA_CODE[1] = 0; GGA_CODE[2] = 0;	
		}
		else{
			GGA_CODE[0] = GGA_CODE[1];  GGA_CODE[1] = GGA_CODE[2]; GGA_CODE[2] = received_char; 
		}	
	}
}

 

How to Calculate Latitude and Longitude in GPS coordinates form

We get Latitude and Longitude from GGA string which is in the form of ddmm.mmmm and dddmm.mmmm respectively.

Where,

D – degree

M – minutes

Now, we can convert received latitude and longitude string in DMS (Degree Minute Second) and Degree Decimal.

DMS – [dd] degree, [mm] minutes, [(.mmmm)*60] seconds

Degree Decimal– [dd] degree + (mm.mmmm/60)

E.g. We have the following Lat/Long data in NMEA format

Latitude – 1829.9639

Longitude – 07347.6174

Now, convert them in the following format –

DMS – 18° degree 29 minutes 57.834 seconds

Degree -  18.499398

 

Video of GPS Communication with PIC18F4550


Components Used

Ublox NEO-6m GPS
Ublox Neo 6m GPS
1
LCD16x2 Display
LCD16x2 Display
1
PIC18f4550
PIC18f4550
1
PICKit 4 MPLAB
PICKit 4 MPLAB
1

Downloads

PIC18F4550 Interface with GPS Project File Download
GPS Basics Download
NMEA Reference Manual Download
Ad