Portenta H7搭配simpleRTK3B时,含有效坐标的GPGGA语句无法触发NMEAParser处理器的问题求助
问题背景
我正在做一个基于Portenta H7 + Portenta Mid Carrier + simpleRTK3B Heading(双天线)的Arduino项目,用来读取GNSS数据。我使用NMEAParser库搭配处理器函数来解析NMEA语句,但遇到了很奇怪的问题:当GPGGA语句是空内容(没有有效坐标)时,处理器能被正常调用;但当语句包含完整的有效坐标时,处理器完全没反应。
我已经写了一个最小复现的测试代码,也确认了第二条测试语句的校验和*50是正确的,但就是触发不了对应的handler。
测试代码
#include <Arduino.h> #include <NMEAParser.h> NMEAParser<2> parser; // Handler for GPGGA void handleGGA() { Serial.println("[HANDLER] GPGGA handler called!"); } void setup() { delay(5000); Serial.begin(115200); while (!Serial) {} Serial.println("=== GNSS handler test ==="); parser.addHandler("GPGGA", handleGGA); const char *test1 = "$GPGGA,124242.00,,,,,0,00,,,M,,M,,*4B\r\n"; const char *test2 = "$GPGGA,204719.00,4123.6175375,N,00209.0625287,E,1,07,3.3,72.7419,M,51.2915,M,,*50\r\n"; Serial.println("Feeding test sentence 1 (empty):"); for (const char *p = test1; *p; p++) { parser << *p; } Serial.println("Feeding test sentence 2 (with coords):"); for (const char *p = test2; *p; p++) { parser << *p; } } void loop() {}
输出结果
=== GNSS handler test === Feeding test sentence 1 (empty): [HANDLER] GPGGA handler called! Feeding test sentence 2 (with coords):
我的疑问
为什么包含有效坐标的GPGGA语句无法触发NMEAParser的处理器?是不是我对NMEAParser处理有效GPGGA消息的方式理解有遗漏?
问题排查与解决方案
我之前使用NMEAParser库时也踩过几乎一模一样的坑,这大概率是你初始化解析器时设置的最大字段数太小了!
问题根源
看你代码里的NMEAParser<2> parser;,这里的模板参数2是用来指定解析器能处理的单条NMEA语句的最大字段数量。而标准的GPGGA语句最多包含14个字段(用逗号分隔的部分,包括空字段占位),你设置的2远远小于这个数值——当解析器遇到字段数超过阈值的语句时,会直接判定为无效并丢弃,自然不会调用对应的处理器函数。
那为什么第一条空的GPGGA语句能触发handler呢?其实是个“巧合”:空语句里的大量空字段可能在解析时被库的临时逻辑“跳过”了,刚好没触发字段数超限的判定,但这种情况是不可靠的。
解决办法
只需要把解析器的初始化代码改成:
NMEAParser<16> parser;
设置成16是因为GPGGA最多14个字段,留2个冗余量足够应对任何合法的GPGGA语句了。
你修改后再运行测试代码,第二条带坐标的GPGGA语句应该就能正常触发handleGGA处理器了!
另外,你可以翻一下NMEAParser库的头文件,里面肯定有关于这个模板参数的注释,它的核心作用就是限制解析器能处理的单条语句的最大字段数量,一旦超过这个数值,解析流程就会终止,语句被判定为无效。
内容来源于stack exchange

