gordon77
Posts: 6881
Joined: Sun Aug 05, 2012 3:12 pm

Set time with GPS

Wed Apr 29, 2015 1:56 pm

I didn't have one of my Pis on the web so I decided to set the date and time using GPS.
It probably isn't the easiest way to do it but it works for me.

Gordon

Code: Select all

#!/usr/bin/python
import serial
import os
from decimal import *
getcontext().prec = 4

# enter your time zone offset

TimeOffset = 0

gpsfound = 2
settime = 0
count = 120

if os.path.exists('/dev/ttyUSB0') == True:
   gpsfound = 0
   ser = serial.Serial('/dev/ttyUSB0',4800,timeout = 10)
else:
   print "No GPS RX found on USB0"
if os.path.exists('/dev/ttyUSB1') == True and gpsfound == 2:
   gpsfound = 1
   ser = serial.Serial('/dev/ttyUSB1',4800,timeout = 10)
else:
   if gpsfound == 2:
      print "No GPS RX found on USB1"
      
if gpsfound < 2:   
   Months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
   MDays = [31,28,31,30,31,30,31,31,30,31,30,31]
   Days = ['Thu','Fri','Sat','Sun','Mon','Tue','Wed','Thu','Fri','Sat','Sun','Mon','Tue','Wed']
   count1 = 1
   locked = 0
   found = 0
   while locked == 0 and count1 <= count:
      gps = ser.readline()
      if gps[1 : 6] == "GPGGA":
         if found == 0:
            print "GPS RX found on USB" + str(gpsfound)
            print "Waiting for lock...."
            found = 1
         if int(gps[43]) > 0 and gps[42] != "*":
            locked = 1
      count1 +=1
   if count1 < 120:
      print "Locked"
   else:
      print "Signal Unlocked, aborting time setting"

   count2 = 1
   cday = 0
   Leap = 0
   while settime == 0 and count1 <= count and count2 <= count:
      gps = ser.readline()
      if gps[1 : 6] == "GPRMC":
         gps2 = gps.split(',',12)
         fulldate = gps2[9]
         fulltime = gps2[1]
         clock = ":" + fulltime[2:4] + ":" + fulltime[4:6]
         Hour = int(fulltime[0:2])
         Hour = Hour + TimeOffset
         if Hour > 23:
            Hour = Hour - 24
            cday = 1
         if Hour < 0:
            Hour = Hour + 24
            cday = -1
         if Hour < 10:
            Hour = "0" + str(Hour)
         else:
            Hour = str(Hour)
         Year = int(fulldate[4:6])
         Mon = int(fulldate[2:4])
         Day = int(fulldate[0:2])
         if cday == 1:
            Day = Day + 1
            if Day > MDays[Mon-1]:
               Mon = Mon + 1
               Day = 1
               if Mon > 12:
                  Year = Year + 1
                  Mon = 1
         if cday == -1:
            Day = Day - 1
            if Day < 1:
               Mon = Mon - 1
               Day = MDays[Mon-1]
               if Mon < 1:
                  Year = Year - 1
                  Mon = 12
                  Day = MDays[Mon-1]

         Month = Months[Mon-1]
         Day = str(Day)
         Years = "20" + str(Year)
         x = 0
         YDays = 0
         while x < Mon - 1:
            YDays = YDays + MDays[x]
            if (2000 + Year)/4 == (2000+ Decimal(Year))/4 and x == 1:
               YDays = YDays + 1
               Leap = 1
            x +=1
         YDays = YDays + int(Day)
         Weekday = (YDays - ((YDays/7)*7))+(Year - 16) + int(Decimal(0.5) + (Decimal(Year)-Decimal(15))/Decimal(4))
         path = "sudo date -s '" + Days[Weekday] + " " + Month + " " + str(Day) + " " + Hour + clock + " " + Years + "'"
         print path
         os.system (path)
         settime = 1
      count2 +=1

if settime == 1:
   print "Time set with Time Offset to UTC " + str(TimeOffset) + " Hour(s)"
else:
   print "Unable to set time"


Last edited by gordon77 on Tue Jul 18, 2017 9:56 am, edited 6 times in total.

User avatar
DougieLawson
Posts: 42288
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK

Re: Set time with GPS

Wed Apr 29, 2015 2:11 pm

There's two "official" ways to do it.
  1. gpsd can set the clock
  2. ntp has a special driver 127.127.28.0
The benefit of gpsd is that it gives you a nice interface to the GPS data for other purposes. If you use the ntp driver you've tied up your GPS receiver.
Languages using left-hand whitespace for syntax are ridiculous

DMs sent on https://twitter.com/DougieLawson or LinkedIn will be answered next month.
Fake doctors - are all on my foes list.

The use of crystal balls and mind reading is prohibited.

gordon77
Posts: 6881
Joined: Sun Aug 05, 2012 3:12 pm

Re: Set time with GPS

Wed Apr 29, 2015 2:24 pm

'official' ?

Doesn't ntp need a network ?

User avatar
DougieLawson
Posts: 42288
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK

Re: Set time with GPS

Wed Apr 29, 2015 2:49 pm

gordon77 wrote:'official' ?

Doesn't ntp need a network ?
NOPE. Not if you've got a stratum 0 time reference.
Languages using left-hand whitespace for syntax are ridiculous

DMs sent on https://twitter.com/DougieLawson or LinkedIn will be answered next month.
Fake doctors - are all on my foes list.

The use of crystal balls and mind reading is prohibited.

chrisfromwa
Posts: 1
Joined: Sat Mar 05, 2016 3:42 pm

Re: Set time with GPS

Thu Apr 16, 2020 7:55 pm

Sorry to bump such an old thread, but I've been trying to get this to work but running into issues.

I'm using this GPS Dongle.
https://www.amazon.com/Navigation-Exter ... op?ie=UTF8

When I first tried to use the code as is, I got an issue about no GPS found.

Doing some research on the dongle, looks like the path to this device is ttyACM0.

So I changed that in the code, just to see if it made a difference. It did, I no longer get the 'no GPS' error. I'm not sure if that was the correct thing to try, but it looks like I get further down into the code but now get this error.

Image

I'm not sure what this piece of code is trying to do, or how to resolve the issue.

Does anyone have any suggestions on how to troubleshoot this?

chrisfromvic
Posts: 1
Joined: Mon Apr 20, 2020 8:57 am

Re: Set time with GPS

Mon Apr 20, 2020 10:00 am

Hi Chris, can you paste run `udevadm monitor`, plug in your GPS dongle, wait for a second, unplug it, and paste the output?

gordon77
Posts: 6881
Joined: Sun Aug 05, 2012 3:12 pm

Re: Set time with GPS

Mon Apr 20, 2020 1:49 pm

chrisfromwa wrote:
Thu Apr 16, 2020 7:55 pm
Sorry to bump such an old thread, but I've been trying to get this to work but running into issues.

I'm using this GPS Dongle.
https://www.amazon.com/Navigation-Exter ... op?ie=UTF8

When I first tried to use the code as is, I got an issue about no GPS found.

Doing some research on the dongle, looks like the path to this device is ttyACM0.

So I changed that in the code, just to see if it made a difference. It did, I no longer get the 'no GPS' error. I'm not sure if that was the correct thing to try, but it looks like I get further down into the code but now get this error.

Image

I'm not sure what this piece of code is trying to do, or how to resolve the issue.

Does anyone have any suggestions on how to troubleshoot this?
Did you try running the code with Python (not Python3)?

gordon77
Posts: 6881
Joined: Sun Aug 05, 2012 3:12 pm

Re: Set time with GPS

Mon Apr 20, 2020 3:44 pm

updated to python3

Code: Select all

#!/usr/bin/python3
import serial
import os
import sys
from decimal import *
getcontext().prec = 4

# enter your time zone offset

TimeOffset = 0

gpsfound = 2
settime = 0
count = 120

if os.path.exists('/dev/ttyUSB0') == True:
   gpsfound = 0
   ser = serial.Serial('/dev/ttyUSB0',4800,timeout = 10)
else:
   print ("No GPS RX found on USB0")
if os.path.exists('/dev/ttyUSB1') == True and gpsfound == 2:
   gpsfound = 1
   ser = serial.Serial('/dev/ttyUSB1',4800,timeout = 10)
else:
   if gpsfound == 2:
      print ("No GPS RX found on USB1")
      
if gpsfound < 2:   
   Months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
   MDays = [31,28,31,30,31,30,31,31,30,31,30,31]
   count1 = 1
   locked = 0
   found = 0
   while locked == 0 and count1 <= count:
      gps = ser.readline()
      if sys.version_info[0] == 3:
         gps = gps.decode("utf-8","ignore")
      if gps[1 : 6] == "GPGGA" or gps[1 : 6] == "GPRMC":
         print (gps)
         if found == 0:
            print ("GPS RX found on USB" + str(gpsfound))
            print ("Waiting for lock....")
            found = 1
         if gps[1 : 6] == "GPGGA" and int(gps[43]) > 0 and gps[42] != "*":
            locked = 1
         if gps[1 : 6] == "GPRMC":
            gps2 = gps.split(',',12)
            if len(gps2[9]) == 6 and len(gps2[1]) == 10:
               locked = 2
            
      count1 +=1
   if count1 < count:
      if locked == 1:
         print ("Locked")
      else:
         print ("Not locked but time and date found")
   else:
      print ("Signal Unlocked, aborted time setting")

   count2 = 1
   cday = 0
   Leap = 0
   while settime == 0 and count1 <= count and count2 <= count:
      gps = ser.readline()
      if sys.version_info[0] == 3:
         gps = gps.decode("utf-8","ignore")
      
      if gps[1 : 6] == "GPRMC":
         print (gps)
         gps2 = gps.split(',',12)
         fulldate = gps2[9]
         fulltime = gps2[1]
         clock = ":" + fulltime[2:4] + ":" + fulltime[4:6]
         Hour = int(fulltime[0:2])
         Hour = Hour + TimeOffset
         if Hour > 23:
            Hour = Hour - 24
            cday = 1
         if Hour < 0:
            Hour = Hour + 24
            cday = -1
         Hour = str(Hour).zfill(2)
         Year = int(fulldate[4:6])
         Mon = int(fulldate[2:4])
         Day = int(fulldate[0:2])
         if cday == 1:
            Day = Day + 1
            if Day > MDays[Mon-1]:
               Mon = Mon + 1
               Day = 1
               if Mon > 12:
                  Year = Year + 1
                  Mon = 1
         if cday == -1:
            Day = Day - 1
            if Day < 1:
               Mon = Mon - 1
               Day = MDays[Mon-1]
               if Mon < 1:
                  Year = Year - 1
                  Mon = 12
                  Day = MDays[Mon-1]

         Month = Months[Mon-1]
         Day = str(Day)
         Years = "20" + str(Year)
         path = "sudo date -s '" + str(Day) + " " + Month + " " + Years + " " + Hour + clock + "'"
         print (path)
         os.system (path)
         settime = 1
      count2 +=1

if settime == 1:
   print ("Time set with Time Offset to UTC " + str(TimeOffset) + " Hour(s)")
else:
   print ("Unable to set time")


Return to “Python”