1

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.

asked May 2, 2022 at 21:32
6
  • 1
    Have you looked at using gpsd (rather than reading the raw device) to make everything easier? If you already have gpsd then sudo gpsctl -n resets the GPS device so that raw access works. forums.raspberrypi.com/viewtopic.php?t=331525 Commented May 2, 2022 at 21:37
  • 1
    Serial sends/receives byte data. You need to convert to/from Unicode. Commented May 2, 2022 at 22:10
  • Milliways: Please excuse my ignorance. What would the PYTHON code look like to convert the data received into a useable format? Commented May 2, 2022 at 22:19
  • Dougie. I am stuck on the PYTHON code: mport gps3. What library do I need to install? Commented May 2, 2022 at 22:21
  • "What would the PYTHON code look like to convert the data received into a useable format?" this is a programming question - best asked on stackoverflow.com, but they expect people to do some research - there will be thousands of examples. In your case a basic python course. You ALSO need to know what the device outputs; I expect digits not strings. Commented May 3, 2022 at 2:02

1 Answer 1

3

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
answered May 2, 2022 at 21:41
1
  • 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. Commented May 2, 2022 at 21:54

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.