pyubx2: Configuring receiver -> then UBXReader stops reading after several succesful readings (F9P)

Firstly I want to thank you for the effort you put into creating this library - it’s AWESOME and you are GREAT! 😄

My config:

u-blox C099-F9P // FWVER = HPG 1.13 // PROTVER = 27.12 navigation frequency: 10Hz connection via USB cable (UART1) windows 10 x64 python 3.7.9 pyubx2 ver. 1.0.2

My problem:

I want to start GNSS (via CFG-RST message), then read UBX messages for some time (in my case these are MON-RF, NAV-DOP, NAV-EELL, NAV-HPPOSLLH, NAV-PVT, NAV-SIG, NAV-STATUS) and stop GNSS (again via CFG-RST). The reason why I want to stop and start GNSS is that I want to save battery while keeping GNSS parameters in memory (so then I may perform hotstart).

How my code below works:

#receiver is stopped -Starting GNSS is succesfull -Reading several first message is also succesful, but then it hangs up and wait for message from serial (but the receiver is still working, and the serial send messages) -I terminate the script #start again (now the receiver keeps working - we are not stopped it) -“Starting” GNSS is succesful - it just sends the message, but of course receiver is already wroking -Reading all messages is succesfull -Stopping GNSS is succesful #again receiver is stopped -Starting GNSS is succesfull -Reading several first message is also succesful, but then it hangs up… …

I tried to set validate flag to True - it raise

UBXStreamError(f"Unknown data header {byte1}. {nmeawarn}")
pyubx2.exceptions.UBXStreamError: Unknown data header 

What I noticed - after several OK readings it starts to divide binary message to single bytes and this is why this error occurs.

To prevent this I need to close port after writing, sleep for 1 second (shorter values don’t help), open serial port again and flush it. This way everything works OK. But the problem is that in the future I would like to configure receiver on the run and then 1 second break looks ugly 😕

Code:

import time
import serial
from pyubx2 import UBXReader, UBXMessage, SET

print("hello")

ser = serial.Serial(port="COM9", baudrate=921600, timeout=1)
print("Port is open? -> ", ser.is_open)

if ser.is_open:
    # START GNSS
    msg = UBXMessage(6, 4, SET, resetMode=9)
    print(msg)
    ser.write(msg.serialize())
    print("STARTED!")

    """
    # CLOSE, SLEEP and OPEN AGAIN
    ser.close()
    time.sleep(1)
    ser = serial.Serial(port="COM9", baudrate=921600, timeout=1)

    # PORT FLUSH
    print("dummy read", ser.read())
    ser.flush()
    ser.flushInput()
    ser.flushOutput()
    """

    # READING UBX
    i = 0
    while i < 300:
        print("reading ", i, ":")
        ubr = UBXReader(ser)
        (raw_data, parsed_data) = ubr.read()
        print(raw_data)
        print(parsed_data)
        if parsed_data.identity == 'NAV-HPPOSLLH':
            print("LON = ", (parsed_data.lon + parsed_data.lonHp/100)*10**(-7))
        print("\n")
        i += 1

    # STOP GNSS
    msg1 = UBXMessage(6, 4, SET, resetMode=8)
    print(msg1)
    msg1 = msg1.serialize()
    ser.write(msg1)
    print("STOPPED!")

    ser.close()

else:
    print("Problem with serial port")

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 18 (12 by maintainers)

Most upvoted comments

Hi Nerolf05 - sorry for the delay in getting back to you. I think this is more a general Python thread-handling question than a specific pyubx2 issue, but if I understand your requirement correctly, you want to send commands to the device while at the same time monitoring the output. That’s basically exactly what the ‘\examples\ubxstreamer.py’ example does, so I recommend you take a look at that. Alternatively, if you want a more sophisticated example you could take a look at the implementation in the PyGPSClient GUI application (specifically the ‘serial_handler.py’ and ‘ubx_handler.py’ modules). I’m closing this issue thread down now, but I hope this helps, and thanks again for your interest in the pyubx2 library.

Cheers.

PS if you’re liking the library, it would help me if you could ‘Star’ it in Github 😃

OK glad it works and sorry for the wild goose chase! You’ve also prompted me to make a corresponding change to the partner GUI application PyGPSClient.

In terms of your use case, few observations that might help:

  1. Might be more robust to have the reader running as a daemon thread and send any CFG command messages via a separate ‘command’ thread - have a look at the ‘\examples\ubxstreamer.py’ example.
  2. For Generation 9+ devices like yours, you can use a CFG-VALSET message to set the CFG-RATE-MEAS parameter (keyid 0x30210001) to the required interval in ms (1000 = 1Hz, 100 = 10Hz, etc). As you know, this affects the frequency at which the GNSS takes position measurements.
  3. If, on the other hand, you simply want to receive certain UBX or NMEA message types more or less frequently, you can use CFG-VALSET to set the corresponding CFG-MSGOUT parameter e.g. to receive GNGGA messages on the USB port every 10 seconds at a GNSS measurement rate of 10Hz, you could use CFG-VALSET to set CFG-MSGOUT-NMEA-ID-GGA-USB (keyID 0x209100bd) to a value of 100, meaning it will send one GGA message out on every 100th position measurement. It won’t necessarily be exactly every 10 seconds but I think it gives you what you’re after.

You might also like to check out PYGPSClient. It’s not intended to be a u-center replacement but, unlike u-center, it runs on any platform and it provides a ‘ubxpresets’ facility allowing users to configure frequently-used message sequences (e.g. in your case a GNSS stop/start or a change in message rate). It also has a somewhat less daunting UI (IMHO!).

Hope this helps. Thanks for picking this up. Are you OK for me to close this issue now?

OK I believe this is sorted now with a fix to UBXReader which I’ve just uploaded in v1.0.3. Basically, you called it in your original issue report but I managed to lead us down a wild goose chase with CFG-RST message formats - doh! The CFG-RST message handling was fine - the problem was in the parsing of the subsequent NMEA TXT responses. Surprised this hasn’t cropped up before.

I’ve rerun my modified version of your test code (with navBbrMask left at the default b’\x00\x00’) and it seems to be working fine now. GNSS is successfully stopped at the end and I’m seeing no further UBX messages until I explicitly start it again. Have a go yourself and let me know if it works for you.

OK leave it with me for now - I’ll need to run some comparative tests against u-center to see exactly how u-center is populating the navBbrMask field in the CFG-RST GNSS stop/start message.