IoT-For-Beginners 实战:在 Raspberry Pi 上接入 Grove GPS Air530 传感器并读取 NMEA 定位数据 📅 发布时间:2026/9/16 1:16:14 👁 浏览次数: IoT-For-Beginners 实战在 Raspberry Pi 上接入 Grove GPS Air530 传感器并读取 NMEA 定位数据【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners本文基于 IoT-For-Beginners 仓库「Transport / 位置追踪」课程1-location-tracking中的 Raspberry Pi 配套文档对应 translations/bg/3-transport/lessons/1-location-tracking/pi-gps-sensor.md 及英文原版 pi-gps-sensor.md编写系统讲解如何将 Grove GPS Air530 这类 UART 串口 GPS 传感器接入树莓派并通过 Python 读取卫星定位的原始 NMEA 数据。读完本文你将掌握GPS 传感器与 Grove Base Hat 的硬件接线、解决蓝牙与串口冲突的系统级配置、基于pyserial的串口读取程序以及后续将原始 NMEA 语句解码为经纬度的进阶路径。硬件准备Grove GPS Air530 传感器本课程选用的是Grove GPS Air530 传感器。这款传感器支持同时连接多套全球导航卫星系统如美国的 GPS、俄罗斯的 GLONASS、中国的北斗等能够获得更快、更精准的定位卫星定位数据中$GNGGA等以GN开头的语句正是多星座系统输出的体现。传感器由两部分构成核心电子板负责接收并解析卫星信号输出定位数据外置天线通过一根细线连接到核心板用于捕获卫星发出的无线电波。 这是一款UART 传感器意味着它通过 UART通用异步收发传输器串行接口向外发送 GPS 数据。UART 协议在本仓库 2-farm/lessons/2-detect-soil-moisture 课程中已有讲解可回看复习。连接 GPS 传感器到 Raspberry Pi接线步骤将 Grove 连接线的一端插入 GPS 传感器上的插座。该插座有防呆设计只有一个方向能插进去。在Raspberry Pi 断电状态下将 Grove 线的另一端插入 Grove Base Hat 上标注为UART的插座。该插座位于中间一排靠近 SD 卡槽一侧与 USB 口和以太网口相对的另一端。摆放 GPS 传感器时应保证其外置天线对天空有清晰的视野——理想位置是开着的窗户旁或室外。天线周围没有遮挡时更容易获得稳定、干净的卫星信号。上电与指示灯判断给 Pi 上电并等待系统启动完成后可以通过传感器上的两颗 LED 快速判断工作状态LED含义蓝色 LED数据正在被发送/传输时闪烁绿色 LED每秒闪烁一次表示正在从卫星接收数据刚上电时蓝色 LED 应闪烁几分钟后绿色 LED 开始闪烁说明已经锁定到卫星信号。如果绿色 LED 始终不闪通常需要调整天线位置让它朝向天空。编程前的准备解决蓝牙与 UART 串口冲突在较新的树莓派型号支持蓝牙的版本上存在一个常见问题蓝牙复用了 Grove UART 端口对应的串口导致两者冲突。为了把串口让给 GPS 传感器需要修改两个系统启动文件。⚠️ 以下修改涉及系统级文件必须以sudo权限通过终端编辑无法直接用 VS Code 编辑VS Code 不具备提升权限。修改 /boot/config.txt在 VS Code 的终端中用nano编辑器打开配置文件sudo nano /boot/config.txt用方向键将光标移动到文件末尾粘贴以下三行配置dtoverlaypi3-miniuart-bt dtoverlaypi3-disable-bt enable_uart1粘贴可使用设备对应的常规快捷键Windows / Linux / Raspberry Pi OS 为CtrlvmacOS 为Cmdv。保存并退出按Ctrlx提示是否保存时按y再按enter确认覆盖/boot/config.txt。若操作失误可以不保存直接退出再重复上述步骤。这三项配置的作用可以理解为pi3-miniuart-bt把蓝牙重定向到 mini-UARTpi3-disable-bt禁用板载蓝牙以释放其占用的串口enable_uart1显式开启 UART 功能——三者配合将主 UART/dev/ttyAMA0完整让给 Grove Base Hat 的 UART 插座。修改 /boot/cmdline.txt接着编辑第二个文件sudo nano /boot/cmdline.txt该文件内容是若干用空格分隔的 key/value 键值对。需要删除所有键为console的条目它们会抢占串口作为内核控制台输出形如consoleserial0,115200 consoletty1删除后示例——如果原始文件是consoleserial0,115200 consoletty1 rootPARTUUID058e2867-02 rootfstypeext4 elevatordeadline fsck.repairyes rootwait修改后的版本应为rootPARTUUID058e2867-02 rootfstypeext4 elevatordeadline fsck.repairyes rootwait同样用上述方式保存并退出nano然后重启 Pi。重启完成后通过 VS Code直接在 Pi 上启动或经 Remote SSH 扩展远程连接重新连上设备。若需要回顾 VS Code 在 Pi 上的安装与启动流程可参考 1-getting-started/lessons/1-introduction-to-iot/pi.md。编写 Python 程序读取 GPS 数据建立项目目录在pi用户的主目录下创建gps-sensor文件夹并在其中新建app.pymkdir ~/gps-sensor然后在 VS Code 中打开gps-sensor文件夹。安装 pyserialGPS 模块通过串口发送 UART 数据Python 侧需要安装pyserial包来与串口通信pip3 install pyserial核心读取程序将以下代码写入app.pyimport time import serial serial serial.Serial(/dev/ttyAMA0, 9600, timeout1) serial.reset_input_buffer() serial.flush() def print_gps_data(line): print(line.rstrip()) while True: line serial.readline().decode(utf-8) while len(line) 0: print_gps_data(line) line serial.readline().decode(utf-8) time.sleep(1)这段代码的逻辑拆解如下从pyserial包导入serial模块连接到/dev/ttyAMA0串口——这正是 Grove Pi Base Hat 为其 UART 插座使用的串口地址波特率9600与 GPS 模块默认一致timeout1保证无数据时readline不会永久阻塞调用reset_input_buffer()与flush()清空该串口连接上的既有数据避免读到残留乱码定义print_gps_data函数将传入的行用rstrip()去掉末尾换行符打印到控制台程序进入无限循环每轮尽量多地读取串口中的文本行逐行调用print_gps_data输出全部读完后休眠 1 秒再重试。 该程序的完整代码位于仓库 code-gps/pi/gps-sensor/app.py。需要说明的是仓库中的版本将print_gps_data定义为无参函数通过闭包引用循环内的全局line并在循环外层套上了try-except——功能与本文展示的版本等价。运行与输出初见 NMEA 语句运行程序后你会看到来自 GPS 传感器的原始输出形如$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这些看似「乱码」的字符串实际上是标准 GPS 数据——NMEA 消息遵循 NMEA 0183 标准。每条消息以$开头后跟 2 个字符表示信号源GP为美国 GPS、GN为多星座/GLONASS、BD为北斗等、3 个字符表示消息类型随后是用逗号分隔的字段以换行符结尾。常见的类型包括类型含义GGAGPS 定位数据包含纬度、经度、海拔以及用于计算定位的可见卫星数ZDA当前日期与时间含本地时区信息GSV可见卫星的详细信息以示例中的$GNGGA语句为例020604.001是 UTC 时间戳4738.538654,N表示北纬 47 度 38.538654 分12208.341758,W表示西经 122 度 08.341758 分1表示有效定位3表示参与定位的卫星数164.7,M为海拔-17.1,M为椭球高。NMEA 的(d)ddmm.mmmm分度格式可换算为十进制度数例如4738.538654换算后为47.6423109度。排错UnicodeDecodeError 与 try-except如果停止并重新启动代码时出现以下错误UnicodeDecodeError: utf-8 codec cant decode byte 0x93 in position 0: invalid start byte UnicodeDecodeError: utf-8 codec cant decode byte 0xf1 in position 0: invalid continuation byte原因在于程序启动时读取到的第一个字节可能正好落在一个 UTF-8 字符的中间导致整行解码失败。解决方案是为 while 循环加上try-except块解码失败时跳过当前行、继续读取下一整行即可。仓库 code-gps/pi/gps-sensor/app.py 中采用的正是这种写法while True: try: line serial.readline().decode(utf-8) while len(line) 0: print_gps_data() line serial.readline().decode(utf-8) # Theres a random chance the first byte being read is part way through a character. # Read another full line and continue. except UnicodeDecodeError: line serial.readline().decode(utf-8) time.sleep(1)进阶把原始 NMEA 解码成经纬度读取到原始 NMEA 数据只是第一步。本课程还提供了「解码」环节使用开源库pynmea2从 NMEA 消息中提取纬度、经度与卫星数示例输出为47.6423109,-122.1390293 - from 3 satellites对应实现见 code-gps-decode/pi/gps-sensor/app.py通过pynmea2.parse()解析每一行仅当sentence_type GGA时处理定位数据用pynmea2.dm_to_sd()将 NMEA 分度格式转为十进制度数再根据lat_dir/lon_dir判断南北纬、东西经并转为正负号。详细步骤可继续阅读 single-board-computer-gps-decode.md。如果你没有物理硬件本课程还提供了两条平行路径虚拟 IoT 设备通过 CounterFit 模拟一个运行在/dev/ttyAMA0串口上的 UART GPS 传感器支持直接设定经纬度、粘贴 NMEA 语句或上传 GPX 轨迹文件见 virtual-device-gps-sensor.mdWio Terminal使用 PlatformIO 与 C 代码读取同一款 Grove GPS 传感器见 wio-terminal-gps-sensor.md。小结至此你已经在 Raspberry Pi 上完成了 GPS 传感器的硬件接入、系统级串口冲突修复并编写 Python 程序通过 UART 成功读取了卫星定位的原始 NMEA 数据。这为后续课程中「存储位置数据」「在地图上可视化位置」「设置地理围栏」等进阶内容打下了数据基础——三者分别对应 2-store-location-data、3-visualize-location-data 与 4-geofences它们共同构成了完整的车辆位置追踪 IoT 方案。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考