最近在给一台移动机器人做 GPS 导航改造,用一块基于 u-blox NEO-M8N 的模块做定位。上电后打开串口助手,结果满屏都是$GxTXT开头的消息,偶尔夹杂着几条看起来像报错的文本,就是等不到$GNGGA和$GNRMC这种正常的定位语句。模块状态灯一直在闪,RXD/TXD 也都正常,天线也放到窗边了,可就是死活不出定位数据。
这种情况我其实不是第一次遇到。以前调 GPS 模块的时候也见过类似现象,不过当时没那么严重,只是偶尔输出一条$GxTXT,没有像这次一样彻底刷屏。但“一直输出 $GxTXT、无法定位”这个组合,确实是 u-blox 模块调试里一个很有代表性的坑,把硬件和配置的疑点几乎全占了。这篇文章就按我实际排查的顺序来写:先看懂消息,再查硬件,再查配置,最后做冷启动恢复。不管你是做无人机、机器人、还是车载定位装置,只要模块用的是 u-blox 系列,思路都通用。
1. 先把奇怪的输出看明白:$GxTXT 到底是什么
1.1 消息格式与常见字段解析
当咱们把 USB-TTL 接上 u-blox 模块,波特率设在 9600 或者 38400,打开串口助手,可能会看到这样的输出:
$GxTXT,01,01,01,ROM CORE 1.00 (59842) ROM BASE 0x10800000 FWVER=HPS 1.13*62 $GxTXT,01,01,01,FIRMWARE VERSION: HPS 1.13 (82457)*51$GxTXT是标准 NMEA 协议里的“文本传输”语句,专门用来传递模块自己产生的提示信息,包括启动信息、固件版本、错误提示等。它的字段结构是这样的:
$GxTXT:前缀,其中 Gx 表示消息所属星座系统。GP 代表 GPS,GL 代表 GLONASS,GA 代表 Galileo,GB 代表北斗,GN 表示多星座融合消息。- 第 1 个字段:本条文本在整组消息中的序号。比如 01 就表示这是第 1 条。
- 第 2 个字段:整组消息的总条数。通常也是 01。
- 第 3 个字段:消息类型,01 一般表示错误或警告,02 表示普通提示。
- 第 4 个字段以后:实际的文本内容,像固件版本号,或者是某些错误信息。
这里要特别说明一下Gx前缀的“多星座”特性。现在新一点的 u-blox 模块(比如 NEO-M8N、NEO-M9N 系列)默认就是多星座输出的,所以你会看到$GNTXT、$GNGGA、$GNRMC这些以 GN 开头的语句。而老一点的 NEO-6M 只支持 GPS 单星座,输出的是$GPTXT、$GPGGA、$GPRMC。如果看到的是 GP 开头,说明模块工作在 GPS 单系统模式,这本身不是问题,关键是后面有没有正常的定位语句输出。
1.2 正常的上电输出长什么样
正常的 u-blox 模块在掉电重启后,你会在串口上看到先输出一两条$GxTXT,内容一般是固件版本或者 ROM 信息,然后紧接着就开始输出定位相关的 NMEA 语句。哪怕模块还没收到卫星信号,输出也不会停,只是语句里面的定位状态是无效的。
以 NEO-M8N 为例,正常启动大约是这个样子:
$GNTXT,01,01,01,ROM CORE 1.00 (59842)*3C $GNGGA,082126.000,,,,,0,0,,,M,,M,,*4A $GNGLL,,,,,082126.000,V,N*5F $GNGSA,A,1,,,,,,,,,,,,,,,*1E $GNRMC,082126.000,V,,,,,,,110824,,,D*55 $GNVTG,,,,,,,,,N*2E你看,就算没有定位,GGA 里的经纬度字段是空的,RMC 里的状态是 V(Void/invalid),但语句照样一条接一条往外发。这就相当于模块在跟你说:“我活着,但我没信号。” 而当串口里一直只有$GxTXT,没有 GGA/RMC/GSV 这些结果时,说明模块不是“没信号”,而是“没干活”或者“配置不对”。这个区分很重要,很多人排查半天,其实一直在错误的方向上打转。
1.3 还有一种输出:反复报错的 $GxTXT
如果$GxTXT的内容不是固件版本,而是类似EEPROM ERROR、GPS START ERROR、NO FIX这样的文本,那更要警惕。这种情况多半是模块内部 Flash 里保存的用户配置出了错,或者是运行时检测到外部异常。举个实际例子,有块模块在错误配置后,每次上电都会先输出一行带EEPROM字样的$GxTXT,然后没有任何定位语句。我一开始不懂,还以为只是启动信息,直到换成另一块正常模块对比,才发现问题出在配置区。
所以,看到$GxTXT时不要直接划走,先把文本内容读出来。文本里往往藏着模块自己给出的线索。如果文本是版本信息,那可能只是配置问题;如果文本里有 ERROR 字样,那大概率是存储或者硬件层面的异常。
2. 第一步排查:硬件供电和天线,问题往往就藏在这里
2.1 供电电压、电流和纹波都要仔细看
u-blox NEO 系列模块的 VCC 典型值是 3.3V,不少模块设计成可以输入 5V,然后板载 LDO 转成 3.3V。表面上看 5V 供电没问题,但如果 LDO 的输入电压和环境温度变化大,输出纹波可能会明显增大,尤其在天线刚开始工作的瞬间,电流冲击会把电压拉低,模块就有可能在启动过程中反复重启,最后表现为只输出启动文本或者干脆乱码。
我建议先用手头的万用表量一下模块 VCC 对地的实际电压,再看数据手册里要求的正常范围。比如 NEO-M8N 的 VCC 工作范围是 2.7V 到 3.6V,如果量出来只有 2.4V,那问题就很明确了。另外,有条件的话尽量用示波器看一下 VCC 的纹波,纹波超过 50mV 就需要注意。没有示波器也没关系,如果模块电源线上并联了一个 100uF 的电解电容和 100nF 的陶瓷电容,很多瞬态跌落问题能缓解不少。
电流这块更关键。有些开发板的 3.3V 输出能力只有 100mA 左右,GPS 模块本身的功耗虽然不高,但如果接了有源天线,整体电流会明显上升。有源天线内部的 LNA 一般需要 5mA 到 20mA 左右的电流,不同品牌差异不小。我在测试时习惯在电源回路里串一个万用表测电流,正常情况下模块加有源天线,工作电流会在 50mA 到 150mA 之间波动。如果你测出来只有 1mA 以下,那模块的基带基本没有工作,电源和焊接要先排查。
2.2 天线问题:无源、有源、短路、开路
天线环节是重灾区,我见过太多人在这里栽跟头。GPS 天线大体分两类:
- 无源陶瓷天线:内部没有放大器,直接通过 RF 走线接到模块的 RF_IN 引脚。优点是便宜简单,缺点是增益低,对信号环境要求高,在室内基本收不到星。
- 有源天线:内部带 LNA,需要额外供电。常见的工作电压是 3.3V 或 5V,供电通过馈线的中心导体送到天线端。有源天线增益高,适合放在户外或者遮挡较多的地方,也方便拉长馈线。
如果你用的是有源天线,但模块没有给天线供电,或者模块上压根没有天线供电电路,结果就是信号极弱,定位很难成功。反过来,如果你把有源天线接到了不支持有源天线的模块上,馈线中心导体上可能长期挂着高电平,运气不好还会烧掉天线内部器件。
排查天线时,我喜欢用万用表电阻档测馈线中心导体与屏蔽层之间的电阻。不同天线表现不一样,但有以下规律:
- 无源陶瓷天线:中心导体对屏蔽层应是开路状态。
- 有源天线:因为内部有 LNA,中心对屏蔽会呈现类似二极管的正反电阻特性,正向几百欧到几十千欧,反向阻值更大。
如果测出来中心对屏蔽完全短路,那基本可以断定天线馈线内部破了或者天线内部短路,直接换天线。如果测出来完全开路,也可能说明馈线中间断了。对于有源天线,还要确认供电电压正确,常见的模块会在板子上标注 V_ANT 引脚,有的用 3.3V,有的用 5V,接错轻则信号差,重则烧 LNA。
2.3 接线顺序和电平匹配
接线这块,很多刚上手的人会在 TX/RX 上打转。u-blox 模块上,模块的 TX 要接单片机的 RX,模块的 RX 要接单片机的 TX,GND 必须共地。如果反了,串口助手一类工具可能有微弱的 FIFO 数据,但基本看不到正常语句。
电平匹配容易被忽视。NEO-M8N 这类模块的 IO 口最高耐压一般在 3.6V 左右,如果你的单片机是 5V 系统,直接拿 5V TX 去驱动模块 RX,轻则边沿失真导致通信质量差,重则损坏模块。我见过有人把 5V Arduino 的 TX 直接接到 NEO-M8N 的 RX 上,结果模块上电后一直输出启动信息,后面的数据全是乱码,最后加了一个双向电平转换模块才恢复。
还有一个细节:有些模块板载了 3.3V 稳压器,可以直接接 5V 电源。但如果你是从裸模块飞线,千万不要把 5V 直接怼到模块 VCC 上。请先查模块资料或者原理图,确认 VCC 允许的范围,再接线。
3. 第二步排查:用 u-center 重新梳理模块配置
3.1 备份配置是动手前最重要的一步
硬件检查完后,下一步是借助 u-blox 官方的 u-center 工具。这个软件可以在 u-blox 官网下载,Windows 版最常用。把模块通过 USB-TTL 连到电脑,打开软件后,在右下角选择 COM 口和波特率。默认波特率一般是 9600,但如果之前有人改过,你可能要逐个尝试 38400、115200 甚至 460800。
连上模块之后,强烈建议先把当前配置备份下来。在 u-center 里,通过菜单Receiver -> Configuration -> Generate Configuration...可以把当前配置生成一个 .txt 或者 .xml 文件;也可以通过View -> Configuration View里的 CFG-CFG 功能把配置导出。为什么要备份?因为后面的排查动作可能会清空配置,万一模块本身没问题,只是配置被我们改坏了,至少还能恢复回去,避免白白浪费时间。
3.2 检查输出协议:NMEA 是否被关闭
我那块“满屏 $GxTXT”的模块,最后查出来的原因就是这里的配置:它的 UART1 输出协议被改成只输出 UBX 协议,NMEA 输出被关闭了。模块本身并没有坏,它一直很健康地工作,只是把“该发的定位语句”全关了,只剩下$GxTXT这种独立于协议开关的文本消息在输出。
在 u-center 里检查方法是这样的:
- 打开菜单
View -> Configuration View(快捷键 Ctrl+F)。 - 找到
PRT配置项,选择 UART1。 - 查看
Target下的Out协议。 - 正常应该勾选
UBX、NMEA、RTCM3里的至少一个,做常规定位时,NMEA一定要勾选。 - 如果只勾了
UBX,那么串口上会出现的是二进制的 UBX 帧,肉眼看着就是一堆乱码;如果连UBX也关了,那就只剩$GxTXT这种文本消息还能看见。
这种情况的解决方案很简单:把NMEA勾上,点击发送,让配置立即生效。然后回到串口助手,你应该就能看到 GGA/RMC 语句了。但要注意,如果这次改完没有保存到 Flash,模块掉电重启后又会变回原来的配置,所以改完后记得做保存操作。
3.3 检查 GNSS 星座和工作模式
u-blox 模块的多星座支持很好用,但配置里一旦关掉了某些星座,定位速度和能力会受影响。比如说,某个模块原本开了 GPS 和北斗,但后来被改掉了,只留 GLONASS,而你在国内测试时 GLONASS 卫星数量本来就少,冷启动可能要好几分钟甚至完全悬着。
打开 u-center 的GNSS配置页面,可以看到当前启用星座和各星座的通道数。建议尽量开启模块支持的所有星座。NEO-M8N 支持 GPS、北斗、GLONASS、Galileo 等多星座,开启后,冷启动抓星会快很多。同时,Assisted GNSS之类的功能可以根据需要进行配置,不是必须的,但很多模块默认关闭,不影响本文的定位流程。
模块还有几种工作模式,比如“便携式”“车载”“静态”等,不同模式下的动态模型和最大加速度不一样。如果你把车载模式用在低速机器人上,通常问题不大;反过来,如果你以静态模式在高速车上测试,定位效果就可能变差。默认的“便携式”模式覆盖范围最广,前期调试阶段用这个模式最省心。
3.4 波特率必须匹配,改了要保存
波特率不匹配造成的现象很迷惑:打开串口助手后,看到满屏乱码,或者偶尔出现几个正常字符,很多人会以为是接线问题。其实只要把波特率切换成模块配置的波特率,数据马上就正常了。
u-blox 模块默认波特率是 9600,但开发板上经常被改到 115200。还有更极端的,我接手过一块前同事调试过的板子,波特率被改成 460800,当时我试了 9600、38400、115200 都不对,最后是把 460800 试出来才连上的。所以,如果串口一直是乱码,不要老老实实只试 9600 和 115200,把常用的几个波特率全试一遍,包括 460800。
另外特别提醒:u-blox 模块的配置是可以掉电保存的。如果你在 u-center 里改了波特率,没有执行Receiver -> Action -> Save Config或者勾选Save on shutdown再掉电,那下次上电大概率还是旧波特率。这属于“改了等于没改”的经典坑。
4. 第三步排查:冷启动与恢复出厂配置
4.1 恢复默认配置:比冷启动更彻底的清理
如果硬件正常、供电正常、天线正常,但模块还是只输出$GxTXT,那极有可能是模块内部的非易失存储里躺着问题的配置文件。u-blox 模块支持电池供电的 RAM 保存配置,也支持写入内部 Flash,有些用户修改配置后掉电保存,结果把 NMEA 输出或者 GNSS 星座改坏了,下次上电就出现这种“能开机但没法定位”的怪现象。
在 u-center 里恢复默认配置的操作路径很直接:
- 菜单
Receiver -> Action -> Restore Default。 - 再执行一次
Receiver -> Action -> Cold Start,让模块重新开始搜星。
恢复默认配置后,模块会回到出厂状态,UART1 默认输出 NMEA 和 UBX 协议,默认波特率是 9600,GNSS 星座恢复成默认组合。如果之前的问题是配置造成的,到这一步基本就能解决。
有个细节要注意:不同型号的默认波特率可能不一样,比如部分 M8N 开发板默认 9600,而有些 RTK 模块默认 115200。恢复默认配置后,如果串口没输出,别急着怀疑没恢复成功,先确认当前波特率是不是又变回 9600 了。
4.2 手动发送命令:应对没有电脑的嵌入式环境
实际项目里,GPS 模块经常是接着单片机、树莓派或者 ROS 主机,不方便搬着 u-center 到处跑。这时候可以用串口直接发 UBX 二进制命令来实现冷启动和配置恢复。
一个常用的冷启动命令是 UBX-CFG-RST,典型字节序列为:
B5 62 06 04 04 00 FF FF 00 00 0C 5D这条命令会让模块执行冷启动,也就是清空当前定位状态并重新搜星。如果模块配置存放区损坏比较严重,冷启动可能不生效,这时可以发清除用户配置的命令 UBX-CFG-CFG:
B5 62 06 09 0D 00 00 00 00 00 FF FF 00 00 00 00 00 00 17 33这条命令会清除 Flash 中的用户配置,下次上电时使用默认参数。
不过这里必须提醒一句:UBX 命令的校验和会随命令内容变化,而且不同固件版本对同一命令的实现可能有差异。网上搜到的命令字节码,不一定在你的模块上适用。最靠谱的办法是把模块先接到 u-center,在里面手工操作一次,同时用 u-center 的报文日志功能把实际发出的数据包记录下来,之后就能直接拿来用。
4.3 恢复后如何验证输出
恢复默认配置并冷启动后,模块正常工作的输出应该是这样的:
$GNGGA,082126.000,2231.1234,N,11356.5678,E,1,12,0.8,45.6,M,-1.2,M,,*53 $GNGLL,2231.1234,N,11356.5678,E,082126.000,A,A*4F $GNGSA,A,3,02,05,09,12,17,21,23,25,28,30,,,1.1,0.8,0.7*1F $GNRMC,082126.000,A,2231.1234,N,11356.5678,E,0.2,45.6,110824,,,D*77 $GNVTG,45.6,T,,M,0.2,N,0.3,K,A*3C如果还没有定位,GGA 里的状态位会是 0 或者 V,RMC 里的状态位会是 V,但语句本身会一直周期性输出。所以,“能看到 GGA/RMC”是模块进入正常工作的底线。至于定位成不成功,那是信号和天线层面的问题。我的经验是,把天线放到窗外或者楼顶,冷启动之后一般 1 到 3 分钟内就能出定位,如果在室内,等 10 分钟没定位也很正常,别因此又误判成模块故障。
4.4 一个容易混淆的“软件包报错”
顺带说一句,调试过程中如果是在 Linux 环境里装 ROS 或者其他工具包,终端里可能见过“无法定位软件包”这种报错,比如无法定位软件包 ros-noetic-desktop-full。这其实是 apt 软件源配置有问题,跟 GPS 的“无法定位”完全是两码事,别混为一谈。GPS 这边“无法定位”指的是模块收不到足够卫星信号、算不出经纬度;apt 那边的“无法定位”是仓库里没有对应安装包名称。如果看到这类报错,去检查软件源列表,而不是回头折腾 GPS 模块。
5. 常见问题与排查技巧实录
5.1 问题速查表
把我在 GPS 模块调试中遇到过的典型现象、原因和解决办法整理成表,方便快速对照:
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 只输出 $GxTXT,无 GGA/RMC | 输出协议被改成 UBX only,或 NMEA 输出被关闭 | 用 u-center 检查 PRT 配置,重新勾选 NMEA |
| 只输出 $GxTXT,文本里带 ERROR | 模块 Flash 中配置损坏 | 执行恢复默认 / 用 UBX-CFG-CFG 清除配置 |
| 上电后没有任何输出 | 波特率不匹配、TX/RX 接反、供电不足 | 检查波特率与接线,测量供电 |
| 输出全是乱码 | 波特率不匹配,或模块 IO 被 5V 信号损坏 | 重新匹配波特率,增加电平转换 |
| 输出正常但一直 V/无定位 | 天线损坏、室内信号遮挡、有源天线未供电 | 换天线、把模块放到窗边/室外、给天线供电 |
| 放置一段时间后突然恢复 | 首次冷启动耗时过长,或所在位置遮挡严重 | 耐心等 5-10 分钟,或挪到信号好的位置 |
| 电脑上定位正常,接到板子不行 | 开发板供电能力不足,或板子串口接线有误 | 加强供电,检查串口接线,必要时加电容 |
| 输出中只有 $GxTXT,无任何 NMEA 且硬复位无效 | 模块主控异常或固件损坏 | 尝试重新刷固件,或更换模块 |
5.2 四个值得反复强调的坑
第一个坑:在室内测试等于自我欺骗。GPS 信号在室内衰减极其严重,混凝土墙体基本能把信号吃干净。如果模块输出正常、但一直定位失败,先别怀疑模块,把天线移到窗边或者户外再试。很多“无法定位”的场景,其实就是测试环境不行。我见过很多新手把模块放在工位上,非要它定位成功才肯继续,浪费了半天时间。
第二个坑:模块和电脑必须共地。串口信号是以 GND 为基准的,如果模块 GND 和 USB-TTL 的 GND 没有连起来,看到的要不就是乱码,要不就是完全没有数据。不少金属外壳的转接板会让用户误以为已经通过外壳或者其他路径接地,但实际上没有。这是我的实际教训,曾经在现场因为这个问题浪费了一小时。
第三个坑:改配置之后一定要保存到 Flash。前文反复强调过,u-blox 模块的配置是“易失 + 非易失”双份体系。在 u-center 里改了参数,默认只在 RAM 里生效,掉电就没了。如果你想让配置持久化,必须执行一次保存命令,或者在配置窗口勾选 Save on shutdown。我自己的项目里,就出现过改完配置、测试正常、然后重新上电又打回原形,最后才发现是保存没有做。
第四个坑:有源天线供电的电压真的随板子不同而不同。有的模块 V_ANT 是 3.3V 分出来的,有的是 5V 直通,有的甚至需要你外接电源。买模块之前,先看原理图,搞清楚天线供电方式。我曾经把 5V 的天线接到 3.3V 的 V_ANT 上,虽然没烧,但信号一直很差,最后查资料才发现供电电压不对。电压过高烧 LNA 的例子也不是没有。
5.3 如果所有常规步骤都排除了,还不行怎么办
如果供电、天线、接线、配置、冷启动都折腾过了,模块依然只输出$GxTXT,那问题可能出在固件或硬件本身。这时候可以尝试:
- 用 u-center 的固件升级功能重刷模块固件,先备份当前固件,再确认固件版本匹配。
- 换一块同型号的良品模块做交叉验证,如果替换后一切正常,那基本可以认定原模块有硬件问题。
- 检查模块底部焊盘是否有虚焊、连锡,特别是 RF_IN 附近和 VCC 引脚。有时候看起来一切正常,其实是 PCB 焊点出了问题。
- 检查有没有东西挡住了天线附近,比如金属支架、大块散热片,这类遮挡对 GPS 信号影响非常大。
固件刷写属于有一定风险的操作。在刷写前,记得退出所有占用串口的程序,关闭电脑上的蓝牙和一些 GPS 辅助软件,防止刷写过程中串口被抢走导致模块变砖。另外,刷写期间不要断电,一次失败就很可能要返厂。
说实话,排除定位故障这种活,很多时候不是靠高深技术,而是靠细致的排查顺序和好用的工具。我最深的体会是:一上来就怀疑“信号不好”是最容易走弯路的方向。GPS 模块这类器件,出问题时“供电”和“配置”的概率比“天线信号”高得多。如果遇到只输出$GxTXT的情况,我建议按这个顺序走:先看供电和接线,再看输出协议和波特率,最后才轮到天线和信号环境。多数问题会在前三步里就露出真相。另外一个实用小技巧:调试时不要只开着串口助手发呆,同时开着 u-center 看“星座图”和“定位状态”,模块是收到了卫星但算不出位置,还是压根没启动,一眼就能分辨。希望这篇记录能帮你少走一些弯路。