Using Python and a G-Mouse. The G-Mouse is a very poorly named device as it has the same name as an actual computer mouse by Logitech but go figure - it's likely a Chinese thing.
This mundane little device can be hooked up to a computer and used to find the location of the computer via the satellite Global Positioning System to within about 20 feet.#!/usr/bin/env python3# Original Code: https://gist.github.com/Lauszus/5785023#file-gps-py# Created by: Kristian Sloth Lauszusimport timeimport serialdef readString():while 1:while ser.read().decode("utf-8") != '$': # Wait for the begging of the stringpass # Do nothingline = ser.readline().decode("utf-8") # Read the entire stringreturn linedef getTime(string, format, returnFormat):return time.strftime(returnFormat,time.strptime(string, format)) # Convert date and time to a nice printable formatdef getLatLng(latString, lngString):lat = latString[:2].lstrip('0') + "." + "%.7s" % str(float(latString[2:]) * 1.0 / 60.0).lstrip("0.")lng = lngString[:3].lstrip('0') + "." + "%.7s" % str(float(lngString[3:]) * 1.0 / 60.0).lstrip("0.")return lat, lngdef printRMC(lines):print("========================================RMC========================================")# print(lines, '\n')print("Fix taken at:", getTime(lines[1] + lines[9], "%H%M%S.%f%d%m%y", "%a %b %d %H:%M:%S %Y"), "UTC")print("Status (A=OK,V=KO):", lines[2])latlng = getLatLng(lines[3], lines[5])print("Lat,Long: ", latlng[0], lines[4], ", ", latlng[1], lines[6], sep='')print("Speed (knots):", lines[7])print("Track angle (deg):", lines[8])print("Magnetic variation: ", lines[10], end='')if len(lines) == 13: # The returned string will be either 12 or 13 - it will return 13 if NMEA standard used is above 2.3print(lines[11])print("Mode (A=Autonomous, D=Differential, E=Estimated, N=Data not valid):", lines[12].partition("*")[0])else:print(lines[11].partition("*")[0])returndef printGGA(lines):print("========================================GGA========================================")# print(lines, '\n')print("Fix taken at:", getTime(lines[1], "%H%M%S.%f", "%H:%M:%S"), "UTC")latlng = getLatLng(lines[2], lines[4])print("Lat,Long: ", latlng[0], lines[3], ", ", latlng[1], lines[5], sep='')print("Fix quality (0 = invalid, 1 = fix, 2..8):", lines[6])print("Satellites:", lines[7].lstrip("0"))print("Horizontal dilution:", lines[8])print("Altitude: ", lines[9], lines[10], sep="")print("Height of geoid: ", lines[11], lines[12], sep="")print("Time in seconds since last DGPS update:", lines[13])print("DGPS station ID number:", lines[14].partition("*")[0])returndef printGSA(lines):print("========================================GSA========================================")# print(lines, '\n')print("Selection of 2D or 3D fix (A=Auto,M=Manual):", lines[1])print("3D fix (1=No fix,2=2D fix, 3=3D fix):", lines[2])print("PRNs of satellites used for fix:", end='')for i in range(0, 12):prn = lines[3 + i].lstrip("0")if prn:print(" ", prn, end='')print("\nPDOP", lines[15])print("HDOP", lines[16])print("VDOP", lines[17].partition("*")[0])returndef printGSV(lines):if lines[2] == '1': # First sentenceprint("========================================GSV========================================")else:print("===================================================================================")# print(lines, '\n')print("Number of sentences:", lines[1])print("Sentence:", lines[2])print("Satellites in view:", lines[3].lstrip("0"))for i in range(0, int(len(lines) / 4) - 1):print("Satellite PRN:", lines[4 + i * 4].lstrip("0"))print("Elevation (deg):", lines[5 + i * 4].lstrip("0"))print("Azimuth (deg):", lines[6 + i * 4].lstrip("0"))print("SNR (higher is better):", lines[7 + i * 4].partition("*")[0])returndef printGLL(lines):print("========================================GLL========================================")# print(lines, '\n')latlng = getLatLng(lines[1], lines[3])print("Lat,Long: ", latlng[0], lines[2], ", ", latlng[1], lines[4], sep='')print("Fix taken at:", getTime(lines[5], "%H%M%S.%f", "%H:%M:%S"), "UTC")print("Status (A=OK,V=KO):", lines[6])if lines[7].partition("*")[0]: # Extra field since NMEA standard 2.3print("Mode (A=Autonomous, D=Differential, E=Estimated, N=Data not valid):", lines[7].partition("*")[0])returndef printVTG(lines):print("========================================VTG========================================")# print(lines, '\n')print("True Track made good (deg):", lines[1], lines[2])print("Magnetic track made good (deg):", lines[3], lines[4])print("Ground speed (knots):", lines[5], lines[6])print("Ground speed (km/h):", lines[7], lines[8].partition("*")[0])if lines[9].partition("*")[0]: # Extra field since NMEA standard 2.3print("Mode (A=Autonomous, D=Differential, E=Estimated, N=Data not valid):", lines[9].partition("*")[0])returndef checksum(line):checkString = line.partition("*")checksum = 0for c in checkString[0]:checksum ^= ord(c)try: # Just to make sureinputChecksum = int(checkString[2].rstrip(), 16);except:print("Error in string")return Falseif checksum == inputChecksum:return Trueelse:print("=====================================================================================")print("===================================Checksum error!===================================")print("=====================================================================================")print(hex(checksum), "!=", hex(inputChecksum))return Falseif __name__ == '__main__':ser = serial.Serial('/dev/ttyACM0', 9600, timeout=1) # Open Serial porttry:while True:line = readString()lines = line.split(",")if checksum(line):if lines[0] == "GPRMC":printRMC(lines)passelif lines[0] == "GPGGA":printGGA(lines)passelif lines[0] == "GPGSA":# printGSA(lines)passelif lines[0] == "GPGSV":# printGSV(lines)passelif lines[0] == "GPGLL":printGLL(lines)passelif lines[0] == "GPVTG":printVTG(lines)passelse:print("\n\nUnknown type:", lines[0], "\n\n")except KeyboardInterrupt:print('Exiting Script')
If that doesn't work for you then try the following...
sudo apt-get install gpsd gpsd-clients
Then
sudo cat /dev/ttyACM0
That should get you a result.
The results produced by the Python code are as follows
========================================RMC========================================
Fix taken at: Tue Feb 08 15:41:16 2022 UTC
Status (A=OK,V=KO): A
Lat,Long: 47.8076043N, 7.2157055W
Speed (knots): 0.437
Track angle (deg):
Magnetic variation:
Mode (A=Autonomous, D=Differential, E=Estimated, N=Data not valid): A
========================================VTG========================================
True Track made good (deg): T
Magnetic track made good (deg): M
Ground speed (knots): 0.437 N
Ground speed (km/h): 0.809 K
Mode (A=Autonomous, D=Differential, E=Estimated, N=Data not valid): A
========================================GGA========================================
Fix taken at: 15:41:16 UTC
Lat,Long: 47.8076043N, 7.2157055W
Fix quality (0 = invalid, 1 = fix, 2..8): 1
Satellites: 3
Horizontal dilution: 4.91
Altitude: 67.4M
Height of geoid: -32.3M
Time in seconds since last DGPS update:
DGPS station ID number:
========================================GLL========================================
Lat,Long: 47.8076043N, 7.2157055W
Fix taken at: 15:41:16 UTC
Status (A=OK,V=KO): A
Mode (A=Autonomous, D=Differential, E=Estimated, N=Data not valid): A
It can take a few minutes for the GPS mouse to lock onto satellites and produce a result so don't be upset if the Python code crashes the first few times you try to run it.