Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 8597

Troubleshooting • GPS data stream: Capture GGA or capture all?

$
0
0
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:
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)
Our workaround has been to capture data in short bursts 5 seconds or 10 seconds.

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    
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:
b'$GPTXT,01,01,01,NMEA unknown msg*58\n
for every viable
b'$GPGGA,134449.00,1223.78794,S,13051.17915,E,2,10,0.77,24.5,M,46.8,M,,0000*7F\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.

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 = *checksum

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.

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])
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.

Statistics: Posted by gabby SLAMprobe — Sun Jun 01, 2025 5:29 am



Viewing all articles
Browse latest Browse all 8597

Trending Articles