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.
This project was carried out on a laptop running Linux Mint. There are some things to do first or the whole thing won't work,
First... Install Putty on Linux.
Then REBOOT the computer so that it'll take effect.
That will gain you access to the serial port.
The following software (copied) from GitHub will read your GPS...
#!/usr/bin/env python3
# Original Code: https://gist.github.com/Lauszus/5785023#file-gps-py
# Created by: Kristian Sloth Lauszus
import time
import serial
def readString():
while 1:
while ser.read().decode("utf-8") != '$': # Wait for the begging of the string
pass # Do nothing
line = ser.readline().decode("utf-8") # Read the entire string
return line
def getTime(string, format, returnFormat):
return time.strftime(returnFormat,
time.strptime(string, format)) # Convert date and time to a nice printable format
def 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, lng
def 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.3
print(lines[11])
print("Mode (A=Autonomous, D=Differential, E=Estimated, N=Data not valid):", lines[12].partition("*")[0])
else:
print(lines[11].partition("*")[0])
return
def 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])
return
def 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])
return
def printGSV(lines):
if lines[2] == '1': # First sentence
print("========================================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])
return
def 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.3
print("Mode (A=Autonomous, D=Differential, E=Estimated, N=Data not valid):", lines[7].partition("*")[0])
return
def 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.3
print("Mode (A=Autonomous, D=Differential, E=Estimated, N=Data not valid):", lines[9].partition("*")[0])
return
def checksum(line):
checkString = line.partition("*")
checksum = 0
for c in checkString[0]:
checksum ^= ord(c)
try: # Just to make sure
inputChecksum = int(checkString[2].rstrip(), 16);
except:
print("Error in string")
return False
if checksum == inputChecksum:
return True
else:
print("=====================================================================================")
print("===================================Checksum error!===================================")
print("=====================================================================================")
print(hex(checksum), "!=", hex(inputChecksum))
return False
if __name__ == '__main__':
ser = serial.Serial('/dev/ttyACM0', 9600, timeout=1) # Open Serial port
try:
while True:
line = readString()
lines = line.split(",")
if checksum(line):
if lines[0] == "GPRMC":
printRMC(lines)
pass
elif lines[0] == "GPGGA":
printGGA(lines)
pass
elif lines[0] == "GPGSA":
# printGSA(lines)
pass
elif lines[0] == "GPGSV":
# printGSV(lines)
pass
elif lines[0] == "GPGLL":
printGLL(lines)
pass
elif lines[0] == "GPVTG":
printVTG(lines)
pass
else:
print("\n\nUnknown type:", lines[0], "\n\n")
except KeyboardInterrupt:
print('Exiting Script')
If that doesn't work for you then try the following...
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.