I tend to use the pynmea2 library to parse the GPS data:
import serial,time,pynmea2
port = '/dev/serial0'
baud = 9600
serialPort = serial.Serial(port, baudrate = baud, timeout = 0.5)
while True:
str = ''
try:
str = serialPort.readline().decode().strip()
except Exception as e:
print(e)
#print(str)
if str.find('GGA') > 0:
try:
msg = pynmea2.parse(str)
print(msg.timestamp,'Lat:',round(msg.latitude,6),'Lon:',round(msg.longitude,6),'Alt:',msg.altitude,'Sats:',msg.num_sats)
except Exception as e:
print(e)
time.sleep(0.1)
If using a USB GPS check the Pi has detected with dmesg:
pi@raspberrypi:~ $ dmesg
[243897.914645] usb 1-1.1: USB disconnect, device number 21
[243917.925037] usb 1-1.1: new full-speed USB device number 22 using xhci_hcd
[243918.059453] usb 1-1.1: New USB device found, idVendor=1546, idProduct=01a8, bcdDevice= 3.01
[243918.059461] usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[243918.059467] usb 1-1.1: Product: u-blox GNSS receiver
[243918.059472] usb 1-1.1: Manufacturer: u-blox AG - www.u-blox.com
[243918.062126] cdc_acm 1-1.1:1.0: ttyACM0: USB ACM device
Check your GPS is in NMEA mode (i'm using ttyACM0). All of the GPS devices that I have used are either already in this mode or automatically switch to NMEA when I start reading serial data:
pi@raspberrypi:~ $ gpsctl
/dev/ttyACM0 identified as a NMEA0183 at 9600 baud.
Or specify port:
pi@raspberrypi:~ $ gpsctl /dev/ttyACM0
/dev/ttyACM0 identified as a NMEA0183 at 9600 baud.
Or with debug mode and specify port:
pi@raspberrypi:~ $ gpsctl -D 4 /dev/ttyACM0
libgps: gps_sock_open(localhost, 2947)
libgps: netlib_connectsock() returns socket on fd 3
libgps: gps_read() begins
libgps: gps_unpack({"class":"VERSION","release":"3.17","rev":"3.17","proto_major":3,"proto_min)r":12}
libgps: gps_unpack() segment parse '{"class":"VERSION","release":"3.17","rev":"3.17","proto_ma'or":3,"proto_minor":12}
flags: (0x10000000) {VERSION}
VERSION: release=3.17 rev=3.17 proto=3.12
libgps: final flags: (0x10000000) (null)
libgps: gps_read() -> 84 ({PACKET|VERSION})
libgps: gps_read() begins
libgps: gps_unpack({"class":"DEVICES","devices":[{"class":"DEVICE","path":"/dev/ttyACM0","driver":"NMEA0183","activated":"2022-05-03T10:46:53.009Z","flags":1,"native":0,"bps":9600,"parity")"N","stopbits":1,"cycle":1.00}]}
libgps: gps_unpack() segment parse '{"class":"DEVICES","devices":[{"class":"DEVICE","path":"/dev/ttyACM0","driver":"NMEA0183","activated":"2022-05-03T10:46:53.009Z","flags":1,"native":0,"b's":9600,"parity":"N","stopbits":1,"cycle":1.00}]}
flags: (0x100000) {DEVICELIST}
DEVICELIST:1 devices:
1: path='/dev/ttyACM0' driver='NMEA0183'
libgps: final flags: (0x100000) (null)
libgps: gps_read() -> 204 ({DEVICELIST|PACKET})
/dev/ttyACM0 identified as a NMEA0183 at 9600 baud.
libgps: gps_close()
pi@raspberrypi:~ $
If your GPS is in binary/native mode you will see something like:
pi@raspberrypi:~ $ gpsctl /dev/ttyACM0
/dev/ttyACM0 identified as a u-blox SW ROM CORE 3.01 (107888),HW 00080000,FWVER=SPG 3.01,PROTVER=18 at 9600 baud.
Or with debug info:
pi@raspberrypi:~ $ gpsctl -D 4 /dev/ttyACM0
libgps: gps_sock_open(localhost, 2947)
libgps: netlib_connectsock() returns socket on fd 3
libgps: gps_read() begins
)ibgps: gps_unpack({"class":"VERSION","release":"3.17","rev":"3.17","proto_major":3,"proto_minor":12}
'ibgps: gps_unpack() segment parse '{"class":"VERSION","release":"3.17","rev":"3.17","proto_major":3,"proto_minor":12}
flags: (0x10000000) {VERSION}
VERSION: release=3.17 rev=3.17 proto=3.12
libgps: final flags: (0x10000000) (null)
libgps: gps_read() -> 84 ({PACKET|VERSION})
libgps: gps_read() begins
libgps: gps_unpack({"class":"DEVICES","devices":[{"class":"DEVICE","path":"/dev/ttyACM0","driver":"u-blox","subtype":"SW ROM CORE 3.01 (107888),HW 00080000,FWVER=SPG 3.01,PROTVER=18","activated":"2022-05-03T11:08:01.042Z","flags":1,"native":0,"bps":9600,"parity":"N",")topbits":1,"cycle":1.00,"mincycle":0.25}]}
libgps: gps_unpack() segment parse '{"class":"DEVICES","devices":[{"class":"DEVICE","path":"/dev/ttyACM0","driver":"u-blox","subtype":"SW ROM CORE 3.01 (107888),HW 00080000,FWVER=SPG 3.01,PROTVER=18","activated":"2022-05-03T11:08:01.042Z","flags":1,"native":0,"bps":96'0,"parity":"N","stopbits":1,"cycle":1.00,"mincycle":0.25}]}
flags: (0x100000) {DEVICELIST}
DEVICELIST:1 devices:
1: path='/dev/ttyACM0' driver='u-blox'
libgps: final flags: (0x100000) (null)
libgps: gps_read() -> 294 ({DEVICELIST|PACKET})
/dev/ttyACM0 identified as a u-blox SW ROM CORE 3.01 (107888),HW 00080000,FWVER=SPG 3.01,PROTVER=18 at 9600 baud.
libgps: gps_close()
pi@raspberrypi:~ $
Switch to NMEA mode with:
pi@raspberrypi:~ $ gpsctl -n -D 4 /dev/ttyACM0
libgps: gps_sock_open(localhost, 2947)
libgps: netlib_connectsock() returns socket on fd 3
libgps: gps_read() begins
)ibgps: gps_unpack({"class":"VERSION","release":"3.17","rev":"3.17","proto_major":3,"proto_minor":12}
'ibgps: gps_unpack() segment parse '{"class":"VERSION","release":"3.17","rev":"3.17","proto_major":3,"proto_minor":12}
flags: (0x10000000) {VERSION}
VERSION: release=3.17 rev=3.17 proto=3.12
libgps: final flags: (0x10000000) (null)
libgps: gps_read() -> 84 ({PACKET|VERSION})
libgps: gps_read() begins
libgps: gps_unpack({"class":"DEVICES","devices":[{"class":"DEVICE","path":"/dev/ttyACM0","driver":"NMEA0183","activated":"2022-05-03T11:26:54)043Z","flags":1,"native":0,"bps":9600,"parity":"N","stopbits":1,"cycle":1.00}]}
libgps: gps_unpack() segment parse '{"class":"DEVICES","devices":[{"class":"DEVICE","path":"/dev/ttyACM0","driver":"NMEA0183","activated":"20'2-05-03T11:26:54.043Z","flags":1,"native":0,"bps":9600,"parity":"N","stopbits":1,"cycle":1.00}]}
flags: (0x100000) {DEVICELIST}
DEVICELIST:1 devices:
1: path='/dev/ttyACM0' driver='NMEA0183'
libgps: final flags: (0x100000) (null)
libgps: gps_read() -> 204 ({DEVICELIST|PACKET})
libgps: gps_read() begins
libgps: gps_unpack({"class":"DEVICE","path":"/dev/ttyACM0","driver":"NMEA0183","activated":"2022-05-03T11:26:58.045Z","flags":1,"native":0,"b)s":9600,"parity":"N","stopbits":1,"cycle":1.00}
libgps: gps_unpack() segment parse '{"class":"DEVICE","path":"/dev/ttyACM0","driver":"NMEA0183","activated":"2022-05-03T11:26:58.045Z","flags':1,"native":0,"bps":9600,"parity":"N","stopbits":1,"cycle":1.00}
flags: (0x180000) {DEVICE|DEVICELIST}
DEVICE: Device is '/dev/ttyACM0', driver is 'NMEA0183'
DEVICELIST:1 devices:
1: path='/dev/ttyACM0' driver='NMEA0183'
libgps: final flags: (0x180000) (null)
libgps: gps_read() -> 172 ({DEVICE|DEVICELIST|PACKET})
libgps: gps_close()
USB port may then be held by gpsd:
pi@raspberrypi:~ $ sudo lsof /dev/ttyACM0
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
Output information may be incomplete.
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
gpsd 537 gpsd 8u CHR 166,0 0t0 472 /dev/ttyACM0
Kill that gpsd process using the PID value with:
sudo kill 537
sudo gpsctl -n
resets the GPS device so that raw access works. forums.raspberrypi.com/viewtopic.php?t=331525