This code below defines the system without any of this
Tested with Neo 6M GPS Module and Raspberry Pi B
(Python 2.7.9)
Note: this module already has RTC and a battery, you do not need to use DS1307 DS3231 etc.
This gps module tells the date and time in UTC, then the system will be set to UTC.
The system must be preconfigured with your location

Save code in file /home/pi/GPSupdate.py
To run:
$sudo python /home/pi/GPSupdate.py
Note: At interrupt this code with CTRL+C all applications python will stopped, see last lines (killall -9 python)
See:
http://www.gpsinformation.org/dale/nmea.htm#nmea
https://www.u-blox.com/en/evaluation-software-and-tools
https://www.u-blox.com/sites/default/fi ... 005%29.pdf
https://www.u-blox.com/sites/default/fi ... 018%29.pdf (Pag. 63/75: 20.10 RMC)
[RMC] Recommended Minimum data
Message Structure:
$GPRMC,hhmmss,status,latitude,N,longitude,E,spd,cog,ddmmyy,mv,mvE,mode*cs<CR><LF>
Example:
$GPRMC,083559.00,A,4717.11437,N,00833.91522,E,0.004,77.52,091202,,,A*57
Checksum at the end of each sentence: The checksum field consists of a '*' and two hex digits representing an 8 bit exclusive OR of all characters between, but not including, the '$' and '*'
Code: Select all
# -*- coding: utf-8 -*-
import datetime
import serial # http://pyserial.readthedocs.io/en/latest/pyserial.html
import time
from time import sleep
from threading import Thread
import os
import subprocess
import socket
#see http://www.gpsinformation.org/dale/nmea.htm#nmea
# DEVICE = '/dev/ttyUSB0'
DEVICE = '/dev/ttyAMA0'
DataBytes = ""
GpsUpdateInterval = 15 # minute
showGpsData = True
showUpdateMessage = True
def GpsDateTimeUpdate():
global portRpi
global DataBytes
global showGpsData
global showUpdateMessage
global GpsUpdateInterval
countTime = GpsUpdateInterval
minuteOld = 0
updateEnable = False
while True:
minuteNow = time.strftime("%M")
if minuteOld != minuteNow:
minuteOld = minuteNow
countTime += 1
if countTime > GpsUpdateInterval:
countTime = 0
updateEnable = True
portRpi.reset_input_buffer()
if updateEnable:
if portRpi.isOpen():
DataBytes = DataBytes + portRpi.read()
if chr(13) in DataBytes:
if chr(10) in DataBytes:
DataBytes = DataBytes.replace(chr(10), "")
if chr(13) in DataBytes:
DataBytes = DataBytes.replace(chr(13), "")
list1 = DataBytes.split(',')
if (len(list1) == 13):
if((list1[0] == "$GPRMC") &
(len(list1[1]) == 9) &
(len(list1[9]) == 6)):
if(showGpsData):
print DataBytes
print
checksum = 0
for char in range(DataBytes.index('$') + 1,
DataBytes.index('*')):
checksum = (checksum ^ ord(DataBytes[char]))
list2 = list1[len(list1) - 1].split('*')
if len(list2) == 2:
if int(list2[1], 16) == checksum:
hourGPS = int(list1[1][:2])
minuteGPS = int(list1[1][2:4])
secondGPS = int(list1[1][4:6])
dayGPS = int(list1[9][:2])
monthGPS = int(list1[9][2:4])
yearGPS = int(list1[9][4:6])
setDateTimeUTC(yearGPS,
monthGPS,
dayGPS,
hourGPS,
minuteGPS,
secondGPS)
updateEnable = False
minuteNow = time.strftime("%M")
minuteOld = minuteNow
if showUpdateMessage:
print 'GPS update now'
if(list1[2] == "A"):
print 'Satellite mode'
else:
print 'Local RTC mode'
print
DataBytes = ""
else:
sleep(0.1)
def setDateTimeUTC2(seconds_epoch):
command_wait('date -u -s "@' + str(seconds_epoch) + '"')
def setDateTimeUTC(year, month, day, hour, minute, second):
strUTCyear2set = str(year)
strUTCmonth2set = str(month)
strUTCday2set = str(day)
strUTChour2set = str(hour)
strUTCminute2set = str(minute)
strUTCsecond2set = str(second)
if(len(strUTCyear2set) < 4):
strUTCyear2set = str(year + 2000)
if(len(strUTCmonth2set) < 2):
strUTCmonth2set = '0' + strUTCmonth2set
if(len(strUTCday2set) < 2):
strUTCday2set = '0' + strUTCday2set
if(len(strUTChour2set) < 2):
strUTChour2set = '0' + strUTChour2set
if(len(strUTCminute2set) < 2):
strUTCminute2set = '0' + strUTCminute2set
if(len(strUTCsecond2set) < 2):
strUTCsecond2set = '0' + strUTCsecond2set
command_wait('date -u +%Y%m%d -s "' + strUTCyear2set +
strUTCmonth2set +
strUTCday2set + '"')
command_wait('date -u +%T -s "' + strUTChour2set + ':' +
strUTCminute2set + ':' +
strUTCsecond2set + '"')
seconds_epoch = time.mktime(datetime.datetime.now().timetuple())
seconds_epoch += 3
setDateTimeUTC2(seconds_epoch)
def command_wait(command):
## command = "sudo mount /dev/sda1 /mnt/usb"
process = subprocess.Popen(command,
shell=True,
stdout=subprocess.PIPE)
process.wait()
if(process.returncode != 0):
print 'command wait - error: '
print process.returncode
def command_nowait(command):
## command = "sudo mount /dev/sda1 /mnt/usb"
#process = subprocess.Popen(command,
# shell=True,
# stdout=subprocess.PIPE)
subprocess.Popen(command,
shell=True,
stdout=subprocess.PIPE)
## process.wait()
## print process.returncode
def MyIP():
print("IP: " + get_ip())
def get_ip():
s = socket.socket(socket.AF_INET,
socket.SOCK_DGRAM)
try:
# doesn't even have to be reachable
s.connect(('8.8.8.8', 0))
IP = s.getsockname()[0]
except:
IP = '127.0.0.1'
finally:
s.close()
return IP
#command_wait("echo " + IP + " > /tmp/relogio.log")
if __name__ == '__main__':
print 'Start update system DateTime from GPS'
MyIP()
print 'UTC: ' + str(datetime.datetime.utcnow())
print 'Local: ' + str(datetime.datetime.now())
print 'Test --> set UTC DateTime: 2016/01/01 12:00:00'
setDateTimeUTC(2016, 1, 1, 12, 0, 0)
if os.path.exists(DEVICE):
try:
portRpi = serial.Serial(DEVICE,
timeout=None,
baudrate=9600,
xonxoff=False,
rtscts=False,
dsrdtr=False)
except ValueError:
print('Error: Serial Port')
Thread1 = Thread(target=GpsDateTimeUpdate)
Thread1.start()
secondOld = 0
while True:
try:
secondNow = time.strftime("%S")
if secondOld != secondNow:
secondOld = secondNow
print 'UTC: ' + str(datetime.datetime.utcnow())
print 'Local: ' + str(datetime.datetime.now())
print
sleep(0.1)
except (KeyboardInterrupt, SystemExit):
command_nowait("killall -9 python")
Using Ninja IDE to edit:
http://ninja-ide.org/