【发布时间】:2017-01-11 23:21:38
【问题描述】:
我不是最好的程序员,但我研究并尝试了不同的角度来解析 GPS 字符串。
我目前正在开展一个大学项目,我和我的团队正在构建机器人庭院除草机的自主部分。我负责创建自定义 D-GPS。我不能使用 TinyGPS,因为我们不允许使用 Arduino 软件,所以我必须使用“C”。
我们还没有我们的微控制器,所以我仍在使用 Arduino 软件,只是想在没有 TinyGPS 的情况下做到这一点。
这是 TinyGPS 提供的所有设置:
#include <SoftwareSerial.h>
#define ARDUINO_GPS_RX 9 // Arduino RX pin connected to GPS TX
#define ARDUINO_GPS_TX 8 // Arduino TX pin connected to GPS RX
#define GPS_BAUD_RATE 9600 // The GPS Shield module defaults to 9600 baud
// Create a SoftwareSerial object called gps:
SoftwareSerial gpsPort(ARDUINO_GPS_TX, ARDUINO_GPS_RX);
// We'll also define a more descriptive moniker for the Serial Monitor port.
// This is the hardware serial port on pins 0/1.
#define SerialMonitor Serial
#include <string.h>
#include <stddef.h>
这是我尝试解析的地方:
const char string[] = gpsPort.read();
const char delimiters[] = "$GPRMC,";
char *cp, *tokentime, *tokenA, *tokenlat, *tokenlng, *tokenfixed, *tokensat, *tokendil, *tokenalt, *tokengeoid, *tokenempty, *tokenchecksum;
void setup()
{
gpsPort.begin(GPS_BAUD_RATE);
SerialMonitor.begin(9600);
}
void loop()
{
if (gpsPort.available()) // If GPS data is available
//SerialMonitor.write(gpsPort.read()); // Read it and print to SerialMonitor
if (SerialMonitor.available()) // If SerialMonitor data is available
gpsPort.write(SerialMonitor.read()); // Read it and send to GPS
cp = strdupa (string); /* Make writable copy. */
tokensentence = strtok (cp, delimiters); /*gets the first sentence to parse*/
tokentime = strtok (NULL, delimiters); /* token => 123519 "time taken at 12 o clock 35 min 19 sec" */
tokenA = strtok (NULL, delimiters); /* token => "A"ignore */
tokenlat = strtok (NULL, delimiters); /* token => 4807.038,N "Latitude 48 deg 07.038' N" */
tokenlng = strtok (NULL, delimiters); /* token => 01131.000,E "Longitude 11 deg 31.000' E" */
tokenfixed = strtok (NULL, delimiters); /* token => 1 "Fix quality: 0 = invalid" */
tokensat = strtok (NULL, delimiters); /* token => 08 "Number of satellites being tracked" */
tokendil = strtok (NULL, delimiters); /* token => 0.9 "Horizontal dilution of position" */
tokenalt = strtok (NULL, delimiters); /* token => 545.4,M "Altitude, Meters, above mean sea level" */
tokengeoid = strtok (NULL, delimiters); /* token => 46.9,M "Height of geoid (mean sea level) above WGS84 ellipsoid */
tokenempty = strtok (NULL, delimiters); /* token => empty field */
tokenchecksum = strtok (NULL, delimiters); /* token => *47 "the checksum data, always begins with *" */
SerialMonitor.print("Lat: "); SerialMonitor.println(tokenlat);
SerialMonitor.print("Lng: "); SerialMonitor.println(tokenlng);
}
我遇到的问题是“初始化程序无法确定字符串的大小”。我见过的所有示例都有一个定义的字符串,但我不知道如何使用带有“实时”数据的 strtok 进行解析(如果这是调用它的最佳方式)。我曾尝试单独使用“serial.read”而不是“gpsPort.available”,但没有运气。
只是一些背景信息,这段代码:
void setup()
{
SerialMonitor.begin(9600); // Initialize the serial monitor port at 9600 baud
gpsPort.begin(GPS_BAUD_RATE); // The GPS module's default baud is 9600
}
void loop()
{
if (gpsPort.available()) // If GPS data is available
SerialMonitor.write(gpsPort.read()); // Send it to the serial monitor
if (SerialMonitor.available()) // If data is sent to the serial monitor
gpsPort.write(SerialMonitor.read()); // send it to the GPS module
}
给出这组字符串:
$GPRMC,235316.000,A,4003.9040,N,10512.5792,W,0.09,144.75,141112,,*19
$GPGGA,235317.000,4003.9039,N,10512.5793,W,1,08,1.6,1577.9,M,-20.7,M,,0000*5F
$GPGSA,A,3,22,18,21,06,03,09,24,15,,,,,2.5,1.6,1.9*3E
我最终试图解析出纬度和经度。
【问题讨论】:
-
这是一个很好的问题,我会投赞成票,但我已经删掉了很多聊天内容。请尽量避免使用诸如“我真的搜索了很多年”和“这个问题可以吗”之类的材料,因为这些材料经常出现在没有任何努力或研究的问题中,而且你不想听起来像他们!
:-) -
您是否注意到每个示例行都有不同的开头,例如
$GPRMC、$GPGGA和$GPGSA。如果你只是谷歌,你会很快找到GPS - NMEA sentence information,它提供了每种线路类型的详细信息。同样不运行这个,我看到const char delimiters[] = "$GPRMC,";看起来非常错误,因为$、G、P、R、M和C没有用作分隔符;我希望有一些链接const char delimiters[] = ",";