so i am now testing my GPS script on the pi-top[4] and it works with only changing the serial port from ttyTHS0 (xavier NX) to ttyAMA0 (pi-top)
So now i tried to add code to display it on the miniscreen and i get this when running in a virtualenv. any idea on this issue when using virtualenv’s?
When running in terminal without venv
the code i am running is this, its a little messy but will sort that later, its my plan to rework it
import io
import serial
from pitop.miniscreen import Miniscreen
ms = Miniscreen()
serialConf = serial.Serial('/dev/ttyAMA0', 9600, timeout=1.0, rtscts=True)
serialio = io.TextIOWrapper(io.BufferedRWPair(serialConf, serialConf))
# writes PMTK to the GPS device to specify what NMEA sentences to output
# shows GGA, GSA, RMC, ZDA
serialConf.write(b'$PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1*34\r\n')
# gps Variables
gpsFix = bool(False) # GPS Fix
gpsFxt = ''
gpsLat = '' # GPS Latitude
gpsLatDD = '' # GPS Latitude decimal
gpsLon = '' # GPS Longitude
gpsLonDD = '' # GPS Longitude Decimal
gpsDTS = '' # GPS Date Time Stamp
gpsSpd = '' # GPS Speed
gpsSat = 0 # Number of GPS Satelites
gpsAlt = '' # GPS Altitude
def fix(data):
#checks to see if GPS device has a fix
if data[0] == '$GPGSA':
global gpsFix, gpsFxt
gpsFix = True if int(data[2]) > 1 else False
gpsFxt = f'{data[2]}D' if int(data[2]) > 1 else ''
def speedCalc(data, u):
#converts speed to user required units
if u == 1:
return f'{round((float(data) * 1.150779448),1)} MPH'
elif u == 2:
return f'{round((float(data) * 1.852),1)} KM/H'
elif u == 3:
return f'{round((float(data) * 1.943844),1)} m/s'
else:
return f'{round(float(data),1)} kn'
def coordDecode(data, b):
#decodes lat and lon co-ordinates from GPS NMEA
return f"{data.split('.')[0][0:-2]}ᵒ {b} {data.split('.')[0][-2:]}.{data.split('.')[1]} mins"
def coordDecimal(data,b):
# converts GPS coords to decimal, used for logging and put into a map service
x = data.split('.')
if b == 'S' or b == 'W':
# makes the coord a negative if South or West
degs = float(f'-{x[0][0:-2]}')
mins = float(f'-{x[0][-2:]}')/60
secs = (60*float(f'-0.{x[1]}'))/3600
else:
# Keeps the coord a positive for North and East
degs = float(f'{x[0][0:-2]}')
mins = float(f'{x[0][-2:]}')/60
secs = (60*float(f'0.{x[1]}'))/3600
return round(float(degs+mins+secs),6)
def nmeaDecode(nmea):
# I know globals are bad, it just solves an issue at this time
global gpsLat, gpsLon, gpsLatDD, gpsLonDD, gpsFix, gpsDTS, gpsSat, gpsAlt, gpsSpd
if nmea[0] == '$GPZDA':
# gets the date and time from GPS
gpsDTS = f'{nmea[2]}-{nmea[3]}-{nmea[4]} {nmea[1][0:2]}:{nmea[1][2:4]}:{nmea[1][4:6]}'
elif nmea[0] == '$GPRMC':
#decodes lat and lon to degrees and mins
gpsLat = coordDecode(nmea[3], nmea[4])
gpsLon = coordDecode(nmea[5], nmea[6])
#converts GPS coords to decimal
gpsLatDD = coordDecimal(nmea[3], nmea[4])
gpsLonDD = coordDecimal(nmea[5], nmea[6])
# for speed, it can be calculated in MPH, KM/H, m/s Knots
# 1 = MPH | 2 = KM/H | 3 = m/s | any other no. for knots
gpsSpd = speedCalc(nmea[7], 1)
elif nmea[0] == '$GPGGA':
# gets number of satelites in use
gpsSat = int(nmea[7])
gpsAlt = f'{nmea[9]} {nmea[10]}'
#elif nmea[0] == '$GPGSA':
# return nmea
while 1:
try:
sentence = serialio.readline().strip().split(',')
if gpsFix:
#once GPS has fix, get GPS info
nmeaDecode(sentence)
print(f'''
Lat :\t {gpsLat} \tspeed :\t{gpsSpd}
Lon :\t{gpsLon} \tAltitude :\t{gpsAlt}
Time :\t{gpsDTS}\tFix :\t{'Yes' if gpsFix else 'No'}, {gpsFxt}, {gpsSat} Sats
''')
# Display Latituse on miniscreen
ms.display_multiline_text(f'Lat: {gpsLat}', font_size=10)
else:
# Check for GPS Fix
fix(sentence)
print(f'''
Lat :\t \tspeed :\t
Lon :\t \tAltitude :\t
Time :\t \tFix :\t{'Yes' if gpsFix else 'No'}
''')
except serial.SerialException as e:
print(f'Device error: {e}')
break
except UnicodeDecodeError:
continue```