[solved] pi-top sdk issue in virtualenv

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```

hey @CAProjects! the issue is because of a missing package. Try installing libatlas-base-dev (sudo apt install libatlas-base-dev -y) and let us know how it goes!

2 Likes

Thanks @pi-topJorge worked a treat, its displaying on the miniscreen in venv now :stuck_out_tongue: