Skip to content

Commit e4579ed

Browse files
committed
update NMEA PAIR response handling
1 parent 4a3eca6 commit e4579ed

6 files changed

Lines changed: 39 additions & 17 deletions

File tree

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,11 @@ warning ![warning icon](https://github.com/semuconsulting/PyGPSClient/blob/maste
236236
**Pre-Requisites:**
237237

238238
- Receiver capable of being configured via proprietary NMEA sentences, connected to the workstation via USB or UART port.
239-
- The facility includes support for a wide range of Quectel LG and LC series receivers via PQTM*, PSTM* and PAIR* sentences¹. Additional types may be supported in the underlying NMEA parser library [pynmeagps](https://github.com/semuconsulting/pynmeagps) in later releases (*contributions welcome*).
239+
- The facility includes support for a wide range of Quectel LG and LC series receivers via `PQTM*`, `PSTM*` and `PAIR*` sentences¹ ². Additional types may be supported in the underlying NMEA parser library [pynmeagps](https://github.com/semuconsulting/pynmeagps) in later releases (*contributions welcome*).
240240

241-
¹ Note that Quectel message support depends on the *specific model variant* and firmware version, and several models (e.g. LG290 and LC29) exist in a wide range of variants. Refer to the GNSS Protocol Guide for your *specific* variant.
241+
¹ Note that Quectel receivers implement a bewildering array of different configuration protocols (based on a mixture of proprietary `PQTM*`, `PSTM*` and `PAIR*` NMEA message types). Support depends on the *specific model variant and firmware version*, and several models (e.g. LG290 and LC29) exist in a wide range of variants. Refer to the GNSS Protocol Guide for your *specific* variant.
242+
243+
² Note that several Quectel configuration commands require a Hot Restart (PQTMHOT) *or* Save (PQTMSAVEPAR or PAIR513) and Reset (PQTMSRR) before taking effect, including for example PQTMCFGCNST (Enable/Disable Constellations), PQTMCFGFIX (Configure Fix Rate), PQTMCFGSAT (Configure Satellite Masks), PQTMCFGSIGNAL (Configure Signal Masks), PAIR050 (Set Fix Rate) and PAIR864 (Set Baud Rate). Devices (e.g. some LC variants) that don't implement a software reset command may have to be physically disconnected and reconnected.
242244

243245
**Instructions:**
244246

@@ -253,8 +255,6 @@ An icon to the right of each 'SEND'
253255
confirmed ![confirmed icon](https://github.com/semuconsulting/PyGPSClient/blob/master/src/pygpsclient/resources/iconmonstr-check-mark-8-24.png?raw=true) or
254256
warning ![warning icon](https://github.com/semuconsulting/PyGPSClient/blob/master/src/pygpsclient/resources/iconmonstr-warning-1-24.png?raw=true)).
255257

256-
**NB:** Several Quectel LG and LC series commands require a Hot Restart (PQTMHOT) before taking effect, including PQTMCFGCNST (Enable/Disable Constellations), PQTMCFGFIX (Configure Fix Rate), PQTMCFGSAT (Configure Satellite Masks) and PQTMCFGSIGNAL (Configure Signal Masks). This is a Quectel protocol constraint, not a PyGPSClient issue.
257-
258258
---
259259
## <a name="ttycommands">TTY Configuration Facilities</a>
260260

@@ -490,7 +490,7 @@ For further details, refer to the `pygnssutils` homepage at [https://github.com/
490490

491491
1. If you encounter persistent `WARNING>>Error parsing data stream Serial stream terminated unexpectedly` messages in the console, this may be indicative of insufficient serial port bandwidth (baudrate or timeout) for the current output message cohort (*particularly if this includes Ephemera or Observation data*). Try increasing the baudrate in the first instance.
492492

493-
2. Most budget USB-UART adapters (e.g. FT232, CH345, CP2102) have a bandwidth limit of around 3MB/s and may not work reliably above 115200 baud, even if the receiver supports higher baud rates. If you're using an adapter and notice significant message corruption, try reducing the baud rate to a maximum 115200.
493+
2. Most budget USB-UART adapters (e.g. FT232, CH345, CP2102, *including those embedded on development boards*) have a bandwidth limit of around 3MB/s (≈ 375000 baud) and may not work reliably above 230600 baud, even if the receiver supports higher baud rates. If you're using an adapter and notice significant message corruption (e.g. frequent `WARNING>>..invalid checksum` messages), try reducing the baud rate to a maximum 230600.
494494

495495
3. Some Linux Wayland platforms appear to require Toplevel dialog windows to be non-transient (`transient_dialog_b: 0`) for the window 'maximise' icon to work properly.
496496

RELEASE_NOTES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
1. Add preset description entry field to Configuration Command Recorder import facility.
66
1. Make TTY Presets dialog fully resizeable.
7+
1. Update NMEA config panel to recognise correct PAIR responses for some Quectel set and poll commands (e.g. a PAIR864 Set baud rate command corresponds to a PAIR865 poll response).
78

89
### RELEASE 1.6.4
910

src/pygpsclient/dynamic_config_frame.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@
9898
)
9999
# alternative POLL dictionary names for where POLL command
100100
# doesn't correspond to SET (fudge for Quectel)
101+
# e.g. a PAIR864 (set baud rate) command corresponds to PAIR865 (poll baud rate)
102+
# (for PAIR commands, the poll is typically one digit higher than the set)
101103
ALT_POLL_NAMES = {
102104
"AIR050": "AIR051",
103105
"AIR058": "AIR059",
@@ -111,8 +113,8 @@
111113
"AIR100": "AIR101",
112114
"AIR104": "AIR105",
113115
"AIR400": "AIR401",
114-
"AIR410": "AIR421",
115-
"AIR420": "AIR411",
116+
"AIR410": "AIR411",
117+
"AIR420": "AIR421",
116118
"AIR432": "AIR433",
117119
"AIR434": "AIR435",
118120
"AIR436": "AIR437",
@@ -406,7 +408,7 @@ def _do_poll_cfg(self, *args, **kwargs): # pylint: disable=unused-argument
406408
return
407409

408410
msg = penddlg = pendcfg = None
409-
# use alternate names for some NMEA PAIR/PQTM POLL commands
411+
# use alternate name for some NMEA PAIR/PQTM POLL commands
410412
cfg_id = ALT_POLL_NAMES.get(self._cfg_id, self._cfg_id)
411413
# set any POLL arguments to specified or default values
412414
# e.g. portid = "1", msgname="RMC"
@@ -477,23 +479,26 @@ def _do_poll_args(self, cfg_id: str) -> dict:
477479
pass
478480
return args
479481

480-
def update_status(self, msg: object):
482+
def update_status(self, msg: NMEAMessage | UBXMessage):
481483
"""
482484
UBXHandler or NMEAHandler module has received expected command response
483485
and forwarded it to this module, entry widgets are pre-populated with
484486
current configuration values and confirmation status is updated.
485487
486-
:param object msg: UBXMessage or NMEAMessage response
488+
:param NMEAMessage | UBXMessage msg: UBXMessage or NMEAMessage response
487489
"""
488490

491+
# self.logger.debug(f"{msg.identity=}")
489492
ok = False
490493
# strip off any variant suffix from cfg_id
491494
# e.g. "QTMCFGUART_CURR" -> "PQTMCFGUART"
492-
cfg_id = (
493-
"P" + self._cfg_id.rsplit("_", 1)[0]
494-
if self._protocol == NMEA
495-
else self._cfg_id
496-
)
495+
if self._protocol == NMEA:
496+
cfg_id = self._cfg_id.rsplit("_", 1)[0]
497+
# use alternate name for some NMEA PAIR/PQTM POLL commands
498+
# e.g. a PAIR864 (set baud rate) command corresponds to PAIR865 (poll baud rate)
499+
cfg_id = "P" + ALT_POLL_NAMES.get(cfg_id, cfg_id)
500+
else:
501+
cfg_id = self._cfg_id
497502

498503
# if this message identity matches an expected response
499504
if msg.identity in (cfg_id, ACK, NAK):

src/pygpsclient/nmea_config_dialog.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ def update_pending(self, msg: NMEAMessage):
154154
:param NMEAMessage msg: NMEA config message
155155
"""
156156

157+
# self.logger.debug(f"{msg.identity=}")
157158
nmeafrm = self._pending_confs.get(msg.identity, None)
158159

159160
if nmeafrm is not None:

src/pygpsclient/nmea_handler.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ def process_data(self, raw_data: bytes, parsed_data: NMEAMessage):
128128
self._process_FMI(parsed_data)
129129
elif parsed_data.msgID[0:3] == "QTM" and hasattr(parsed_data, "status"):
130130
self._process_QTMACK(parsed_data)
131+
elif parsed_data.msgID[0:3] == "AIR":
132+
self._process_AIR(parsed_data)
131133
except ValueError:
132134
pass
133135

@@ -518,3 +520,18 @@ def _process_IMU(self, data: NMEAMessage):
518520
ims["status"] = str(getattr(data, "quality", ""))
519521
except (TypeError, KeyError, AttributeError):
520522
pass
523+
524+
def _process_AIR(self, data: NMEAMessage):
525+
"""
526+
Process PAIR sentences.
527+
528+
Quectel LC* series configuration or poll message.
529+
530+
:param NMEAMessage data: PAIR* message
531+
"""
532+
533+
try:
534+
if self.__app.dialog(DLGTNMEA) is not None:
535+
self.__app.dialog(DLGTNMEA).update_pending(data)
536+
except (TypeError, KeyError, AttributeError):
537+
pass

src/pygpsclient/ubx_handler.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,8 +413,6 @@ def _process_NAV_SIG(self, data: UBXMessage):
413413
now,
414414
)
415415

416-
# print(f"DEBUG {self.__app.gnss_status.sig_data=}")
417-
418416
def _process_NAV_STATUS(self, data: UBXMessage):
419417
"""
420418
Process NAV-STATUS sentences - Status Information.

0 commit comments

Comments
 (0)