我想在Arduino上使用TinyGPS++来解析NMEA数据并在OLED显示屏上显示信息。但是,不是使用软件串行和TX / RX引脚,而是通过USB接收NMEA数据。
我按照TinyGPS ++的例子,但我遇到了两个问题:
1) 当我通过串行监视器发送一个NMEA语句时,只有前64个字符被Arduino接收(Windows,Arduino 1.6.9)。我怎样才能克服这个限制?我通过删除几个小数位来帮助自己,但这不是首选的方法。
2) 在TinyGPS ++ BasicExample中,示例NMEA字符串在只读存储器中定义:
// A sample NMEA stream.
const char *gpsStream =
"$GPRMC,045103.0,A,3014.0,N,09748.0,W,36.88,65.02,030913,,,A*7C\r\n"
"$GPGGA,045104.0,3014.0,N,09749.0,W,1,09,1.2,211.6,M,-22.5,M,,*62\r\n"
"$GPRMC,045200.0,A,3014.0,N,09748.0,W,36.88,65.02,030913,,,A*77\r\n"
"$GPGGA,045201.0,3014.0,N,09749.0,W,1,09,1.2,211.6,M,-22.5,M,,*6C\r\n"
"$GPRMC,045251.0,A,3014.0,N,09748.0,W,36.88,65.02,030913,,,A*7D\r\n"
"$GPGGA,045252.0,3014.0,N,09749.0,W,1,09,1.2,211.6,M,-22.5,M,,*6F\r\n";
并由
解析while (*gpsStream) {
Serial.print(*gpsStream);
gps.encode(*gpsStream++);
}
我以这种方式收到我的NMEA(不幸的是只有一行):
if (Serial.available()) {
while (Serial.available() > 0) {
if(index < 80)
{
inChar = Serial.read();
inData[index] = inChar;
index++;
inData[index] = '\0';
}
}
}
并尝试通过以下方式解析它:
index = 0;
while (index < 80) {
gps.encode(inData[index]);
Serial.print(inData[index]);
index++;
}
但是这不能按预期工作。检查位置isValid()
是否始终返回不为真。
不幸的是,我有几种可能的不良行为来源。
我对NMEA和串行数据通信都没有经验,而且我对Arduino / C只有很少的经验。你能指点我如何解决这些(这些)问题吗?
答案 0 :(得分:0)
基本上,您不需要累积NMEA字符。只需在收到它们时将它们送到GPS库。你不提供整个循环,但在那里遇到问题也很常见。
在与几个GPS库及其示例挣扎之后,我最终写了NeoGPS。它比所有其他库更快,更小,它验证校验和,并且示例结构正确。与其他库不同,NeoGPS不会将GPS值存储为浮点值,因此它可以保持GPS设备的完整精度。
如果您想尝试一下,请务必遵循安装说明。 NMEA.ino示例将为您发送的每批GPS句子发出一行信息(CSV格式),以默认的RMC句子结束。请务必对其进行修改以使用Serial
对象而不是gps_port
,或者只需将其定义为:
#define gps_port Serial
它还将显示已解析的字符数,已收到的好句数以及校验和错误的句数。如果您没有正确生成校验和,这可能有助于调试。 This site也很有用。
这些CSV线将通过USB端口(发送到PC)发回,但您可以轻松更改它以将特定字段发送到OLED(请参阅NMEAloc.ino)。
虽然可能在PC上开发某些内容然后将其移植到像Arduino这样的嵌入式环境中,但您必须注意(1)线性程序结构和(2)忽略资源限制(程序大小,MCU速度和RAM)。 Arduino环境存在许多怪癖,通常会使“草图”移入/移出PC时会感到沮丧。 :P