将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号引脚。
所需库
与OLED显示屏连接Arduino Uno需要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对象和SoftwareSerial对象。为了定义软件串口,我们必须提供RX和TX引脚作为参数。由于Arduino的4号引脚连接到Neo 6M模块的TX,因此4号引脚是Arduino端的RX,类似地,3号引脚是TX。
TinyGPS gps; SoftwareSerial ss(4, 3);
在Setup中,我们初始化Serial和SoftwareSerial。在示例代码中,他们已将SoftwareSerial初始化为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 sentences, failed;
接下来,有一个持续一秒钟的for循环,其中解析来自软件串口的传入数据。**gps.encode()**函数接收来自软件串口的每个字节,并在数据已完全解析并准备使用时返回true。
因此,当它返回true时,我们将**newData**设置为true。
// For one second we parse GPS data and report some key values for (unsigned long start = millis(); millis() - start lt; 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; } }
如果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标志是否为true,如果是,则打印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("** No characters received from GPS: check wiring **");
请注意,您可能需要将接收器及其天线靠近窗户以获取准确的位置。另请注意,GNSS接收器通常具有大约30-40秒的冷启动时间。这意味着它将在通电后大约30-40秒获得有效的定位。