In this tutorial, we will be designing a GPS receiver to display the Latitude and Longitude on a Liquid Crystal Display (LCD). GPS stands for Global Positioning System. It was originally designed for military and intelligence applications at the height of the Cold War in the 1960s.

GPS is a network of orbiting satellites that send precise details of their position back to the Earth and track the exact location of the GPS receiver. If it is mounted on a vehicle, then we can track the location of the vehicle. There are about 24 geostationary satellites that orbit around the Earth every 12 hours covering the whole planet.

For a GPS receiver to lock onto a particular location, at least 3 such satellites are needed. They undergo the process called triangulation. Actually four such satellites will be involved to lock onto the GPS signal. The three points will be on the Earth and the fourth point will be in space, which is not taken in to consideration.

 
Figure 1: GPS Satellite Lock

In the above diagram, the satellites A, B, C rotate around the earth and lock the location on the earth. GPS is free of cost for the customer. Anybody can track their location. It is very helpful in navigation.

To design the project some of the steps involved are necessary components, hardware assembly, software coding, and displaying the result.

Materials:

Hardware Assembly:

a)      GPS Receiver:

The 1X5 right angle pin is soldered to the LS20031 GPS receiver. To solder them together, there is an easy trick that makes it very simple. Solder the pins to the GPS receiver. The completed soldered GPS receiver should look like figure 3.

For an introduction to the LS20031 GPS Receiver, check out this tutorial from Jaycon Systems.

b)      LCD:
The LCD is soldered with straight pin headers to attach it to the bread board. The soldered LCD should look like figure 4.

Figure 4: LCD

c)      Arduino:
The Arduino Uno board has a built-in voltage regulator, which can supply both the 5V and 3.3V. We can directly connect the pins from the board. The GPS receiver LS20031 will operate in 3.3V. For the LCD, the voltage connected is from the 5V pin. For this project, the wires on the board connected are 5V, 3.3V, GND, and the data lines are 12, 11, 5, 4, 3, 2, 1, 0.

 

d)      Bread board assembly:
The LCD and GPS receiver are inserted to the bread board. The connection goes as follows:


Figure 5: Bread board assembly

 

Software Code:

Below is the code used to display our location on the LCD screen.  Before you upload the code, make sure the transmitting line of the GSP (Pin 3) is disconnected. In other words, disconnect the wire that goes into the Arduino’s pin 0 before uploading the code. Once the code is uploaded, you can connect the wire again. 

#include <SoftwareSerial.h>
#include <LiquidCrystal.h>

SoftwareSerial mySerial(0, 1); // RX, TX
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

//Initialize the variables globally 
char GPS_text;
int comma_count = 0;
String latitude, longitude;
int South = 0, West = 0, count =1;

void setup()  
{
  Serial.begin(115200);
  mySerial.begin(57600);
  lcd.begin(16, 2);
}

void loop() // run over and over
{
  if (mySerial.available()){ //Check for the data available 
    GPS_text = mySerial.read(); //Store the value in the variable
    if(GPS_text == '$'){    //Check if the variable starts with '$'
      Serial.write("\n");
      comma_count = 0;
      latitude = "\0";
      longitude = "\0";
    }
    
//**************GPS Count*************//
    
    if(GPS_text == ',') //Check for the comma and separate
    {
    `  comma_count = comma_count +1;
    }
    if(comma_count == 2)
    {
      latitude += GPS_text;   //The receiver transmit or receive by a byte at a time. This command will be used to store the bytes in the single variable 
      count = 0;
    }
    if(comma_count == 3)
    {
      latitude += GPS_text;  
      if (count == 1)
      {
        
//  **********GPS LATITUDE DATA SEPERATION***********

        Serial.println("***************GPS DATA************");
        Serial.println("LAT:"+ latitude); //To display the GPS format latitute in ddmm.mmmm
        String dd, mm1, mm2, mm3;
        int dotlocation = latitude.indexOf('.');
        dd = latitude.substring(dotlocation-4, dotlocation-2);
        mm1 = latitude.substring(dotlocation-2, dotlocation);
        mm2 = latitude.substring(dotlocation+1, dotlocation+5);
        unsigned long D1 = dd.toInt();    //Convert the recived string to int
        unsigned long MM1 = mm1.toInt();  //Convert the recived string to int
        unsigned long MM2 = mm2.toInt();  //Convert the recived string to int
        int setdot;   //Used to set the precision
        if (D1 > 9)
          setdot = 2;  
        else 
          setdot = 1;          
        Serial.print("DD= ");  
        Serial.println(D1);    //Store the dd 
        Serial.print("mm1=");  
        Serial.println(MM1);   //Store two mm
        Serial.print("mm2=");
        Serial.println(MM2);   //Store the remain .mmmm
        Serial.print("dotlocation = ");
        Serial.println(dotlocation);
     
//***********Conversion****************//
        D1= D1 * 100000;
        Serial.println(D1);
        MM1 = MM1 * 10000;
        unsigned long temp;
        temp = MM1 + MM2;
        Serial.println(temp);
        temp = temp / 6;
        D1 = D1+ temp;   
     
        Serial.print("D1 = ");
        Serial.println(D1);
        String A = (String)D1;
        dd = A.substring(0,setdot);
        mm1= A.substring(setdot);
       
        if (GPS_text == 'S')
        {
          A = '-' + dd + '.' + mm1;  //To display the "-dd.mmmm" if its South
          Serial.write("South = \t");                   
        }
        else
        {
          A = dd + '.' + mm1;   //To display the "dd.mmmm" if its North
          Serial.write("North = \t");              
        }   
        Serial.println(A); 
       
//*********LCD Display*******// 
             
       lcd.setCursor(0, 0); //Setting the cursor position            
       lcd.print("LAT:" + A); //Print the result in the LCD   
     }
   //to check the GPS text after comma
     count = count+1;
   }
   
   if(comma_count == 4)
   {
     longitude += GPS_text;
     count =0;
   }
   
   if(comma_count ==5)
   {
     longitude += GPS_text;
     
     if (count == 1)
     {
//  **********GPS Longitude DATA SEPERATION*********** 
       
       Serial.println("LON:"+ longitude);
       String dd, mm1, mm2, mm3;
       int dotlocation = longitude.indexOf('.');
       dd = longitude.substring(dotlocation-5, dotlocation-2);
       mm1 = longitude.substring(dotlocation-2, dotlocation);
       mm2 = longitude.substring(dotlocation+1, dotlocation+5);
       unsigned long D1 = dd.toInt();    //Convert the recived string to int
       unsigned long MM1 = mm1.toInt();  //Convert the recived string to int
       unsigned long MM2 = mm2.toInt();  //Convert the recived string to int
       int setdot;
       if (D1 > 99)
         setdot = 3;
       else if (D1 >9)
         setdot = 2;
       else
         setdot = 1;          
       Serial.print("DD= ");
       Serial.println(D1);   //Store the dd
       Serial.print("mm1=");
       Serial.println(MM1);  //Store the mm
       Serial.print("mm2=");
       Serial.println(MM2);  //Store the .mmmm
       Serial.print("dotlocation = ");
       Serial.println(dotlocation);
       
     //***********Conversion****************//
     
       D1= D1 * 100000;
       Serial.println(D1);
       MM1 = MM1 * 10000;
       unsigned long temp;
       temp = MM1 + MM2;
       Serial.println(temp);
       temp = temp / 6;
       D1 = D1+ temp;   
     
       Serial.print("D1 = ");
       Serial.println(D1);
       String A = (String)D1;
       dd = A.substring(0,setdot);
       mm1= A.substring(setdot);
       
       if (GPS_text == 'W')
       {
         A = '-' + dd + '.' + mm1;   //To display if its West
         Serial.write("West = \t");                    
       }
        else
        {
          A = dd + '.' + mm1;   //To display if its South
          Serial.write("East = \t");
        }   
        Serial.println(A); 
        
//*********LCD Display*******// 

         lcd.setCursor(0, 1); //Setting the cursor position            
         lcd.print("LON:" + A);//Print the result in the LCD
       }
       count = count+1;
     }
     if(comma_count == 6)
     {
       count =0;
     }
   } 
 }

 

Software code explanation:

#include <SoftwareSerial.h>
#include <LiquidCrystal.h>

SoftwareSerial mySerial(0, 1); // RX, TX
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

char GPS_text;
int comma_count = 0;
String latitude, longitude;
int South = 0, West = 0, count =1;

void setup()  
{
  Serial.begin(115200);
  mySerial.begin(57600);
  lcd.begin(16, 2);
}

In the first part of the code, we are simply including the libraries required to manipulate the LCD screen and serial communication. We then initialize the screen with the interface pins and establish a serial communication for the GPS. Next, we declare and initialize the variables that we will use throughout the code. In the setup section, we set the baud rate for our serial communications and set the LCD’s number of columns and rows. 

GPS_text = mySerial.read(); //Store the value in the variable
   if(GPS_text == '$'){    //Check if the variable starts with '$'
     Serial.write("\n");
     comma_count = 0;
     latitude = "\0";
     longitude = "\0";
     }

In this part of the code inside the loop, we are reading the data transmitted from the GPS to the Arduino and checking if it matches the symbol $. If this is the case, the variables adopt the values assigned to them.

//**********GPS LATITUDE DATA SEPERATION***********
Serial.println("***************GPS DATA************");
Serial.println("LAT:"+ latitude); //To display the GPS format latitute in ddmm.mmmm
String dd, mm1, mm2, mm3;
int dotlocation = latitude.indexOf('.');
dd = latitude.substring(dotlocation-4, dotlocation-2);
mm1 = latitude.substring(dotlocation-2, dotlocation);
mm2 = latitude.substring(dotlocation+1, dotlocation+5);
unsigned long D1 = dd.toInt();    //Convert the received string to int
unsigned long MM1 = mm1.toInt();  //Convert the received string to int
unsigned long MM2 = mm2.toInt();  //Convert the received string to int
int setdot;   //Used to set the precision
if (D1 > 9)
setdot = 2;  
else 
setdot = 1;          
Serial.print("DD= ");  
Serial.println(D1);    //Store the dd 
Serial.print("mm1=");  
Serial.println(MM1);   //Store two mm
Serial.print("mm2=");
Serial.println(MM2);   //Store the remain .mmmm
Serial.print("dotlocation = ");
Serial.println(dotlocation);

When we get a coordinate from the GPS, we receive it in the format ddmm.mmm. In order to facilitate future calculations, we divide the information into dd, mm, mmmm. This section of the code takes care of that. We use the function “indexOf()” to find the dot location and split the data accordingly. Afterwards we convert each part to unsigned long int values. 

//***********CONVERSION******************
D1= D1 * 100000;
Serial.println(D1);
MM1 = MM1 * 10000;
unsigned long temp;
temp = MM1 + MM2;
Serial.println(temp);
temp = temp / 6;
D1 = D1+ temp;   
     
Serial.print("D1 = ");
Serial.println(D1);
String A = (String)D1;
dd = A.substring(0,setdot);
mm1= A.substring(setdot);

When the GPS coordinates are in the ddmm.mmmm format, then it is necessary to convert the coordinates into normal decimal values in order to be able to plot the location in Google maps, for example. This is done by multiplying dd and mm by 10000. The remaining mmmm value is added to the new mm value and the result is divided by 6. This result is then added to the new dd value. If the N/S indicator shows ‘S’ (South), the result needs to be multiplied by -1. We also set the dot location for the value to be meaningful using the function substring(). 

**********GPS Longitude DATA SEPERATION*********** 
Serial.println("LON:"+ longitude);
String dd, mm1, mm2, mm3;
int dotlocation = longitude.indexOf('.');
dd = longitude.substring(dotlocation-5, dotlocation-2);
mm1 = longitude.substring(dotlocation-2, dotlocation);
mm2 = longitude.substring(dotlocation+1, dotlocation+5);
unsigned long D1 = dd.toInt();    //Convert the recived string to int
unsigned long MM1 = mm1.toInt();  //Convert the recived string to int
unsigned long MM2 = mm2.toInt();  //Convert the recived string to int
int setdot;
if (D1 > 99)
setdot = 3;
else if (D1 >9)
setdot = 2;
else
setdot = 1;          
Serial.print("DD= ");
Serial.println(D1);   //Store the dd
Serial.print("mm1=");
Serial.println(MM1);  //Store the mm
Serial.print("mm2=");
Serial.println(MM2);  //Store the .mmmm
Serial.print("dotlocation = ");
Serial.println(dotlocation);

**********************Conversion*********************
D1= D1 * 100000;
Serial.println(D1);
MM1 = MM1 * 10000;
unsigned long temp;
temp = MM1 + MM2;
Serial.println(temp);
temp = temp / 6;
D1 = D1+ temp;   
     
Serial.print("D1 = ");
Serial.println(D1);
String A = (String)D1;
dd = A.substring(0,setdot);
mm1= A.substring(setdot);

The same process repeats for the longitude. 

***********************LCD display********************
lcd.setCursor(0, 0); //Setting the cursor position            
lcd.print("LAT:" + A); //Print the Latitude result in the LCD   

lcd.setCursor(0, 1); //Setting the cursor position            
lcd.print("LON:" + A); //Print the Longitude result in the LCD    

Once we have the correct format of the longitude and latitude, we can now display the coordinate on the LCD screen. First we set the cursor position on the first column and row to display the latitude on the top half on the screen. Then we set the cursor position on the first column and second row to display the longitude on the bottom half of the screen. 

Result:
When the code uploads, the GPS takes time to lock onto our position, so we need to be patient. Once the GPS is stable, the red light in the GPS will start to blink. This is the output given by the GPS receiver before doing any operations with the received result.

Let’s analyze one of the lines to see what each thing means:

$GPGGA,201052.600,2805.1123,N,08036.4561,W,1,3,2.11,180.7,M,-308

The picture below shows the result after the conversion has taken place in the code: 

The values can be directly used in Google maps to find the location.

28”08’462’N; 80”60’798’W is the location of 801 E Hibiscus Blvd, Melbourne, FL 32901,
which is the address of Jaycon Systems!

If you find the code long and confusing, there is a library written by Mikal Hart:

TinyGPS

You can use the example “test_with_gps_sample” to display the GPS’s latitude and longitude among other things. Make sure the baud rate is 115200 in Serial.begin, and select your rx and tx pins to be 0 and 1 in SoftwareSerial ss();

If you have any questions about this tutorial, do not hesitate to post a comment, shoot us an email, or post it in our forum.