Skip to content

Instantly share code, notes, and snippets.

@jiemde
Forked from aldrinleal/gpsdecoder.py
Created June 27, 2017 18:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jiemde/dbde1f9045d5e06cedd693f20b4ab7b4 to your computer and use it in GitHub Desktop.
Save jiemde/dbde1f9045d5e06cedd693f20b4ab7b4 to your computer and use it in GitHub Desktop.
pytrack gps decoder
class GPSDecoder:
def __init__(self, i2c=None):
if i2c is None:
from machine import I2C
i2c = I2C(0, mode=I2C.MASTER, pins=('G9', 'G8'))
self.i2c = i2c
self.buf = ""
self.clear()
def clear(self):
self.fixStatus = self.lat = self.lng = self.utcTime = None
self.pdop = self.hdop = self.vdop = None
self.alt = self.geoid = None
self.cogT = self.cogM = self.speedKnots = self.speedKm = None
self.utcDate = None
def to_decimal(self, pos, mod):
import math
dotoffset = pos.find('.')
if 4 == dotoffset:
d, m = (pos[0:2], pos[2:])
elif 5 == dotoffset:
d, m = (pos[0:3], pos[3:])
d = float(d)
m = float(m)
r = m / 60.0
result = (d + r)
if -1 != "SW".rfind(mod):
result *= -1.0
return result
def hasPosition(self):
result = None != self.fixStatus
result &= None != self.lat
result &= None != self.lng
result &= None != self.utcTime
result &= None != self.pdop
result &= None != self.hdop
result &= None != self.vdop
result &= None != self.alt
result &= None != self.geoid
result &= None != self.fixStatus
result &= None != self.utcDate
#result &= None != self.cogT
#result &= None != self.cogM
#result &= None != self.speedKnots
#result &= None != self.speedKm
return result
def parse(self):
from utime import sleep_ms
from math import modf
received = self.i2c.readfrom(0x10, 255)
self.buf += received.decode("utf8")
lines = self.buf.split("\n")
off = 0
for line in lines:
# if len(line) > 2:
# print("line trailer: %s" % hexlify(line[-2:]))
off += len(line) + 2
exclude = False
if not line:
exclude = True
elif len(line) <= 1:
exclude = True
elif '$' != line[0]:
exclude = True
elif line[-1:] != "\r":
exclude = True
if exclude:
self.buf = self.buf[off:]
continue
if len(self.buf) > 1024:
self.buf = self.buf[1+self.buf.rfind("\n"):]
line = line.strip()
lastAsterisk = line.rfind('*')
if -1 != lastAsterisk:
line = line[:lastAsterisk]
args = line.split(",")
command = args[0]
if command[-3:] == "GLL":
lat = args[1]
ns = args[2]
lng = args[3]
ew = args[4]
utcTime = args[5]
dataValid = args[6]
positioningMode = args[7]
self.lat = self.to_decimal(lat, ns)
self.lng = self.to_decimal(lng, ew)
self.utcTime = utcTime
elif command[-3:] == "GSA":
self.fixStatus = args[2]
self.pdop = float(args[-3])
self.hdop = float(args[-2])
self.vdop = float(args[-1])
elif command[-3:] == "GSV":
# Ignored. Pura Groselha.
pass
elif command[-3:] == "GGA":
self.utcTime = args[1]
self.lat = self.to_decimal(args[2], args[3])
self.lng = self.to_decimal(args[4], args[5])
self.fixStatus = args[6]
self.hdop = float(args[8])
self.alt = float(args[9])
self.geoid = float(args[11])
elif command[-3:] == "VTG":
#print("args:%s" % repr(args))
if 0 != len(args[1]):
self.cogT = float(args[1])
if 0 != len(args[3]):
self.cogM = float(args[3])
self.speedKnots = float(args[5])
self.speedKm = float(args[7])
self.fixStatus = args[9][0]
elif command[-3:] == "RMC":
valid = args[2]
if "A" == valid:
self.utcTime = args[1]
self.lat = self.to_decimal(args[3], args[4])
self.lng = self.to_decimal(args[5], args[6])
self.speedKnots = float(args[7])
self.cogM = float(args[8])
self.utcDate = args[9]
self.fixStatus = args[12][0]
else:
print("Not parsed: %s" % repr(args))
self.buf = self.buf[off:]
# TODO: Use just the time difference instead of a fixed value
sleep_ms(500)
return self.hasPosition()
d = GPSDecoder()
while not d.parse():
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment