如何解析Raspberry Pi Pico读取的sr1612z1 GPS模块NMEA数据?
解决Raspberry Pi Pico解析SR1612Z1 GPS模块NMEA数据的问题
核心问题说明
你当前收到的NMEA数据没有有效定位信息:
$GNGLL语句的经纬度字段为空,定位状态标记为V(无效);$GPGSV只是卫星可见状态报告,不包含经纬度、速度等定位结果。
这说明GPS模块还未完成搜星定位,需要将天线放置在室外开阔区域,等待数分钟让模块捕获卫星信号。
修正数据读取与分割的错误
你当前的代码直接将字节对象转成字符串,会混入b'等标识,且未按NMEA语句的换行分隔规则处理,导致分割结果混乱。正确的处理步骤如下:
正确的MicroPython读取与解析代码
import machine # 初始化UART(根据你的实际引脚、波特率调整,SR1612Z1默认波特率通常为9600) uart = machine.UART(0, baudrate=9600, tx=0, rx=1) while True: if uart.any(): # 读取单条NMEA语句,解码为字符串并去除首尾空白字符 line = uart.readline().decode('utf-8').strip() # 仅处理合法的NMEA语句(以$开头) if line.startswith('$'): parts = line.split(',') # 解析包含核心定位数据的$GNGGA语句 if parts[0] == '$GNGGA': fix_status = parts[6] # 0=未定位,1=有效定位,2=差分定位 if fix_status != '0': # 转换经纬度格式:DDMM.MMMMM → DD.DDDDD lat = parts[2] lat_dir = parts[3] lat_deg = float(lat[:2]) + float(lat[2:])/60 if lat_dir == 'S': lat_deg = -lat_deg lon = parts[4] lon_dir = parts[5] lon_deg = float(lon[:3]) + float(lon[3:])/60 if lon_dir == 'W': lon_deg = -lon_deg print(f"经纬度:{lat_deg:.6f}, {lon_deg:.6f}") print(f"锁定卫星数:{parts[7]}") print(f"海拔高度:{parts[9]} 米") # 解析包含速度、航向的$GNRMC语句 elif parts[0] == '$GNRMC': fix_status = parts[2] # A=有效定位,V=无效 if fix_status == 'A': # 节转换为公里/小时(1节=1.852公里/小时) speed_kmh = float(parts[7]) * 1.852 course = parts[8] print(f"移动速度:{speed_kmh:.2f} km/h") print(f"航向角度:{course}°")
关键解析逻辑说明
- 按行读取:NMEA协议每条语句以
\r\n分隔,用readline()确保每次处理一条完整语句,避免多条语句混分割。 - 优先处理核心语句:
$GNGGA:包含经纬度、定位状态、卫星数、海拔等核心定位数据;$GNRMC:包含速度、航向、定位时间等实用信息;
- 经纬度格式转换:NMEA输出的经纬度是
DDMM.MMMMM(度分格式),需要转换为十进制的DD.DDDDD格式才能直接使用; - 状态判断:必须先检查定位状态字段(
$GNGGA的第7项、$GNRMC的第3项),只有状态有效时,后续字段的数据才可信。
额外注意事项
- 确认UART的波特率、引脚与GPS模块的配置一致,SR1612Z1默认波特率一般为9600;
- 解码时使用
utf-8编码,避免出现乱码; - 处理空字段:未定位时部分字段为空,转换数值前需判断,避免抛出
ValueError。
内容的提问来源于stack exchange,提问作者MISTERME
相关产品推荐
相关产品推荐

