In this video tutorial we develop a GPS tracker based on the Raspberry Pi Pico W and the Adafruit Ultimate GPS V3. We include a SSD1305 OLED display. The project will use the schematic below:

For your convenience, the code we developed in the video is included below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | from machine import Pin,I2C,UART import time import _thread from ssd1306 import SSD1306_I2C i2c2 = I2C(1, sda=Pin(2), scl=Pin(3), freq=400000) dsp = SSD1306_I2C(128,64,i2c2) dataLock = _thread.allocate_lock() keepRunning = True GPS = UART(1, baudrate=9600, tx=machine.Pin(8), rx=machine.Pin(9)) #The following line ensures that the GPS reports the GPVTG NMEA Sentence GPS.write(b"$PMTK314,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n") NMEAdata = { 'GPGGA' : "", 'GPGSA' : "", 'GPRMC' : "", 'GPVTG' : "" } GPSdata = { 'latDD' : 0, 'lonDD' : 0, 'heading' : 0, 'fix' : False, 'sats' : 0, 'knots' : 0 } def gpsThread(): print("Thread Running") global keepRunning,NMEAdata GPGGA = "" GPGSA = "" GPRMC = "" GPVTG = "" while not GPS.any(): pass while GPS.any(): junk = GPS.read() print(junk) myNMEA = "" while keepRunning: if GPS.any(): myChar=GPS.read(1).decode('utf-8') myNMEA = myNMEA + myChar if myChar == '\n': myNMEA = myNMEA.strip() if myNMEA[1:6] == "GPGGA": GPGGA = myNMEA if myNMEA[1:6] == "GPGSA": GPGSA = myNMEA if myNMEA[1:6] == "GPRMC": GPRMC = myNMEA if myNMEA[1:6] == "GPVTG": GPVTG = myNMEA if GPGGA != "" and GPGSA!="" and GPRMC!="" and GPVTG!="": dataLock.acquire() NMEAdata = { 'GPGGA' : GPGGA, 'GPGSA' : GPGSA, 'GPRMC' : GPRMC, 'GPVTG' : GPVTG } dataLock.release() myNMEA = "" print("Thread Terminated Cleanly") def parseGPS(): readFix=int(NMEAmain['GPGGA'].split(',')[6]) if readFix !=0: GPSdata['fix'] = True latRAW = NMEAmain['GPGGA'].split(',')[2] latDD = int(latRAW[0:2]) + float(latRAW[2:])/60 if NMEAmain['GPGGA'].split(',')[3] == 'S': latDD = -latDD GPSdata['latDD']= latDD lonRAW=NMEAmain['GPGGA'].split(',')[4] lonDD=int(lonRAW[0:3]) + float(lonRAW[3:])/60 if NMEAmain['GPGGA'].split(',')[5] == 'W': lonDD = -lonDD GPSdata['lonDD'] = lonDD heading = float(NMEAmain['GPRMC'].split(',')[8]) GPSdata['heading'] = heading knots = float(NMEAmain['GPRMC'].split(',')[7]) GPSdata['knots'] = knots sats = NMEAmain['GPGGA'].split(',')[7] GPSdata['sats'] = sats def dispOLED(): dsp.fill(0) if GPSdata['fix'] == False: dsp.text("Waiting for Fix . . .",0,0) if GPSdata['fix'] == True: dsp.text("ULTIMATE GPS: ", 0,0) dsp.text("LAT: "+str(GPSdata['latDD']),0,16) dsp.text("LON: "+str(GPSdata['lonDD']),0,26) dsp.text("SPEED: "+str(GPSdata['knots'])+' Knts',0,36) dsp.text("HEAD: "+str(GPSdata['heading'])+'deg.',0,46) dsp.text("SATS: "+str(GPSdata['sats']),0,56) dsp.show() _thread.start_new_thread(gpsThread,()) time.sleep(2) try: while True: dataLock.acquire() NMEAmain = NMEAdata.copy() dataLock.release() parseGPS() if GPSdata['fix'] == False: print("Waiting for Fix . . .") if GPSdata['fix'] == True: print("Ultimate GPS Tracker Report: ") print("Lat and Lon: ",GPSdata['latDD'],GPSdata['lonDD']) print("Knots: ",GPSdata['knots']) print("Heading: ",GPSdata['heading']) print("Sats: ",GPSdata['sats']) print() dispOLED() time.sleep(10) except KeyboardInterrupt: print("\nStopping Program . . . Cleaning Up UART") keepRunning = False time.sleep(1) GPS.deinit() time.sleep(1) dsp.fill(0) dsp.show() print("Exited Cleanly") |