将 GNSS 接收器与 Arduino 连接以获取位置
在本教程中,我们将 Arduino 与 GNSS 接收器连接并获取当前位置。任何 GNSS 接收器通常都使用 UART 进行通信。我们将使用 ublox Neo6M GNSS 模块。
电路图
如您所见,我们将 Vcc 连接到 5V,GND 连接到 GND,将 Neo 6M 的 RX 连接到 Arduino Uno 的引脚 3,将 Neo 6M 的 TX 连接到 Arduino Uno 的引脚 4。
所需库
将 Arduino Uno 与 OLED 显示屏连接起来需要 TinyGPS 库 −
前往工具 →管理库,搜索此库,然后点击"安装"。
代码演示
我们将演示 TinyGPS 库附带的示例代码。前往文件 → 示例 → TinyGPS → simple_test 访问代码。
或者,您也可以在 GitHub 上访问代码 − https://github.com/mikalhart/TinyGPS/blob/master/examples/simple_test/simple_test.ino
如您所见,我们首先要添加所需的库:SoftwareSerial 和 TinyGPS。 SoftwareSerial 是一个库,可以与任何非串行端口的数字引脚进行串行通信。在这里,我们将使用该库来实现与 Arduino Uno 的 3 号和 4 号引脚的串行通信。
#include −SoftwareSerial.h> #include −TinyGPS.h>
接下来,我们定义 TinyGPS 对象和 Software Serial 对象。定义 Software Serial 对象时,需要提供 RX 和 TX 引脚作为参数。由于 Arduino 的 4 号引脚连接到 Neo 6M 模块的 TX 引脚,因此 4 号引脚在 Arduino 端是 RX 引脚,同理,3 号引脚是 TX 引脚。
TinyGPS gps; SoftwareSerial ss(4, 3);
在设置过程中,我们初始化了串口和软件串口。示例代码中,软件串口的波特率初始化为 4800。请查看您的 Neo 6M 模块的数据手册,如果您需要更高的波特率,例如 9600,请进行相应的更改。之后,我们添加了几个打印语句,其中包含库的版本号。
void setup() { Serial.begin(115200); ss.begin(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 sentence, failed;
接下来是一个持续一秒的 for 循环,用于解析来自软件串口的数据。 gps.encode() 函数接收来自软件串口的每个字节,并在数据完全解析并可供使用时返回 true。
因此,当它返回 true 时,我们将 newData 设置为 true。
// 我们解析 GPS 数据并报告一些关键值一秒钟 for (unsigned long start = millis(); millis() - start lt; 1000;) { while (ss.available()) { char c = ss.read(); // Serial.write(c); // 如果要查看 GPS 数据流,请取消注释此行 if (gps.encode(c)) // 是否有新的有效语句? newData = true; } }
如果 newData 为 true,我们将使用 f_get_position() 函数获取浮点型经纬度值,并获取数据年龄(即收集数据的时间)。我们使用 .satellites() 函数获取接收器可见的卫星数量,并使用 .hdop() 函数获取水平精度因子。您可以在此处阅读有关 hdop 的更多信息 https://en.wikipedia.org/wiki/Dilution_of_precision_(navigation)#:~:text=DOP%20can%20be%20expressed%20as,position%20(3D)%20dilution%20of%20precision。
在每个打印语句中,我们检查 INVALID 标志是否为真,如果为真,则打印 0,否则打印计算值。
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()); }
稍后,我们使用 .stats() 函数计算从 GNSS 接收器接收到的字符数、句子数以及校验和计算失败的次数。
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("** 未从 GPS 接收到字符:请检查接线 **");
请注意,您可能需要将接收器及其天线靠近窗户才能获得准确的位置。另请注意,GNSS 接收器的冷启动时间通常约为 30-40 秒。这意味着开机后大约需要 30-40 秒才能获得有效的位置信息。