基于 ublox 7 的 GPS 模块 - 使用 Arduino 从板上的 UART 引脚检索时,大部分时间 data/incorrectly 格式的数据不完整
ublox 7 based GPS module - incomplete data/incorrectly formatted data most of the time when retrieving from UART pins on board with Arduino
我看过很多关于这个主题的教程,但我无法确定我从基于 ublox NEO 的 GT-U7 收到的所有消息中的大部分(>90%)不完整的问题-7(虽然令人困惑的是亚马逊商店中的商品描述说的是 NEO-6,但是评论和 u-center 状态,它是 NEO-7):
代码如下:
#include <SoftwareSerial.h>
#include <TinyGPS.h>
float lat = 0.0,lon = 0.0; // create variable for latitude and longitude object
SoftwareSerial gpsSerial(10,11); //rx,tx
TinyGPS gps; // create gps object
void setup(){
Serial.begin(9600); // connect serial
gpsSerial.begin(9600); // connect gps sensor
}
void loop(){
if (!gpsSerial.available()) Serial.println("GPS device not available");
while(gpsSerial.available()){ // check for gps data
char d = gpsSerial.read();
Serial.print(d);
if(gps.encode(d))// encode gps data
{
Serial.println("Encoding data successful");
gps.f_get_position(&lat,&lon); // get latitude and longitude
// display position
Serial.println("----------------------------------");
Serial.println("Position: ");
Serial.print("\tlat : ");
Serial.println(lat,6);
Serial.print("\tlong : ");
Serial.println(lon,6);
}
}
Serial.println();
/*
String latitude = String(lat,6);
String longitude = String(lon,6);
Serial.println(latitude+";"+longitude);
*/
delay(1000);
}
u-center 与我通过 USB 数据线连接到我的笔记本电脑的设备没有任何问题。然而(当然 USB 线是分离的!)当涉及到串行通信时,事情看起来并不那么光明。
起初我以为模块根本不工作。然而,闪烁的 LED(每秒一次)指示固定位置。而 u-center 能够提取所有数据(卫星、速度、经纬度、UTC 时间等)的事实告诉我并非如此。
我在上面的代码中注释掉了整个循环并添加了 if:
if (!gpsSerial.available()) Serial.println("GPS device not available");
令我惊讶的是,在串行监视器中,我在开始时只收到一次此消息,之后我得到了最后注释掉的输出(lon
和 lat
都等于 0.0
).下一步是在不编码的情况下读取数据。
我注意到大多数消息都有类似 ,,,,
或不完整的结尾。输出中的某些行是前一行的不完整部分。我在在线解码器中粘贴了几条消息,然后收到错误消息,告诉我格式错误(我是新手,所以看它并没有告诉我它的正确性)。
基本上
if(gps.encode(d))
{
...
}
是执行几乎一直失败的地方。偶尔我会在这里和那里收到正确的消息(例如 $GPGLL
),但总体而言,现在它比实际可靠的数据检索更幸运。
我读到波特率很重要,但根据我目前的发现,应该使用 9600。
知道这里发生了什么吗?我应该为 Serial.begin(...)
尝试不同的波特率吗?我确实尝试过使用该值并将其启动会产生根本无法读取的垃圾数据。所以至少我确定波特率会影响我的数据流的完整性和结构完整性。
请注意,这发生在 "proper" Arduino Uno 和我自己将排针焊接到的 Arduino Nano 上。
波特的值必须设置为与模块设置相同的值NEO-7
。据我所知,9600 是它的默认值,您不需要使用任何其他值。但是您可以检查为模块设置的确切值。
我不确定,但您是否尝试过以下代码?或者这个 example 原样。
void loop() {
String code = "";
while (gpsSerial.available()) {
code += (char)(gpsSerial.read());
}
Serial.println(code)
if (gps.encode(code) && code.length() > 0){
gps.f_get_position(&lat, &lon);
Serial.println("----------");
Serial.println("Position: ");
Serial.print("\tlat : ");
Serial.println(lat, 6);
Serial.print("\tlong : ");
Serial.println(lon, 6);
}
}
数据不完整其实很正常。至少在开始时或每当模块失去 GPS 定位并尝试获取新定位时。
现在我使用下面的代码:
#include <SoftwareSerial.h>
#include <Wire.h>
#include <TinyGPS.h>
/* This sample code demonstrates the normal use of a TinyGPS object.
It requires the use of SoftwareSerial, and assumes that you have a
4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
TinyGPS gps;
SoftwareSerial ss(8, 9);
void setup()
{
Wire.begin(0x11); // I2C address. Leave empty to join bus as master
Serial.begin(9600); //115200
ss.begin(9600); //4800
Serial.print("Simple TinyGPS library v. "); Serial.println(TinyGPS::library_version());
Serial.println("by Mikal Hart");
Serial.println();
}
void loop()
{
bool newData = false;
unsigned long chars;
unsigned short sentences, failed;
// For one second we parse GPS data and report some key values
for (unsigned long start = millis(); millis() - start < 1000;)
{
while (ss.available())
{
char c = ss.read();
// Serial.write(c); // uncomment this line if you want to see the GPS data flowing
if (gps.encode(c)) // Did a new valid sentence come in?
newData = true;
}
}
if (newData)
{
float flat, flon;
unsigned long age;
gps.f_get_position(&flat, &flon, &age);
Serial.print("LAT=");
Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
Serial.print(" LON=");
Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
Serial.print(" SAT=");
Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
Serial.print(" PREC=");
Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
Serial.print(" SPD=");
float fspd = gps.f_speed_kmph();
Serial.print("km/h");
Serial.print(fspd == TinyGPS::GPS_INVALID_F_SPEED ? 0 : fspd);
unsigned long date, _time;
gps.get_datetime(&date, &_time, &age);
Serial.print(" DATE=");
Serial.print(date);
Serial.print(" TIME=");
Serial.print(_time);
}
gps.stats(&chars, &sentences, &failed);
Serial.print(" CHARS=");
Serial.print(chars);
Serial.print(" SENTENCES=");
Serial.print(sentences);
Serial.print(" CSUM ERR=");
Serial.println(failed);
if (chars == 0)
Serial.println("** No characters received from GPS: check wiring **");
}
这是 TinyGPS 库附带的示例之一。
我在 u-center 中打开了 NMEA 消息日志,发现了完全相同的问题。这基本上给了我一个提示,问题不在模块本身,而是我这里的信号接收不佳加上我需要等待更长的时间才能得到修复。问题是我实际上需要打开我的 window 并将我的设置放在框架上。否则我几乎没有接待。这还包括 phone 服务。 :D
我看过很多关于这个主题的教程,但我无法确定我从基于 ublox NEO 的 GT-U7 收到的所有消息中的大部分(>90%)不完整的问题-7(虽然令人困惑的是亚马逊商店中的商品描述说的是 NEO-6,但是评论和 u-center 状态,它是 NEO-7):
代码如下:
#include <SoftwareSerial.h>
#include <TinyGPS.h>
float lat = 0.0,lon = 0.0; // create variable for latitude and longitude object
SoftwareSerial gpsSerial(10,11); //rx,tx
TinyGPS gps; // create gps object
void setup(){
Serial.begin(9600); // connect serial
gpsSerial.begin(9600); // connect gps sensor
}
void loop(){
if (!gpsSerial.available()) Serial.println("GPS device not available");
while(gpsSerial.available()){ // check for gps data
char d = gpsSerial.read();
Serial.print(d);
if(gps.encode(d))// encode gps data
{
Serial.println("Encoding data successful");
gps.f_get_position(&lat,&lon); // get latitude and longitude
// display position
Serial.println("----------------------------------");
Serial.println("Position: ");
Serial.print("\tlat : ");
Serial.println(lat,6);
Serial.print("\tlong : ");
Serial.println(lon,6);
}
}
Serial.println();
/*
String latitude = String(lat,6);
String longitude = String(lon,6);
Serial.println(latitude+";"+longitude);
*/
delay(1000);
}
u-center 与我通过 USB 数据线连接到我的笔记本电脑的设备没有任何问题。然而(当然 USB 线是分离的!)当涉及到串行通信时,事情看起来并不那么光明。
起初我以为模块根本不工作。然而,闪烁的 LED(每秒一次)指示固定位置。而 u-center 能够提取所有数据(卫星、速度、经纬度、UTC 时间等)的事实告诉我并非如此。
我在上面的代码中注释掉了整个循环并添加了 if:
if (!gpsSerial.available()) Serial.println("GPS device not available");
令我惊讶的是,在串行监视器中,我在开始时只收到一次此消息,之后我得到了最后注释掉的输出(lon
和 lat
都等于 0.0
).下一步是在不编码的情况下读取数据。
我注意到大多数消息都有类似 ,,,,
或不完整的结尾。输出中的某些行是前一行的不完整部分。我在在线解码器中粘贴了几条消息,然后收到错误消息,告诉我格式错误(我是新手,所以看它并没有告诉我它的正确性)。
基本上
if(gps.encode(d))
{
...
}
是执行几乎一直失败的地方。偶尔我会在这里和那里收到正确的消息(例如 $GPGLL
),但总体而言,现在它比实际可靠的数据检索更幸运。
我读到波特率很重要,但根据我目前的发现,应该使用 9600。
知道这里发生了什么吗?我应该为 Serial.begin(...)
尝试不同的波特率吗?我确实尝试过使用该值并将其启动会产生根本无法读取的垃圾数据。所以至少我确定波特率会影响我的数据流的完整性和结构完整性。
请注意,这发生在 "proper" Arduino Uno 和我自己将排针焊接到的 Arduino Nano 上。
波特的值必须设置为与模块设置相同的值NEO-7
。据我所知,9600 是它的默认值,您不需要使用任何其他值。但是您可以检查为模块设置的确切值。
我不确定,但您是否尝试过以下代码?或者这个 example 原样。
void loop() {
String code = "";
while (gpsSerial.available()) {
code += (char)(gpsSerial.read());
}
Serial.println(code)
if (gps.encode(code) && code.length() > 0){
gps.f_get_position(&lat, &lon);
Serial.println("----------");
Serial.println("Position: ");
Serial.print("\tlat : ");
Serial.println(lat, 6);
Serial.print("\tlong : ");
Serial.println(lon, 6);
}
}
数据不完整其实很正常。至少在开始时或每当模块失去 GPS 定位并尝试获取新定位时。
现在我使用下面的代码:
#include <SoftwareSerial.h>
#include <Wire.h>
#include <TinyGPS.h>
/* This sample code demonstrates the normal use of a TinyGPS object.
It requires the use of SoftwareSerial, and assumes that you have a
4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
TinyGPS gps;
SoftwareSerial ss(8, 9);
void setup()
{
Wire.begin(0x11); // I2C address. Leave empty to join bus as master
Serial.begin(9600); //115200
ss.begin(9600); //4800
Serial.print("Simple TinyGPS library v. "); Serial.println(TinyGPS::library_version());
Serial.println("by Mikal Hart");
Serial.println();
}
void loop()
{
bool newData = false;
unsigned long chars;
unsigned short sentences, failed;
// For one second we parse GPS data and report some key values
for (unsigned long start = millis(); millis() - start < 1000;)
{
while (ss.available())
{
char c = ss.read();
// Serial.write(c); // uncomment this line if you want to see the GPS data flowing
if (gps.encode(c)) // Did a new valid sentence come in?
newData = true;
}
}
if (newData)
{
float flat, flon;
unsigned long age;
gps.f_get_position(&flat, &flon, &age);
Serial.print("LAT=");
Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
Serial.print(" LON=");
Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
Serial.print(" SAT=");
Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
Serial.print(" PREC=");
Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
Serial.print(" SPD=");
float fspd = gps.f_speed_kmph();
Serial.print("km/h");
Serial.print(fspd == TinyGPS::GPS_INVALID_F_SPEED ? 0 : fspd);
unsigned long date, _time;
gps.get_datetime(&date, &_time, &age);
Serial.print(" DATE=");
Serial.print(date);
Serial.print(" TIME=");
Serial.print(_time);
}
gps.stats(&chars, &sentences, &failed);
Serial.print(" CHARS=");
Serial.print(chars);
Serial.print(" SENTENCES=");
Serial.print(sentences);
Serial.print(" CSUM ERR=");
Serial.println(failed);
if (chars == 0)
Serial.println("** No characters received from GPS: check wiring **");
}
这是 TinyGPS 库附带的示例之一。
我在 u-center 中打开了 NMEA 消息日志,发现了完全相同的问题。这基本上给了我一个提示,问题不在模块本身,而是我这里的信号接收不佳加上我需要等待更长的时间才能得到修复。问题是我实际上需要打开我的 window 并将我的设置放在框架上。否则我几乎没有接待。这还包括 phone 服务。 :D