Make a GPS Clock With a PIC Microcontroller

January 29, 2016 by Jens Christoffersen

In this article I'll show you one way to use a PIC microcontroller to get the time and date from a GPS module.

Use a PIC microcontroller to get time and date from a GPS module.



In the previous articles Make a GPS Clock With Arduino and Make a GPS Clock With PICAXE, I've made GPS clocks with both an Arduino and a PICAXE. In this article, I'm using a PIC16F628A. For a brief introduction to GPS and navigation, read the article in the first link.

In this article I'm using a different GPS module than I did in the previous articles. The baud rate is 9600, so I have to configure the uart port to match this. To read out the time, I'm going to use the GPRMC sentence. This sentence looks like this:


The GPRMC sentence and others are sent each second. The software will search for the right one and use the information from that.


The following schematic is built on a breadboard. Notice the display LCD output block. D6 and D7 are connected to the PICs pins 12 and 13. This happens to be PGC and PGD, the programming pins. I'm not going to read from the LCD, so I ground the RW pin. I've also grounded D0-D3. It is good practice to ground unused pins like this, however unused pins on a PIC mounted on a PCB I like to route to a pad for easy access if I'm adding some more features to the project. This is not the case here since the circuit is breadboarded.

Click on image for full size.

Parts List

The following is an edited list from the BOM ulp in EagleCAD.


The software is commented, but I'll walk through it in general here.

First are the includes libraries, configuration bits, variable declaration, and prototyping of the functions. Then I have the functions to drive the LCD display. To get the LCD display to work properly, you'll have to follow a certain recipe. After that comes the uart functions and two functions to display a message when the received time and date is not valid.

The main program starts off with some instructions: turning off comparators, setting the right directions to the ports, and set all port s to low. Then it initialize the LCD port and the uart port. In the main while-loop, each byte received on RX is placed in a variable. The variable is compared to see if it's the dollar sign, $. If it is a dollar sign, I know now that I'm at the beginning of an NMEA sentence, but I don't know which one. Then it reads the next six bytes and puts them in an array. This array is then compared to a predefined array. If it is equal, then I know two things: one, I have a sentence and two, I have the right sentence. Now follows a lot of for-loops, to read and place the right values in the right places. In this example it reads time, date, latitude and longitude, but only time and date are displayed on the LCD.

When the program is near the end of the main while-loop, it displays the time and date on the LCD. The time displayed is often called GPS ZULU time.

You can download the c-source code below.


In this article, I've shown you one way to get the time and date from a GPS module using a PIC microcontroller. With small changes in the code, you can use this on a different PIC. The program reads time, date, latitude and longitude, but it only display the time and date. I challenge the reader to display lat and lon.

Pictures and Video

Here are some pictures of the breadboard.

Startup screen.

Before the PIC receives valid data.

The module has a small backup battery that helps to start the clock much faster before it has a satellite fix.

Now there is valid information in the NMEA sentence.

Give this project a try for yourself! Get the BOM.

  • P
    Phil-S February 06, 2016

    Nice, polished project.
    I need a fairly accurate time source for projects around the house (programmable thermostats etc.) so this would be ideal.
    I don’t generally use PICAXE and stick with Arduino (no time to learn something else) so will proably use your Arduino version

    Like. Reply
  • Jim Point OH February 06, 2016

    Thanks for the project. This has also been done with MMbasic running on a PIC32. Very few parts and works like a champ. Take a look at the project here…

    Only 8 parts to make this work.


    Like. Reply
  • F
    Fgv April 15, 2016

    I tried to simulate this circuit with successfully compiled software in Proteus 8 without success, I’m wondering why!

    Like. Reply
  • J
    johnbpilot March 05, 2019

    For some reason, I keep getting errors when I try to compile the code as is:

    GPS_Time.c:47:15: error: conflicting types for ‘getch’
    unsigned char getch(void);
    C:\Program Files (x86)\Microchip\xc8\v2.05\pic\include\c90\conio.h:14:13: note: previous declaration is here
    extern char   getch(void);
    GPS_Time.c:48:6: error: variable has incomplete type ‘void’
    void interrupt tc_int(void);
    GPS_Time.c:48:15: error: expected ‘;’ after top level declarator
    void interrupt tc_int(void);
    GPS_Time.c:170:15: error: conflicting types for ‘getch’
    unsigned char getch() {
    C:\Program Files (x86)\Microchip\xc8\v2.05\pic\include\c90\conio.h:14:13: note: previous declaration is here
    extern char   getch(void);
    GPS_Time.c:179:6: error: variable has incomplete type ‘void’
    void interrupt tc_int(void) {
    GPS_Time.c:179:15: error: expected ‘;’ after top level declarator
    void interrupt tc_int(void) {
    6 errors generated.

    Any idea how to fix this?

    Like. Reply
  • Perby1977 March 09, 2019

    Is there a up to date c-source.

    Like. Reply
  • E
    Erik Burman March 28, 2019

    I was referred to this project by my recent HackerBox kit. After setting the X8C global options C Standard to C90, I had no problem compiling and downloading the code to my PIC chip. However the LCD will only display the intro screen..line 1 “PIC 16F628A” and line 2 “GPS CLOCK_.” It never moves beyond that. The GPS module is powered and the flashing green light indicates that it’s receiving satellite signals. I definitely have the GPS serial TX line connected to the PIC RX port, but nothing more happens. Any ideas? Simple code change maybe?

    Like. Reply
    • E
      Erik Burman March 29, 2019
      By the way, I checked the output from the GPS module with a logic analyzer and it's sending appropriate data. So, I know that the module is working.
      Like. Reply
  • T
    t1d August 17, 2019

    Thank you for sharing this great project. It is just what I was looking for.

    I am preparing to do your project with a PIC18F4550. I am a novice with coding. I have a few questions, please…
    - I have the 1602 Display; I have never used one. Is there anything that I need to do to prepare it for this project? I know that there are display libraries, but I think they go into the MCU. If your code does not already have the needed library, what do I need to do to get it loaded (download link, instructions, etc.)
    - My demo board has a 20MHz oscillator. I think we normally configure for 8Mhz. What do I need to do to change the frequency? Just change the configuration frequency?
    - I think I can match the pins up, based on their functions. Is there anything to watch out for, in doing that?
    - Do you have any other tips, or cautions.

    Thank you for your help. I look forward to having a really cool, super accurate clock.

    Like. Reply
    • J
      Jens Christoffersen August 19, 2019
      Hi. If you have a 1602, like mine, the 9 first functions in the code, should be enough to drive the display. You need the change the pins in the code, so they match you MCU. In line 148 - 159, I go through the steps for calculating the new baud rate. You need to change that for the 20MHz crystal. Good luck with your project. :-)
      Like. Reply
  • A
    ahmad111 September 05, 2019

    i have done the same project with pic 16f887 with little modification and it is working properly.

    Like. Reply
  • S
    sergioilha5 November 30, 2019

    ola nao teria como postar o arquivo hex ja pronto ?

    Like. Reply