Hi All,
Precis:
We have a rover project and have established comms to the GPS unit on the serial port.
Q:
What is best practice for capturing GPS data from the serial port.
Problem:
The serial port is a little flakey, in that if we keep capturing data, at some point we get an error:
Background and what we have tried:
In the first version of the code, we capture everything that comes in on that port:We call that function at about 5Hz and pipe everything to a gps_data.csv file and then parse it later.
There is a lot of garbage in that file. we get about 7 of these:
It sorta works, but it takes a few seconds (like 7 to 10) to return a GGA line.
And I also want the b'$GPRMC data.
I tried running a for loop to step through each of the GPS Message Types that I want, but the loop takes so long, that it crashes out with the serial port error above. 20 seconds is enough for the port to error.
So, my questions:
1) Is this normal for a serial port to crash out like that?
2) Is there some way to make the code robust against the error?
3) What is best practice with GPS:
* Log it to a file and parse it later?
* Parse it as you go and only return the data we need?
Thanks heaps if you read this far.
Any insight gratefully accepted.
Precis:
We have a rover project and have established comms to the GPS unit on the serial port.
Q:
What is best practice for capturing GPS data from the serial port.
Problem:
The serial port is a little flakey, in that if we keep capturing data, at some point we get an error:
Our workaround has been to capture data in short bursts 5 seconds or 10 seconds.serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)
Background and what we have tried:
In the first version of the code, we capture everything that comes in on that port:
Code:
GPS = serial.Serial("/dev/serial0", baudrate=9600, timeout=0.5) # opening this port needs sudodef get_gps_data(): raw_gps_data = GPS.readline() # this is the line that generates the error str_gps_data = str(raw_gps_data).strip() # strip() takes out the newline and whitespaces return(str_gps_data) # the data is in CSV format There is a lot of garbage in that file. we get about 7 of these:
for every viableb'$GPTXT,01,01,01,NMEA unknown msg*58\n
So what I have been trying to do now is to parse each line as it comes in GPS.readline() and return for example just the $GPGGA data.b'$GPGGA,134449.00,1223.78794,S,13051.17915,E,2,10,0.77,24.5,M,46.8,M,,0000*7F\n'
Code:
def get_GPS_msg(msg_type): # if find eg "GGA" in raw_gps_data then return the line as a CSV Comma Separated Values list. while True: raw_gps_data = GPS.readline() gps_data_str = raw_gps_data.decode('utf-8').strip() # remove newlines whitespaces and make a string. index = gps_data_str.find(msg_type) if index != -1: print(gps_data_str) break else: time.sleep(0.2) return(gps_data_str) # GGA CSV list elements are # 0 = $GPGGA , 1 = UTC, 2 = Lat , 3 = NS, 4 = Long , 5 = EW , 6 = (0 = not valid, 1 = GPS fix) , 7 = NumSats , 8 = HDOP , 9 = Height , 10 = Meters , 11 = Geoid Sep , 12 = Meters , 13 = age , 14 = ref stn , 15 = *checksumIt sorta works, but it takes a few seconds (like 7 to 10) to return a GGA line.
And I also want the b'$GPRMC data.
I tried running a for loop to step through each of the GPS Message Types that I want, but the loop takes so long, that it crashes out with the serial port error above. 20 seconds is enough for the port to error.
Code:
def main(): gps_msg_types = ["GGA","RMC","GST","GSV","GLL","ROT","TXT","GSA","VTG","DTM"] for msg_type in range(len(gps_msg_types)): get_GPS_msg(gps_msg_types[msg_type])1) Is this normal for a serial port to crash out like that?
2) Is there some way to make the code robust against the error?
3) What is best practice with GPS:
* Log it to a file and parse it later?
* Parse it as you go and only return the data we need?
Thanks heaps if you read this far.
Any insight gratefully accepted.
Statistics: Posted by gabby SLAMprobe — Sun Jun 01, 2025 5:29 am