我想在Arduino上使用TinyGPS++来解析NMEA数据并在OLED显示器上显示信息。但是,NMEA数据将通过USB接收,而不是使用软件串行和TX / RX引脚。

我遵循了TinyGPS ++的示例,但是遇到了两个问题:

1)
当我通过串行监视器(Windows,Arduino 1.6.9)发送一个NMEA语句时,Arduino仅接收前64个字符。如何克服这个限制?我通过删除几个小数位来帮助自己,但这不是首选的方式。

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的经验很少。您能指出我如何解决这些问题的方向吗?

最佳答案

基本上,您不需要累积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或从PC移植变得令人沮丧。 :P

10-07 20:50