LPC2148 – GPS Interfacing

This article is a continuation of the series of tutorials on the LPC2148 Microcontroller (ARM7). The aim of this series is to provide easy and practical examples that anyone can understand. In the previous tutorial, we have interfaced the ultrasonic sensor with LPC2148 (ARM7). In this tutorial, we are going to see GPS Interfacing with LPC2148.

Suggestion to read

Before we will start i would suggest you to read these topics. Then only you can understand this strongly. If you already know, please go ahead.

Components Required

  • LPC2148 Development Board
  • GPS Module
  • LCD Module (To print the Latitude and Longitude)

GPS

Introduction

The Global Positioning System (GPS) is a satellite-based navigation system that consists of 24 orbiting satellites, each of which makes two circuits around the Earth every 24 hours. These satellites transmit three bits of information – the satellite’s number, its position in space, and the time the information is sent. These signals are picked up by the GPS receiver, which uses this information to calculate the distance between it and the GPS satellites.

With signals from three or more satellites, a GPS receiver can triangulate its location on the ground (i.e., longitude and latitude) from the known position of the satellites. With four or more satellites, a GPS receiver can determine a 3D position (i.e., latitude, longitude, and elevation). In addition, a GPS receiver can provide data on your speed and direction of travel. Anyone with a GPS receiver can access the system. Because GPS provides real-time, three-dimensional positioning, navigation, and timing 24 hours a day, 7 days a week, all over the world, it is used in numerous applications, including GIS data collection, surveying, and mapping.

GPS Data Format

GPS units spit out data in a dizzying array of formats. It can become a challenge to take the output from a GPS unit.

When you connect a GPS board up and look at the data coming off of it, you are likely to see something like this:

$GPRMC,000009.800,V,,,,,0.00,0.00,060180,,,N*43
$GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32
$GPGGA,000010.800,,,,,0,0,,,M,,M,,*41
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPRMC,000010.800,V,,,,,0.00,0.00,060180,,,N*4B
$GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32
$GPGGA,000011.800,,,,,0,0,,,M,,M,,*40
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPRMC,000011.800,V,,,,,0.00,0.00,060180,,,N*4A
$GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32
$GPGGA,000012.800,,,,,0,0,,,M,,M,,*43
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,1,1,00*79

This is what the data looks like when your GPS does not have a fix. When it does have a fix, there will be all types of numbers between the commas in the lines above. So, how do we make sense of all this? The first thing is to learn some of the lingo. Each line above is referred to as an NMEA sentence. There are different NMEA sentence types, and the type is indicated by the first characters before the comma. So, $GPGSA is a certain type of NMEA sentence, and $GPRMC is a different type of NMEA sentence. To make this whole thing a manageable problem, the first thing we must realize is that the data that we want will be in the $GPRMC sentence. If your GPS unit has options to turn the other sentences off, then turn them off to simplify the data getting thrown at you. If you can not turn the other sentences off, then just ignore them, and focus on the $GPRMC.

If your GPS has a fix, then your GPS sentences should look something like this:

$GPRMC,092204.999,A,4250.5589,S,14718.5084,E,0.00,89.68,211200,,A*25

Let’s start by breaking down the $GPRMC sentence.

  1. The $GPRMC is simply telling what sentence type is on the line.
  2. The next number represents the Coordinated Universal Time (UTC). It works like this, 092204.999 would be 09:22 and 04.999 seconds in UTC. Since converting from UTC to your local time is simply a matter of knowing what time zone you are in, you can see that one thing you get from a GPS is a very accurate clock.
  3. The next letter just lets you know if your signal is Active (A) or Void (V).  An ‘A’ indicates you are getting a signal and things are working properly. A ‘V’ means you do not have a signal.
  4. Now, for the good stuff, the next number and following letter give you your latitude.  4250.5589,S should be interpreted as,  Your Latitude is 42 degrees, 50.5589 minutes, in the Southern Hemisphere.
  5. Similarly, the next number, 14718.5084,E,  is Longitude. This is interpreted as, Your Longitude is 147 degrees 18.5084 minutes, in the Eastern Hemisphere.

Note: Degrees could be a one, two, or three-digit number. Hence you have to be careful parsing this data. What is always the case is that the first two numerals to the left of the decimal place, and the numbers to the right of the decimal represent the minutes. So, always take the number starting two to the left of the decimal, and those following all the way to the comma, and that is your minutes. Unfortunately, if you simply try to put 4250.5589,S,14718.5084,E, into Google Earth, it will not recognize it. The simplest thing you can do to get Google Earth to recognize and properly display the coordinate would be to enter the following:

42 50.5589S, 147 18.5084E

Notice the space inserted between degrees and minutes, and no comma before hemisphere designation. This would properly display that single point via the Google Earth search bar.

This data is enough to get Latitude and Longitude.

Applications

GPS used in many fields.

  • Agriculture
  • Aviation
  • Environment
  • Marine
  • Public Safety & Disaster Relief
  • Rail
  • Recreation
  • Roads & Highways
  • Space
  • Surveying & Mapping

Now we will interface the GPS Module to LPC2148.

GPS Interfacing with LPC2148

Connection

LCD:

  • RS – P1.23
  • RW – P1.22
  • EN – P1.21
  • Data Lines – P1.24 – P1.31

GPS:

  • VCC – Power Supply 3.3 – 6 V
  • GND – Ground
  • TX – UART1 RX Pin In LPC2148

GPS Interfacing with LPC2148

Programming – GPS Interfacing with LPC2148

This program will display the latitude and longitude in LCD. In this code, while loop doesn’t do anything. Everything will be done by Serial ISR function. That prints are based on Indian latitude and longitude. If you didn’t get proper digits in LCD, please separate those arrays based on your country’s lat and long. I’ve mentioned those arrays above.

#include <LPC214X.H>
#include <stdio.h>
#include <string.h>

#define LCD_DATA1 24
#define RS1 23
#define RW1 22
#define EN1 21

/*----- GPS Functions (UART1) -----*/
void init_uart1(void)	;
void init_uart1int(void);
void sendserial1(unsigned char serdata);
void UART1_ISR(void)__irq;

/*----- LCD Functions -----*/
void display1(unsigned char *);
void command1(unsigned char );
void lcd_data_char1(unsigned char);
void delay (unsigned int );
void lcd_init(void);

char namegps[7], name1gps[7] = "GPRMC,",gpsdat[63];
char msggps , checkgps;
int h;
unsigned char f;

int main(void)
{
	
	IODIR1=0xfff00000;
	IODIR0=0x00ffBfff;
	VPBDIV=0x02;

	lcd_init();
	init_uart1int();

	command1(0x80);
	display1("LON:                ");
	command1(0xc0);
	display1("LAT:                ");
	
	while(1);

}


void UART1_ISR(void)__irq
{
	//U1IER=0X00;
	
	if((U1LSR & 1)!=0) {		// check for receive interrupt
		msggps=U1RBR;
		
		if(msggps=='$') {
			U1IER=0X00;

			for(f=0;f<=5;f++) {
				while(!(U1LSR & 0x01));
				namegps[f]=U1RBR;
			}
		  	checkgps=strcmp(namegps,name1gps);
		   	if(checkgps==0) {
		   		for(f=0;f<=62;f++) {
						while(!(U1LSR & 0x01)); 
						gpsdat[f]=U1RBR;			
				}

				command1(0x84);
				for(h=12;h<14;h++) {
					lcd_data_char1(gpsdat[h]);
				}
				lcd_data_char1('.');
				for(h=14;h<16;h++) {
					lcd_data_char1(gpsdat[h]);
				}
				for(h=17;h<19;h++) {
					lcd_data_char1(gpsdat[h]);
				}
				lcd_data_char1(223);
				lcd_data_char1(' ');
				lcd_data_char1('N');

				command1(0xc4);
				for(h=26;h<28;h++) {
					lcd_data_char1(gpsdat[h]);
				}
				lcd_data_char1('.');
				for(h=28;h<30;h++) {
					lcd_data_char1(gpsdat[h]);
				}
				for(h=31;h<33;h++) {
					lcd_data_char1(gpsdat[h]);
				}
				lcd_data_char1(223);
				lcd_data_char1(' ');
				lcd_data_char1('E');
			}
			U1IER=0x01;
		}	
	}
		
	VICVectAddr=0x00000000;
}

void init_uart1(void)				// UART Initializing Function
{
	/* initializing UART1*/
	PINSEL0=PINSEL0 | 0x050000;		// Pin P0.8 and P0.9 for TxD1 and RxD1
	U1LCR= 0x83;				// 8 bits, no Parity, 1 Stop bit     
	U1DLL= 0xC2;				// DLAB = 1, 9600 Baud Rate @ 30MHz VPB Clock
	U1DLM = 0x00;							 
	U1LCR=0x03;				// DLAB = 0
	
	return;
}

void init_uart1int(void)			// UART Initializing Function
{
	/* Initializing UART1 interrupt*/
	VICVectCntl6=0x027;			//	Set priority slot as 6 for UART1
	VICVectAddr6= (unsigned) UART1_ISR ;	// Set Address for UART1 ISR
	VICIntEnable= 0x0080;			// Enable UART1 Interrupt

	/* initializing UART1*/
	PINSEL0=PINSEL0 | 0x050000;		// Pin P0.8 and P0.9 for TxD1 and RxD1
	U1LCR= 0x83;				// 8 bits, no Parity, 1 Stop bit     
	U1DLL= 0xC2;				// DLAB = 1, 9600 Baud Rate @ 30MHz VPB Clock
	U1DLM = 0x00;							 
	U1LCR=0x03;				// DLAB = 0
	U1IER=0x01; 				// Enable RBR interrupt
	return;
}

void sendserial1(unsigned char serdata)
{
	U1THR = serdata;
	while(!(U1LSR & 0x20));
}

void display1(unsigned char *str)
{
	for(;*str!=NULL;str++) {
		lcd_data_char1(*str);
		delay(1);
	}
}

void command1(unsigned char command)
{
	IOCLR1	=	0xffe00000;					
	IOSET1	=	command<<LCD_DATA1;	
	delay(1);
	IOSET1	=	1<<EN1;
	delay(2);
	IOCLR1	=	1<<EN1;
}

void lcd_data_char1(unsigned char data)
{
	IOCLR1	=	0xffe00000;//<<LCD_DATA;
	IOSET1	=	1<<RS1;
	IOSET1	=	data<<LCD_DATA1;
	delay(1);
	IOSET1	=	1<<EN1;
	delay(5);
	IOCLR1	=	1<<EN1;
}

void delay (unsigned int t)
{
	unsigned int j=0;
	while(t-->0) {
		while(j++<10000);
		j=0;
	}
}

void lcd_init()
{
	unsigned char comm[]={0x38,0x0C,0x01,0x06,0x80};
	unsigned int i;
	IODIR1=0xfff00000;
	IODIR0=0x0000FF00;
	delay(1);

	for(i=0;i<=4;i++) {
		command1(comm[i]);
		delay(1);
	}
}

You can try this code with hardware.

In our next tutorial, we will see how to interface the PIR sensor with LPC2148 (ARM7). If you want to use FreeRTOS on LPC2148, then please refer FreeRTOS series.

You can also read the below tutorials.

Linux Device Driver TutorialsC Programming Tutorials
FreeRTOS TutorialsNuttX RTOS Tutorials
RTX RTOS TutorialsInterrupts Basics
I2C Protocol – Part 1 (Basics)I2C Protocol – Part 2 (Advanced Topics)
STM32 TutorialsLPC2148 (ARM7) Tutorials
PIC16F877A Tutorials8051 Tutorials
Unit Testing in C TutorialsESP32-IDF Tutorials
Raspberry Pi TutorialsEmbedded Interview Topics
Reset Sequence in ARM Cortex-M4BLE Basics
VIC and NVIC in ARMSPI – Serial Peripheral Interface Protocol
STM32F7 Bootloader TutorialsRaspberry PI Pico Tutorials
STM32F103 Bootloader TutorialsRT-Thread RTOS Tutorials
Zephyr RTOS Tutorials - STM32Zephyr RTOS Tutorials - ESP32
AUTOSAR TutorialsUDS Protocol Tutorials
Product ReviewsSTM32 MikroC Bootloader Tutorial
VHDL Tutorials
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

9 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Table of Contents