0

Raspberry Pi: Sync Time from GPS using Ublox Neo 6m V2

Your Raspberry Pi doesn’t have a built-in Real Time Clock, which means every time your Raspberry Pi has been rebooted or has been shutdown for long time, the Date & Time of the Raspberry Pi resets to “2000-01-01 00:00:00”.  One way of setting the Raspberry Pi’s Date & Time is via RTC Module. Another way of setting the date & time automatically is via NTP but your RPI must be connected to the internet, or manually setting it via Graphical User Interface (GUI) or via Command Line Interface (CLI), but what if there’s no internet connection available? Getting Date & Time from GPS is one of the best solution that i know. GPS not just provides you coordinates, but provides you accurate Date & Time.

Materials:

  • Raspberry Pi
  • Ublox Neo 6M V2
  • 4 pc Male Header Pin
  • 4 pc Jumper Female to Female
  • SMA Female to uFL/u.FL/IPX/IPEX RF Adapter Cable (Optional but recommended)
  • GPS Antenna (Optional but recommended)

Note: SMA Female to uFL/u.FL/IPX/IPEX RF Adapter Cable and GPS Antenna is optional but it is highly recommended to have it for better antenna gain. 

 

Installation Guide:

Step 1: Solder the header pins to the GPS Module:

Step 2: Connect the SMA Female to uFL/u.FL/IPX/IPEX RF Adapter Cable and GPS Antenna:

Step 3: Connect GPS module to RPI via Jumper Wires.

  • GPS <—> RPI GPIO
  • VCC to PIN 4  (5V) or any 5V PIN
  • RX to PIN 8 (TXD)
  • TX to PIN 10 (RXD)
  • GND to PIN 14 (GND) or any GND Pin

GPIO Pins:

 

Note: Don’t be confused between RX & TX pin of RPI and GPS Module, the RX pin of RPI must be connected to the TX pin of GPS Module and vice versa.

Step 4: Turning off the Serial Console

Step 4a: We need to backup the “/boot/cmdline.txt” file:

sudo cp /boot/cmdline.txt /boot/cmdline_bak.txt

Step 4b: Edit the cmdline.txt

sudo nano /boot/cmdline.txt

Step 4c: Find and delete “console=ttyAMA0,115200” from the file, then save and exit. (ctrl + O then Y to save, then Ctrl + X to exit the nano terminal).

Note: If file doesn’t contain the “console=ttyAMA0,115200” then proceed to next step) 

Step 4d: Edit the /etc/inittab and find “ttyAMA0” keyword and add “#” from the first character of the line.

sudo nano/etc/inittab

Note: If file doesn’t contain the “ttyAMA0” then proceed to next step) 

Step 4e: Edit the /boot/config.txt file

sudo nano /boot/config.txt

Add the following at the end of the file:

dtparam=spi=on
dtoverlay=pi3-disable-bt
enable_uart=1

Ctrl + O to save, then Ctrl +x to exit nano terminal.

 Step 4f: Disable the RPI’s Getty Service:

sudo systemctl stop serial-getty@ttyS0.service
sudo systemctl disable serial-getty@ttyS0.service

Reboot the Raspberry Pi by executing:

sudo reboot now

Step 4g: enable the ttyAMA0 by executing:

sudo systemctl enable serial-getty@ttyAMA0.service

Step 5: Test the GPS Module

Execute the following command:

sudo cat /dev/ttyAMA0

Step 6: Install python library for GPS:

sudo apt-get install python-pip
sudo pip install pynmea2
sudo apt-get install python-serial

Step 7: Python Script to get the GPS time and Sync it to Raspberry Pi’s Date and Time:

gps_sync.py:

import time
import serial
import string
import pynmea2
import datetime
from datetime import timedelta
import operator
import sys
import os

#port = "/dev/ttyS0"
port = "/dev/ttyAMA0"


def checksum(sentence):
  sentence = sentence.strip('\n')
  try:
    nmeadata,cksum = sentence.split('*', 1)
    calc_cksum = reduce(operator.xor, (ord(s) for s in nmeadata), 0)
    return nmeadata,int(cksum,16),calc_cksum	
  except ValueError:
    return False;

fetchDT = 0;
def getGPS():
  global fetchDT
  ser = serial.Serial(port, baudrate = 9600, timeout = 5)
  while 1:
    try:
      while(ser.inWaiting() >0):
        data = ser.readline().rstrip()
        if data[0:6] == "$GPRMC":
          print ""
          if checksum(data) != False:
            splitData = data.split(",")

            if splitData[2] == 'A': #Valid GPS TIME
              print data
              msg = pynmea2.parse(data)
              dateStr="20"+splitData[9][4:6]+"-"+splitData[9][2:4]+"-"+splitData[9][0:2]
              dtStr = dateStr + " " + str(msg.timestamp)
              dt = datetime.datetime.strptime(dtStr, "%Y-%m-%d %H:%M:%S") + timedelta(hours=8)  #OFFSET GMT8
              print "GPS TIME: " +str(dt)
              now = datetime.datetime.now()
              print "SYS TIME: " +str(now.strftime("%Y-%m-%d %H:%M:%S"))
              if dt > now:
                print "GPS TIME IS NOW AHEAD OF SYS TIME"
                os.system("sudo date -s '"+str(dt)+"'")	
              else:
                print "SYS TIME IS NOW AHEAD OF GPS TIME"
              
              if fetchDT >= 60:
                print "FINISH";
                print msg.timestamp;
                ser.close()
                sys.exit(0)
                exit();
                quit()

              fetchDT+=1;
        
    except pynmea2.nmea.ChecksumError as e:
      print("No data this time 0")
      ser.close()
      time.sleep(3)
      getGPS();
    except serial.SerialException as e:
      print("No data this time 1")
      ser.close()
      time.sleep(3)
      getGPS();
    except TypeError as e:
      print("No data this time 3")
      ser.close()
      time.sleep(3)
      getGPS();
    except serial.serialutil.SerialException:
      print("No data this time 4")
      ser.close()
      time.sleep(3)
      getGPS();
    except IOError as e:
      #print("No data this time")
      ser.close()
      getGPS();
    except (KeyboardInterrupt, SystemExit):
      print "Exiting"
      ser.close()
      exit();
    except Exception as e:
      print("No data this time 4")
      ser.close()
      time.sleep(3)
      getGPS();

now = datetime.datetime.now()	
getGPS();




Step 8: Run the application by executing:

sudo python gps_sync.py

You will see strings appeared on the terminal and wait for the correct GPS time to be appeared, the program will check if the GPS time is ahead of the RPI’s System time then it will sync.

You need also change the OFFSET on the program on Line 42, change timedelta(hours=8) to your Timezone, GPS time is based on UTC 0, in our timezone “Asia/Manila” which is UTC+8, so i assigned hours=8, Example if you are in UCT+5, you need to declare timedelta(hours=5).

Note: If you are not getting any date & time from GPS, you might need to relocate your GPS antenna which should be in outside of your house to get data from GPS Satellites. If its very cloudy, it might took time to get GPS data (Around 2-3minutes).

I’ll be updating this post to provide some screenshots soon.

To make the python program run on startup, please see “Running python script at startup

Kevin San Jose, VCP6-DCV

Kevin San Jose, VCP6-DCV

MTCNA, VCP6-DCV, CSS NCII, EIM NCII

Leave a Reply

Your email address will not be published. Required fields are marked *