资讯详情

资讯详情

IoT-For-Beginners 位置追踪实战:Wio Terminal 使用 TinyGPSPlus 解码 NMEA GPS 数据

IoT-For-Beginners 位置追踪实战Wio Terminal 使用 TinyGPSPlus 解码 NMEA GPS 数据【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners本篇技术指南基于 IoT-For-Beginners 项目「Transport / 位置追踪」一课中 Wio Terminal 的 GPS 数据解码环节讲解如何用开源库 TinyGPSPlus 把从 UART 串口读到的原始 NMEA 句子解析成可用的纬度和经度并通过串口监视器实时查看定位结果。读完本文你将掌握在 PlatformIO 工程中引入解码库依赖、逐字符喂养 NMEA 解码器、校验定位有效性并输出卫星数量的完整可运行方案并理解其背后的 NMEA 0183 报文结构与源码实现。任务背景为什么需要对 NMEA 数据做解码在上一环节见 读取 GPS 数据 - Wio Terminal中Wio Terminal 通过左侧 Grove 接口以 UART 方式连接 Grove GPS Air530 传感器并把串口读到的原始数据直接打印到串口监视器输出形如下面的内容$GNGGA,020604.001,4738.538654,N,12208.341758,W,1,3,,164.7,M,-17.1,M,,*67 $GPGSA,A,1,,,,,,,,,,,,,,,*1E $BDGSA,A,1,,,,,,,,,,,,,,,*0F $GPGSV,1,1,00*79 $BDGSV,1,1,00*68这些以$开头、按逗号分段的文本就是 NMEA 0183 标准报文由美国国家海洋电子协会制定的海事电子通信标准。虽然格式固定且信息完整但直接阅读和业务使用都很不便。本环节的核心任务就是用开源库 TinyGPSPlus 自动解析这些句子从中提取十进制度格式的纬度、经度以及参与定位的卫星数量。课程主文档 位置追踪 README 中已详细介绍过 GGA、ZDA、GSV 等报文类型以及(dd)dmm.mmmm的度分格式与十进制度的换算关系解码环节正是把这些理论落到代码上。第一步在 platformio.ini 中添加 TinyGPSPlus 依赖首先打开上一环节创建的gps-sensor工程若未创建可参考 wio-terminal-gps-sensor.md 完成硬件连接与原始读取。TinyGPSPlus 是一个广泛使用的开源 NMEA 解码库包含解析 NMEA 句子并暴露位置、时间、卫星数量等对象的完整代码。在工程的platformio.ini中加入库依赖声明。仓库中本环节完整工程 code-gps-decode/wio-terminal/gps-sensor/platformio.ini 的最终内容为; PlatformIO Project Configuration File [env:seeed_wio_terminal] platform atmelsam board seeed_wio_terminal framework arduino lib_deps mikalhart/TinyGPSPlus 1.0.2关键配置说明[env:seeed_wio_terminal]PlatformIO 的环境名对应 Wio Terminal 开发板platform atmelsamAtmel SAMD51ARM Cortex-M4F芯片平台board seeed_wio_terminal指定 Seeed Wio Terminal 板级定义framework arduino使用 Arduino 框架lib_deps mikalhart/TinyGPSPlus 1.0.2声明依赖 TinyGPSPlus 1.0.2 版本。lib_deps的作用是让 PlatformIO 在首次构建时自动从库仓库下载并编译该依赖无需手动拷贝源码。第二步包含头文件并声明解码器对象在main.cpp顶部加入 TinyGPSPlus 头文件并在Serial3声明之后实例化一个全局解码器对象。仓库中 code-gps-decode/wio-terminal/gps-sensor/src/main.cpp 的对应代码为#include Arduino.h #include wiring_private.h #include TinyGPS.h static Uart Serial3(sercom3, PIN_WIRE_SCL, PIN_WIRE_SDA, SERCOM_RX_PAD_1, UART_TX_PAD_0); TinyGPSPlus gps;#include TinyGPS.h引入 TinyGPSPlus 库的 APIstatic Uart Serial3(...)上一环节建立的 UART 串口对象将 SERCOM3 映射到 Wio Terminal 左侧 Grove 接口的 SCL/SDA 引脚GPS 传感器的数据经由它进入芯片TinyGPSPlus gps;全局解码器实例。所有 NMEA 字符都将被逐字节送入该对象库内部会完成句子边界识别、字段解析与校验和验证。setup()函数保持不变仍以 9600 波特率初始化Serial连接电脑的 USB 串口与Serial3连接 GPS 传感器并通过pinPeripheral(PIN_WIRE_SCL, PIO_SERCOM_ALT)将 Grove 引脚复用到 SERCOM 串口功能上随后由SERCOM3_0_Handler等四个中断服务函数转发到Serial3.IrqHandler()。第三步改造 printGPSData逐字符解码并输出定位这是本环节的核心改动。将printGPSData函数的内容替换为以下代码见 code-gps-decode/wio-terminal/gps-sensor/src/main.cpp#L27-L41void printGPSData() { if (gps.encode(Serial3.read())) { if (gps.location.isValid()) { Serial.print(gps.location.lat(), 6); Serial.print(F(,)); Serial.print(gps.location.lng(), 6); Serial.print( - from ); Serial.print(gps.satellites.value()); Serial.println( satellites); } } }逐行解读这段代码的运行逻辑gps.encode(Serial3.read())从 UART 串口读取一个字符并送入gps解码器。encode()返回布尔值当累积的字符恰好构成一条完整且校验合法的 NMEA 句子时返回true否则返回false。这正是逐字符流式解码的典型用法——每个串口字节到达时调用一次gps.location.isValid()句子解析成功后进一步检查其中是否包含有效的定位数据防止解析到 GSV、GSA 等不含位置的句子时输出空值gps.location.lat(), 6/gps.location.lng(), 6输出十进制度格式的纬度与经度第二个参数6表示保留 6 位小数约 0.11 米精度级别。TinyGPSPlus 内部已把 NMEA 的(dd)dmm.mmmm度分格式换算为十进制度南纬为负值西经为负值gps.satellites.value()输出参与本次定位解算fix的卫星数量Serial.print(F(,))F()宏把字符串常量存放在 Flash程序存储器中而非 SRAM对内存有限的微控制器是标准优化手法。loop()函数则保证串口缓冲区的数据被持续消费void loop() { while (Serial3.available() 0) { printGPSData(); } delay(1000); }Serial3.available() 0说明 UART 缓冲区还有未处理的字符就持续调用printGPSData()当缓冲区清空后延时 1 秒再进入下一轮。相比上一环节用readStringUntil(\n)按整行字符串打印原始 NMEA这里的解码方案是字符级、流式、边收边解更适合实时性要求高的定位应用。第四步构建上传并用串口监视器验证在 PlatformIO 中构建并上传固件platformio run -t upload上传完成后打开串口监视器可执行platformio device monitor或使用 VS Code 中 PlatformIO 插件的 Serial Monitor 命令。当 GPS 传感器完成卫星捕获后串口监视器应输出类似下面的结果 Executing task: platformio device monitor --- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time --- Miniterm on /dev/cu.usbmodem1201 9600,8,N,1 --- --- Quit: CtrlC | Menu: CtrlT | Help: CtrlT followed by CtrlH --- 47.6423109,-122.1390293 - from 3 satellites输出说明47.6423109,-122.1390293十进制度坐标对即纬度,经度北纬 47.6423109°西经 122.1390293°- from 3 satellites本次定位由 3 颗卫星解算得到9600,8,N,1监视器波特率 9600、8 数据位、无校验、1 停止位与代码中Serial.begin(9600)一致。若迟迟没有输出或卫星数为 0通常意味着 GPS 天线视野不佳需要把传感器天线移到窗边或室外以获得更清晰的卫星信号。Grove GPS Air530 传感器上有两颗 LED蓝色 LED 在数据发射时闪烁绿色 LED 在接收到卫星数据时每秒闪烁一次可用于快速排查硬件状态。源码对照仓库中两版工程的差异在 3-transport/lessons/1-location-tracking 目录下并存两个阶段的完整工程可直接对照学习工程目录阶段printGPSData 核心逻辑code-gps/wio-terminal/gps-sensor读取原始 NMEASerial.println(Serial3.readStringUntil(\n))按行打印原始句子code-gps-decode/wio-terminal/gps-sensor解码 GPS 数据gps.encode(Serial3.read())逐字符解析并输出坐标对比可见两版工程的硬件初始化Serial3声明、SERCOM3_x_Handler中断转发、setup()中的引脚复用完全相同唯一的差异就是printGPSData与#include TinyGPS.h这印证了 TinyGPSPlus 的接入成本极低——只需加依赖、包含头、逐字符喂入三步即可从原始报文升级为结构化定位输出。原理纵深TinyGPSPlus 解析的报文是什么TinyGPSPlus 之所以能输出47.6423109,-122.1390293是因为它解析了 NMEA 中的 GGAGPS Fix Data定位数据句子。以课程 README 给出的完整报文为例$GNGGA,020604.001,4738.538654,N,12208.341758,W,1,3,,164.7,M,-17.1,M,,*67其中关键字段为$GNGGA句头。$起始GN表示信号来源此处为 GNSS 多系统联合GLONASS/GPSGGA表示定位数据句子020604.001UTC 时间4738.538654,N纬度字段。(dd)dmm.mmmm格式中4738.538654表示 47 度 38.538654 分换算为十进制度即 47 38.538654/60 ≈ 47.6423109方向符N北纬决定正负12208.341758,W经度字段同理换算为 122 8.341758/60 ≈ 122.1390293方向符W西经使其为负值1定位质量指标3参与定位的卫星数量——即最终输出中from 3 satellites的来源164.7,M海拔米。在基于单板电脑或虚拟 IoT 设备的同类实现中见 single-board-computer-gps-decode.md 及其完整代码 code-gps-decode/virtual-device/gps-sensor/app.pyPython 版使用pynmea2库通过pynmea2.parse(line)、dm_to_sd()完成同样的度分到十进制度换算并用lat_dir S/lon_dir W处理正负号。两者的语义完全对应TinyGPSPlus 的gps.location.lat()等价于 Python 端的dm_to_sd(msg.lat)加南纬取负gps.satellites.value()等价于msg.num_sats。扩展练习继续挖掘 NMEA 中的其他数据本环节的课程作业见 assignment.md鼓励进一步探索 NMEA 句子中除经纬度之外的信息例如当前日期与时间NMEA 报文中带有 UTC 时间戳微控制器可据此校准时钟原理与上一项目用 NTP 同步时间类似海拔elevationGGA 句子中的海拔字段上述报文中的164.7,MTinyGPSPlus 可通过gps.altitude.meters()获取当前速度VGM 等句子携带地速信息TinyGPSPlus 可通过gps.speed.kmph()/gps.speed.mph()获取挑战任务不依赖第三方库自行编写 NMEA 解码器从(dd)dmm.mmmm格式中提取经纬度可以更深刻地理解字符串解析与格式转换的细节。完成以上步骤后Wio Terminal 已经能够将 GPS 传感器输出的原始 NMEA 报文实时解码为结构化坐标这是本课程后续「将位置数据存储到云端」「可视化轨迹」「地理围栏」等环节的数据基础。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →