用 Serial Studio 可视化 Arduino + GY-NEO6MV2 GPS 定位数据:TinyGPS 示例完全指南
【免费下载链接】Serial-StudioOpen-source telemetry dashboard. Supports UART, BLE, MQTT, Modbus, CAN Bus and more.项目地址: https://gitcode.com/GitHub_Trending/se/Serial-Studio
本指南以仓库 examples/TinyGPS 为例,完整讲解如何将 GY-NEO6MV2 GPS 模块通过 Arduino(Uno/Nano/Mega 2560)采集的经纬度与海拔数据,以$latitude,longitude,altitude;文本帧发送给开源遥测仪表盘 Serial Studio,并在地图 Widget 上实时显示位置、将海拔写入 CSV。读完本文,你将掌握 Arduino 端 NMEA 解析与帧封装的完整写法、Serial Studio 端帧解析与地图 Widget 的配置方法,以及排查"地图无数据、解析错位"等典型问题的思路。
示例整体工作流程
整个示例由三部分组成,链路清晰:GPS 模块 → Arduino → Serial Studio。
- GPS 模块(GY-NEO6MV2)以 9600 baud 输出标准 NMEA 语句;
- Arduino 上电后通过 TinyGPS 库解析 NMEA,取出纬度、经度、海拔,并按 Serial Studio 的帧协议封装成一行文本通过串口发出;
- Serial Studio 以 115200 baud 读取该串口,按帧起始符
$、结束符;、分隔符,切分数据,交给 TinyGPS.ssproj 中预配置的 GPS Map 分组,最终渲染到地图 Widget。
兼容性说明:只要是输出 9600 baud NMEA 语句的 GPS 模块均可使用;示例固件默认面向 Arduino Uno/Nano,切换到 Mega 2560(或任何带空闲硬件串口的板子)只需改动固件中两行代码。
硬件连接
需要准备的硬件:一块 GY-NEO6MV2 GPS 模块、一块 Arduino 开发板。
- Uno / Nano(默认方案):固件通过
SoftwareSerial读取 GPS。将 GPS 模块的 TX 引脚接到 Arduino 的pin 2(即固件中软件串口的 RX 引脚),GPS 模块 RX 引脚接 Arduinopin 3。GPS 模块必须以9600 baud工作,这与固件默认值一致。 - Mega 2560 / 带空闲硬件串口的板子(推荐方案):改用
Serial1硬件串口,将 GPS 模块 TX 接到 Mega 的RX1引脚,然后在固件中交换下面两行——取消第一行的注释、注释掉第二行:
//HardwareSerial &gpsSerial = Serial1; SoftwareSerial gpsSerial(2, 3); // For Arduino UNO/Nano从源码结构看(TinyGPS.ino),两个串口对象共用同一个gpsSerial变量名,因此只需要这一处两行改动即可完成迁移,其余代码无需变化。
Arduino 固件:NMEA 解析与帧封装
1. 安装 TinyGPS 库
- 打开 Arduino IDE,进入Sketch > Include Library > Manage Libraries;
- 搜索 "TinyGPS" 并安装。
2. 固件工作原理
固件 TinyGPS.ino 的核心逻辑分为三步:
(1)初始化双串口。setup()中以 115200 启动Serial(用于向 Serial Studio 发送数据),以 9600 启动gpsSerial(用于读取 GPS 模块):
Serial.begin(115200); gpsSerial.begin(9600);这里要特别强调两个波特率的分工:GPS 模块固定 9600 baud(NMEA 标准默认值),而 Arduino 与 Serial Studio 之间是 115200 baud。Serial Studio 端 TinyGPS.ssproj 中的 UART 源正是配置为baudRate: 115200,两者严格对应,任何一端改错都会导致乱码或收不到数据。
(2)在loop()中逐字节喂给 TinyGPS 编码器,并读取位置:
while (gpsSerial.available() > 0) { char receivedChar = gpsSerial.read(); gps.encode(receivedChar); }gps.encode()是 TinyGPS 的状态机入口,每收到一个字节就尝试推进 NMEA 句子的解析,无需等待完整句子。随后用gps.get_position()取原始整数坐标并转换为十进制度数:
latitude = rawLatitude / 1000000.0; // TinyGPS 原始值为百万分之一度 longitude = rawLongitude / 1000000.0;海拔则通过gps.f_altitude()获取;若返回TinyGPS::GPS_INVALID_F_ALTITUDE(无效值,通常发生在尚未锁定卫星时),则回退为0.0,避免把无意义的噪声数据发到上位机。
(3)按帧协议封装并发送。固件使用了 Serial Studio 的三要素帧格式:
| 要素 | 字符 | 作用 |
|---|---|---|
| 起始分隔符 | $ | 标记一帧数据的开始 |
| 结束分隔符 | ; | 标记一帧数据的结束 |
| 字段分隔符 | , | 分隔纬度、经度、海拔三个字段 |
发送代码如下:
Serial.print('$'); // Frame start sequence Serial.print(latitude, 6); // Latitude with 6 decimal places (index = 1) Serial.print(','); // Frame separator Serial.print(longitude, 6); // Longitude with 6 decimal places (index = 2) Serial.print(','); // Frame separator Serial.print(altitude, 2); // Altitude with 2 decimal places (index = 3) Serial.println(';'); // End of the data packet delay(5);最终在串口上产生形如下面的完整帧:
$latitude,longitude,altitude;其中纬度、经度各保留6 位小数(约 0.11 米的分辨率),海拔保留2 位小数;每帧之间delay(5)留出节拍。这里有一个与 Serial Studio 字段索引密切相关的细节:$后的第一个字段是纬度(索引 1)、第二个是经度(索引 2)、第三个是海拔(索引 3),TinyGPS.ssproj中三个数据集的index字段(分别为 1、2、3)正是与此一一对应,任何一端调换顺序都会导致地图上的点位置错乱。
Serial Studio 端配置:导入工程与手工配置
推荐方式:直接导入 TinyGPS.ssproj
- 从 Serial Studio 官网下载并安装软件;
- 启动 Serial Studio,在 Project Editor 中打开本示例自带的 TinyGPS.ssproj。
该工程文件已经包含解析 GPS 帧所需的全部配置。查看工程 JSON 可以看到:
- 数据源:类型为 UART(
busType: 0),baudRate: 115200,与固件发送波特率一致; - 帧检测:
frameStart: "$"、frameEnd: ";",并附带一段内置的 JavaScript 解析器,用frame.split(',')把一帧按逗号切分成数组; - 数据分组 "GPS Map":包含三个数据集——
Latitude(单位°,Widget 类型lat)、Longitude(单位°,Widget 类型lon)、Altitude(单位m,Widget 类型alt),分组本身是widget: "map"的地图分组。
手工配置:从零搭建
如果希望自己动手配置,关键参数如下:
- 帧起始序列(Frame start sequence):
$ - 帧结束序列(Frame end sequence):
; - 数据分隔符(Data separator):
,
配置完成后,点击工具栏上的GPS Map按钮,Serial Studio 会自动创建 GPS 地图 Widget。该 Widget 使用纬度、经度显示当前位置,海拔数据则记入 CSV 日志供后续分析。
从底层实现看,Serial Studio 的 Widget 解析逻辑(WidgetResolution.cpp)会将widget值为"gps"或"map"的分组解析为DashboardGPS类型,这就是"GPS Map 按钮一键生成地图 Widget"的机制来源。
查看与记录 GPS 数据
配置完成后,在 Serial Studio 中选择 Arduino 所在的串口并连接:
- 串口波特率选115200(UART 源已预置该值,只需核对端口号);
- 地图 Widget 会实时显示当前 GPS 位置;卫星图瓦片由网络加载,首次显示可能有短暂延迟;
- 海拔数据可配置为写入 CSV 文件,便于事后回放分析。
地图 Widget 本身还提供了丰富的交互能力。以 GPS.h 中定义的属性为例,它实现了基于瓦片(tile)的地图渲染,并暴露了mapType(底图类型)、autoCenter(自动居中跟随)、showWeather(天气叠加层)、showNasaWeather(NASA 云图叠加层)、plotTrajectory(轨迹绘制)、zoomLevel(缩放级别)等可配置项;同时支持滚轮缩放、鼠标拖拽平移以及世界范围瓦片预缓存(GPS.cpp 中的precacheWorld、latLonToTile等接口)。对应地在 GPS.qml 中,这些设置会通过Cpp_JSON_ProjectModel.widgetSettings()持久化保存,并提供了底图类型下拉框、自动居中、天气叠加、轨迹绘制等工具栏开关,你可以在运行中随时切换而无需重新编辑工程。
常见问题排查
- 地图上没有数据:GPS 模块必须处于开阔天空环境下才能完成卫星锁定(冷启动通常需要数十秒到数分钟);同时确认 Serial Studio 中选择的串口端口正确、波特率为 115200,且 Arduino 已成功烧录固件。
- 解析结果错乱 / 字段错位:检查工程设置中的起始序列(
$)、结束序列(;)、分隔符(,)是否与固件一致;并核对数据集索引是否按"纬度=1、经度=2、海拔=3"的顺序排列,与固件Serial.print的发送顺序严格对齐。 - 乱码:多为波特率不匹配。GPS 模块务必为 9600 baud,Arduino 与 Serial Studio 之间务必为 115200 baud,三端缺一不可。
参考资源
- 示例完整源码与工程文件:examples/TinyGPS
- Arduino 固件:TinyGPS.ino
- Serial Studio 工程配置:TinyGPS.ssproj
- 地图 Widget C++ 实现:GPS.h、GPS.cpp
- 地图 Widget QML 界面:GPS.qml
- Widget 类型解析逻辑:WidgetResolution.cpp
【免费下载链接】Serial-StudioOpen-source telemetry dashboard. Supports UART, BLE, MQTT, Modbus, CAN Bus and more.项目地址: https://gitcode.com/GitHub_Trending/se/Serial-Studio
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考