I am using a NEO-8M Satellite Positioning Module on a Raspberry PI. I am trying to read data off the device using python. I am new to the Raspberry PI and Python. I can read data from the NEO-8M GPS module. My code is as follows:
import serial
gps = serial.Serial("/dev/serial0", baudrate=9600, timeout=0.5)
myRawData = gps.readline()
print(myRawData)
myOutputData = str(myRawData)
print(myOutputData)
The output data is as follows:
b'\xb5b\x01\x07\\\x00\xb0\xc7P\x00\xdf\x07\n'
b'\xb5b\x01\x07\\\x00\xb0\xc7P\x00\xdf\x07\n'
I cannot identify the format that the string is in. I am not sure how to convert the data to a string for further processing.
Any help would be appreciated.
Solved. Shout out to "Dougie". His suggestion to use gpsd has negated my problem.
1 Answer 1
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月03日T10: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月03日T10: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月03日T11: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月03日T11: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月03日T11: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月03日T11: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月03日T11: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
-
I have implemented your code "as is". And get the following error message: 'utf-8' codec can't decode byte 0xf0 in position 4: invalid continuation byte 'utf-8' codec can't decode byte 0xb5 in position 0: invalid start byte This is my problem, I cannot read the string in a useable format.Herman Badenhorst– Herman Badenhorst2022年05月02日 21:54:36 +00:00Commented May 2, 2022 at 21:54
sudo gpsctl -n
resets the GPS device so that raw access works. forums.raspberrypi.com/viewtopic.php?t=331525