1. 从一根网线说起:AGV通信为什么不能只靠"够用就行"
我最早调试AGV的时候,踩过一个大坑:车跑起来了,但调度系统隔三差五丢状态,地图下发经常中断,以为是程序逻辑问题,查了半天发现根源是Wi-Fi信号不稳,更准确地说,是压根没给小车设计一套合格的通信架构。
那时我用的方案很朴素——AGV上挂一个Wi-Fi模块,路由器放产线角落,调度服务跑在PC上,车端和PC端之间用TCP长连接发指令。结果一跑起来状况百出:小车经过金属货架区就断连,调度员在电脑前干瞪眼,AGV停在过道里等恢复。后来我翻了日志,发现断线重连逻辑写得又简陋,对端异常退出根本没处理,恢复时间长达几十秒,这在真实产线上是不可接受的。
所以做AGV通信,第一步不是选模块,而是把"通信链路"当成系统设计的一部分。当前主流的AGV/智能小车通信,已经从单链路走向多链路融合:Wi-Fi负责大带宽、大范围的数据交互,蓝牙承担近场调试和外围设备连接,MQTT负责跨系统、跨设备的消息流转。三种方式各有分工,互相补位,这套架构做扎实了,AGV才是真的"耳聪目明"。
这篇文章,我会把AGV通信架构拆开讲透,先说为什么要拆分工,再逐个讲Wi-Fi、蓝牙、MQTT在实战中的选型、配置、踩坑和联动方案。整篇内容都基于我在实际项目里的经验,适合正在做智能小车、AGV调度、物流机器人项目,或者打算从单片机小车转向完整系统设计的开发者。你不需要一开始就懂很深,但看完之后,应该能对自己的通信方案有个全盘规划。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Wi-Fi链路:AGV的主干道,但别拿它当"万能药"
2.1 AGV对Wi-Fi的需求,和手机上网完全不是一回事
很多人觉得Wi-Fi嘛,连上能用就行,但AGV场景对Wi-Fi的要求完全不同。手机刷视频断几秒无所谓,AGV在自动运行中如果网络抖动超过几百毫秒,要么急停,要么撞人撞货,丢包率高一点,调度体验就会非常糟糕。
AGV对Wi-Fi的核心诉求有三个:低延迟、零漫游断连、多设备并发稳定。低延迟好理解,几百毫秒的响应时间差在几百公斤的AGV身上就是几十厘米的位移;零漫游断连这个很多人忽略,产线几百米的范围不可能靠一个AP覆盖,AGV从一个AP覆盖区走到另一个AP覆盖区,如果漫游切换过程中连接断了,TCP连接重建的代价非常大;多设备并发更不用说了,几十台AGV同时在线,每台车每秒上报状态、接收指令,这跟几十个人同时连Wi-Fi刷视频是两码事。
所以选型时,我建议优先用支持802.11k/v/r快速漫游协议的工业级AP,不要用家用路由器。家用路由器不是不能用,但它的漫游策略是为移动设备优化的,切换AP时往往需要重新认证,重连延迟动辄几百毫秒到秒级。工业AP配合AC控制器,可以把漫游切换时间压缩到50毫秒以内,这个差距在AGV调度里是致命的。
2.2 工控机上的Wi-Fi配置:Ubuntu服务器不连网,是真的头大
AGV车载控制器用Ubuntu系统的比例很高,而Ubuntu服务器版本默认不带桌面,网络配置全靠命令行,经常有人卡在这里。我见过最典型的场景是:工控机装了Ubuntu Server,插上无线网卡,然后发现自己完全不知道怎么配Wi-Fi。
这里我分享一套在无桌面环境下稳定的Wi-Fi配置方法,以Ubuntu 20.04+NetworkManager为例(现在新版本也兼容):
先确认无线网卡被识别:
bash复制ip link show
找到wlan0这样的无线接口。如果找不到,优先查驱动,最常见的坑是网卡需要安装闭源驱动,比如Intel AX210在旧内核下需要手动装固件,Realtek网卡也常有类似问题。然后再看NetworkManager是否接管了它:
bash复制nmcli device status
接着用nmcli连接Wi-Fi:
bash复制nmcli device wifi connect "你的SSID" password "你的密码"
如果你希望AGV每到一个位置都自动重连这个网络,可以设置autoconnect:
bash复制nmcli connection modify "你的SSID" connection.autoconnect yes
但这里有一个重要的坑:AGV车载端不要用DHCP自动获取IP。AGV的调度系统、上位机、底层控制器之间通常有固定IP规划,一旦网络里IP漂移,整个调度关系就乱了。建议给AGV分配静态IP,可以参考这样配置:
bash复制nmcli connection modify "你的SSID" ipv4.method manual \
ipv4.addresses 192.168.1.101/24 \
ipv4.gateway 192.168.1.1 \
ipv4.dns 114.114.114.114
然后重启网络:
bash复制sudo systemctl restart NetworkManager
提示:如果你是用NetworkManager管理的连接,不要去直接编辑/etc/network/interfaces,两套体系冲突会让网卡起不来。很多刚从桌面版转过来的人容易在这里踩坑。
2.3 漫游和干扰:AGV走到墙角就不动了,别再只会重启路由器
Wi-Fi装好只是第一步,AGV在真实场景里最折磨人的是信号盲区和干扰。
盲区:AGV走得很慢,穿行货架、金属柜体、升降门时信号衰减非常快,金属货架对2.4GHz信号的反射和吸收都很严重。我建议做项目时不要凭感觉布AP,先做一轮现场的Wi-Fi信号热力图扫描,用带测绘功能的手持设备或笔记本装个Wi-Fi分析工具,沿着AGV运行路径逐点测信号强度和丢包率。
布点的时候还要注意:AP尽量不要和AGV的天线在同一水平面安装。AGV天线通常在车体顶部,如果把AP也挂在AGV一样高度,很容易被货架和人遮挡;实际项目中,AP吊装到3米以上高度、天线方向朝下45度左右,覆盖效果好很多。
干扰:产线上2.4GHz设备极多——无线鼠标、蓝牙耳机、甚至微波炉。AGV这种对实时性要求高的场景,强烈建议用5GHz频段。5GHz的穿透能力弱一些,但频段干净、抗干扰能力强。设置AP时可以把支持5GHz的SSID单独分出来,AGV只连5GHz,其他终端连2.4GHz,避免挤在一起。
还有一个容易忽略的点——漫游阈值。AGV用的Wi-Fi网卡驱动默认的漫游触发电平可能比较保守(比如信号低于-75dBm才开始找下一个AP),但在工业现场,-65dBm以下就该切了。可以在网卡配置里调低漫游触发阈值(roam_threshold),或者直接在AP侧开启802.11r快速漫游机制,让系统更快判断切换时机。
实测经验:我有一台AGV在老厂房跑,卡车经过某个位置必掉线,后来现场勘查发现那个位置正好顶上有个钢结构横梁,把AP信号挡得死死的。后来我把AP从横梁另一侧挪开了两米,问题彻底消失。这个案例想说的是:Wi-Fi调优很多时候不是改参数,而是先肉眼判断一下物理遮挡。
2.4 AGV调度系统和Wi-Fi的耦合:网络抖动时,调度逻辑要兜底
通信再好,也不能保证网络永远不抖。真正健壮的AGV系统,必须把"网络会断"这个前提写进调度逻辑里。
我给AGV调度系统画过一条底线:网络断开是常态,恢复连接是期望。为此我做了几个兜底策略:
- AGV端和调度端之间维护心跳,心跳超时时间设在1.5到2秒之间,超过就进入"降级模式"。
- 降级模式下,AGV先按最后收到的任务指令继续低速行驶到安全停靠点,然后原地等待,不盲目执行新任务。
- 调度端检测到某台AGV心跳超时后,自动把该AGV标记为"失联",并从当前任务队列中摘除,停止给该车下发新任务,同时防止其他AGV规划路径时与失联车线路冲突。
- 网络恢复后,AGV主动上报当前位姿和状态,调度端重新确认任务状态,再决定是继续执行还是重新规划。
这套策略不复杂,但能避免大量"网络抖一下,车就乱跑"的事故。做AGV,通信设计一定要和调度逻辑一起做,不能等网络出问题再补。
3. 蓝牙链路:被低估的近场通道,调试和维修的救星
3.1 蓝牙在AGV里到底干吗用?不是拿来玩遥控的
Wi-Fi已经能把AGV接入系统了,那蓝牙还有必要吗?有,而且很多场景离了蓝牙真不行。
蓝牙在AGV里的定位,我总结为三个:近场调试接口、外围从站连接、应急维护通道。
近场调试接口:AGV调试时最烦的是什么?车体力跑起来了,但你没法插网线看日志。Wi-Fi确实可以远程,但如果是Wi-Fi本身的问题呢?这时候蓝牙串口模块(如HC-05、HC-06)就是救命通道——你可以拿着手机或笔记本,贴着车体连蓝牙串口,看启动日志、校准参数、手动运动控制,不等Wi-Fi恢复就能排查问题。很多AGV出厂时,调试接口就是通过蓝牙串口暴露的,一台笔记本在现场配对,想改参数秒秒钟的事。
外围从站连接:AGV上很多外围设备——条码扫描枪、RFID读卡器、IO手持控制器、称重传感器——它们大多不支持Wi-Fi,但蓝牙串口/经典蓝牙是标配。比如AGV扫描货架条码时,条码枪和车载主机之间走蓝牙串口,距离短、抗干扰、延迟低,比Wi-Fi可靠得多。
应急维护通道:AGV在运行中出故障,调度系统又连不上的情况下,工程师拿一个蓝牙手柄或手机APP,靠近车体就能把车拖回检修点。这条通道不需要任何网络基础设施,是独立于Wi-Fi的保底手段。
3.2 CSR8510 A10蓝牙适配器:Ubuntu下装驱动,一次搞通
做AGV用的工控机,蓝牙模块最常出问题的就是USB蓝牙适配器,尤其是CSR8510 A10这颗芯片,几乎人手一个,但它在Ubuntu下的体验可以说是折磨。
你插上去之后,lsusb能看到:
bash复制Bus 002 Device 005: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
但它不会自动变成可用的蓝牙设备。很多人卡在这一步就开始疯狂查hciconfig,发现没有hci0设备,于是怀疑是驱动问题。
核心原因在于:CSR8510 A10需要先确认固件下载正常,同时确保系统里装了bluez协议栈。驱动方面,Linux内核自带的btusb模块理论上支持CSR芯片,但需要固件文件/lib/firmware/ath3k-1.fw或者是CSR的iop文件,缺少就会导致不能正常工作。
解决的路径是这样的:
先装bluez全家桶:
bash复制sudo apt update
sudo apt install bluez bluez-tools blueman
再检查内核模块是否加载:
bash复制lsmod | grep btusb
如果没有,手动加载:
bash复制sudo modprobe btusb
然后启动蓝牙服务:
bash复制sudo systemctl enable bluetooth
sudo systemctl start bluetooth
sudo hciconfig hci0 up
到这里,大部分CSR8510 A10可以正常工作了。如果还不行,大概率是固件问题,可以在/lib/firmware目录下找找有没有rtl_bt之类的目录,再尝试把固件放到/lib/firmware/brcm/。
提示:CSR8510 A10在很多工控机上供电不稳,建议插在机箱后置USB口,不要插前置USB延长线,否则会出现"一会能用一会不能用"的诡异故障。
3.3 HC-05蓝牙模块连不上?先在代码外找原因
HC-05是STM32、Arduino开发中最常见的蓝牙串口模块。做智能小车和AGV底层的时候,几乎每个人都连过HC-05,但"连不上"这个问题,99%不是程序问题,而是硬件/配置问题。
最经典的场景是:手机蓝牙搜索到HC-05了,但配对一直失败,或者配对成功但串口收发没有反应。我的排查顺序是这样的:
第一步:确认模块处于AT命令配置模式还是数据透传模式。HC-05上电时,按住模块上的按键再上电,会进入AT模式(状态灯慢闪,约2秒一次);正常数据模式状态灯快闪(约0.5秒一次)。很多人模块上电就以为是在AT模式,结果发AT指令没响应,以为模块坏了。
第二步:确认串口电平。HC-05是3.3V TTL电平,直接接5V单片机的TX/RX会有电平风险。好的做法是用逻辑电平转换板,或者确认你的STM32板子IO口是3.3V逻辑。如果接错了板子,会出现"能搜到设备但连接后收不到数据"的情况。
第三步:确认蓝牙串口参数。HC-05默认波特率是9600(有些版本是38400),数据位8、停止位1、无校验,必须和单片机侧的串口配置完全一致。很多人Arduino串口监视器选对了波特率,但忘了检查Newline还是No line ending,发数据方式不对,模块自然没反应。
第四步:配对码。HC-05默认配对码是1234,很多Android手机会弹窗让你输,输错一次后系统会缓存错误的配对结果,即使你后来输对了也不行,需要在手机蓝牙设置里"取消保存"该设备再重新配对。
第五步:检查天线距离和干扰。HC-05是经典蓝牙,2.4GHz,和Wi-Fi共用频段,如果你把HC-05和ESP8266、手机Wi-Fi放得很近,实验台上干扰会很强,把蓝牙放在离金属件、电机驱动线远一点的位置,问题会少很多。
蓝牙地址也是排查时要关注的。12位蓝牙地址(如00:13:01:00:00:01)前6位是厂商号,HC-05的厂商段一般是00:13:01,当你在设备列表里看到这样的地址,基本可以确认是常见的CSR/ISSC方案的模块。如果搜到一堆同名蓝牙设备,你可以通过地址区分哪一只是你的。
3.4 蓝牙在Android和Windows端的坑:不是硬件能解决的事
做AGV调试工具时,Android手机或工控机Windows端连接蓝牙也是最常见的入口。这里有两个高频坑都想提醒一下。
Android 14及以上禁用经典蓝牙OPP文件传输:如果你在Android端做AGV配置工具,需要传输文件或者做蓝牙串口通信,注意高版本Android在权限管理上越来越严格,尤其是经典蓝牙的OPP profile被禁用,很多老App直接废了。解决方案是尽量用BLE(低功耗蓝牙)重写通信协议,或者用厂商提供的SDK转发文件。不要硬扛,Google这条路已经堵死了。
Windows笔记本上没有蓝牙设置项:很多Dell、ThinkPad笔记本在系统设置里找不到蓝牙,不一定是硬件坏了,大概率是蓝牙驱动被禁用或者BIOS里被关了。先在设备管理器里看是否有蓝牙设备;如果没有,去BIOS里确认Wireless里的Bluetooth选项是Enable;如果设备前有黄色感叹号,卸载设备后重启,让Windows重新扫描驱动。
蓝牙在AGV项目里是辅助定位,但辅助定位不代表可以轻敌。一个靠谱的近场调试通道,能让你少跑无数趟现场。
4. MQTT:让AGV从"单机小车"升级为"系统节点"的关键
4.1 MQTT为什么能成为AGV通信的中间层?
Wi-Fi给了通道,蓝牙给了近场入口,但AGV要融入整个工厂/仓储系统,还缺一个"语言"——这就是MQTT的价值。
简单理解MQTT的定位:它是基于TCP协议的轻量级消息发布/订阅协议。相比你直接写Socket、写自定义TCP协议,MQTT最大的优势是解耦和标准化。
举个例子:AGV调度系统要获取AGV的状态,如果走自定义TCP,你需要为每台AGV建立连接、处理粘包拆包、维护消息顺序、处理断线重连。但用MQTT,AGV作为客户端,把状态消息发布到一个Topic上,调度系统订阅这个Topic,就能收到所有AGV的状态。多了一台AGV?无所谓,只要它订阅/发布到对应的Topic就行。这就是"发布/订阅"模型的价值:生产者和消费者互不关心对方是谁、在哪里、有多少个,只关心消息本身。
另一个关键点是遗嘱消息(Last Will and Testament, LWT)。这个特性几乎是给AGV场景量身定做的:AGV正常下线时,会发一条遗嘱里的"离线"消息;但如果AGV断电、宕机、网络断开,MQTT broker会代替这台AGV,自动广播它预设好的遗嘱消息,调度系统立刻就能感知"这台车失联了",从而启动兜底逻辑。这在自定义TCP协议里,你得自己写心跳超时和状态管理,很容易出漏洞。
4.2 MQTT Broker选型:EMQX还是自建?我从开发到生产都试过
做AGV项目时,MQTT Broker(消息服务器)怎么选,我算是花了不少时间比较。
开发阶段:本地起一个EMQX,或者直接用Docker起个Mosquitto,先跑通消息流,验证协议和Topic设计。Mosquitto轻量、够用,但它的Web管理界面不友好,功能也有限。EMQX有Dashboard,Web页面可以直接看连接数、消息数、Topic列表,调试体验好非常多,所以我的建议是开发阶段直接用EMQX。
生产环境:如果你在产线上跑几十台AGV,消息量并不算大——每台AGV每秒上报几条状态,即使一百台车,也才几百TPS,EMQX一台普通服务器跑绰绰有余。但要注意,生产级Broker不是只扛TPS,还需要有:集群能力、消息持久化、认证鉴权、监控告警、TLS加密。EMQX社区版就支持大部分,但如果你要更严格的权限控制(比如每台AGV只能发布/订阅自己的Topic),建议用企业版或者自研权限插件。
我在CentOS上部署EMQX的一键傻瓜流程是这样的:
bash复制# 添加EMQX官方源(以CentOS 7/8为例)
curl -s https://packages.emqx.net/emqx-ce/v5.0/centos/7/emqx-ce.repo | sudo tee /etc/yum.repos.d/emqx-ce.repo
# 安装
sudo yum install -y emqx
# 启动服务
sudo systemctl start emqx
sudo systemctl enable emqx
启动后,访问http://服务器IP:18083,用默认账号admin/public进入Dashboard,然后创建专用账号、建立Topic权限,基本就齐活了。
提示:生产环境一定要启用认证,不要用默认账号对外开放。我见过有厂商的MQTT broker直接用admin/public裸奔,结果产线小车状态被外部扫描到,数据安全风险非常大。
4.3 AGV的MQTT消息怎么设计:Topic命名和Payload结构
Topic设计是MQTT接入AGV系统最核心的环节,设计得好,后面加车、加功能都轻松;设计得差,后面想改Topic结构,所有客户端都要动。
下面是我在项目里用的一套Topic设计参考:
agv/{device_id}/status:AGV实时状态(位姿、电量、速度、当前任务ID)。用Retained保留消息,调度系统随时能拿到每台车的最新状态。agv/{device_id}/heartbeat:心跳消息,周期1秒。agv/{device_id}/cmd:调度系统向AGV下发任务指令。AGV订阅这个Topic。agv/{device_id}/report:AGV上报任务执行结果、异常事件、日志。agv/telemtry:聚合遥测,适合调试和可视化展示。factory/agv/online:AGV上线/下线通知,用遗嘱消息配合。
Payload我建议统一用JSON,不要用自定义二进制格式。二进制省那几十个字节,带来的解析成本和跨系统协作成本远高于收益。一个典型的AGV状态消息长这样:
json复制{
"device_id": "AGV-001",
"timestamp": 1697123456789,
"x": 12.35,
"y": 45.21,
"theta": 1.5708,
"battery": 87.5,
"speed": 0.5,
"status": "running",
"task_id": "TASK-88321",
"error_code": 0
}
这个JSON消息每秒从AGV发布一次到agv/AGV-001/status。调度系统订阅agv/+/status通配符,就能拿到所有AGV的状态。当你新接入一台AGV时,只要按同一套规范发布消息,调度系统自动识别,这就是MQTT的扩展性。
4.4 QoS、遗嘱和保留消息:三个你必须搞懂的特性
MQTT从协议层面给了三个很关键的能力,AGV场景必须搞明白。
QoS(服务质量):MQTT的QoS 0、1、2三档。在AGV场景,状态上报这类消息用QoS 0就行,丢了可以靠下一帧状态补上,重发反而造成延迟和堆积;任务下发这类关键指令,建议用QoS 1,保证至少送达一次,但注意要配合消息去重(同一任务ID只执行一次);QoS 2能严格保证不重复,延迟更高,正常情况下AGV调度用不上,只有在"资金交易级"的数据里才需要。
遗嘱消息(LWT):前面提过,这是MQTT对AGV场景最有价值的能力。配置遗嘱消息时要注意:遗嘱消息的Topic和Payload一定要提前约定好,而且不能和正常状态消息的主键冲突。建议遗嘱消息单独一个Topic路径,比如agv/AGV-001/lwt,内容是一个{"device_id":"AGV-001","online":false,"offline_reason":"abnormal"}的JSON。这样调度系统订阅了agv/+/lwt,一旦有车失联,立即触发路径重规划和紧急响应。
保留消息(Retained):如果AGV状态消息设置了Retained,新的调度系统节点启动时,不用等待AGV下一轮心跳,就能立刻拿到每台车的最新状态。这个在系统重启、热切换节点时特别有用,否则调度系统重启之后要等1秒心跳才能恢复全局视图,中间这段时间就是盲区。
4.5 从ESP8266到STM32:设备端MQTT接入的实战思路
很多做智能小车的人是从ESP8266入门的,ESP8266用MQTT连阿里云物联网平台的教程满天飞,但到了STM32,问题就来了:STM32怎么跑MQTT?
我的建议是不要直接在STM32上跑完整的MQTT协议栈。STM32F103ZET6的RAM和Flash虽然能放下开源MQTT客户端库(比如paho-embedded-c),但写起来复杂、调试痛苦,而且STM32本身要干电机控制、传感器采集这些实时性很高的活,再塞一个MQTT客户端,调度问题会让你头大。
更好的做法是分层设计:STM32负责底层运动控制和数据采集,通过串口和上层通信板(树莓派/ESP32/工控机)对接;上层板卡跑Linux或RTOS,用市面上的MQTT库接入系统。我在一个项目中就是这么干的:STM32F103ZET6做底层控制,树莓派Zero 2W做通信中间层,树莓派上跑一个Python脚本,通过串口接收STM32发来的状态帧,转换后再通过MQTT发布到调度系统;同时订阅调度系统的任务指令,解析后通过串口发给STM32执行。这套架构的好处是:底层控制不受网络波动影响,即使MQTT断了,STM32这边还可以继续执行预定义的本地任务,车不会因网络问题马上停摆。
5. 三种通信的协同:用"通信优先级矩阵"守住AGV的安全底线
5.1 一张表说清Wi-Fi、蓝牙、MQTT的分工与取舍
我说了这么多,最终要落脚到协同设计上。很多AGV项目失败,不是技术选项少,而是没有搞清楚每一种通信方式的最佳分工。
| 通信方式 | 主要职责 | 数据量 | 延迟 | 距离 | 优点 | 缺点 |
|---|---|---|---|---|---|---|
| Wi-Fi | 车载主链路:地图下发、调度指令、多车协同、日志回传 | 大 | 低 | 50-100米 | 带宽大、覆盖好、延迟低 | 部署复杂、受干扰影响大 |
| 蓝牙 | 近场调试、外围设备连接、应急维护 | 小 | 低 | 5-15米 | 免布线、即插即用、不依赖基础设施 | 距离短、带宽低、设备多时信道拥挤 |
| MQTT | 跨系统消息中间层:状态上报、任务分发、系统集成 | 小 | 中低 | 通过Wi-Fi/以太网 | 标准协议、解耦、可扩展性强 | 依赖broker稳定性、端到端延迟受中间链路影响 |
Wi-Fi是主干道,MQTT是配送规则,蓝牙是路边救援通道。三者不是替代关系,而是互补关系。
5.2 断网时AGV该怎么办:一套可落地的降级策略
通信协同的最终目标,是让AGV在复杂网络环境下仍然安全。这里我分享一个在多个项目里验证过的"通信优先级矩阵",它的逻辑是:Wi-Fi为第一优先链路,MQTT是Wi-Fi之上的应用协议,蓝牙为手动应急通道,控制器底层永远保留安全急停能力。
具体执行策略可以这样设计:
- 正常状态:Wi-Fi+MULTI,AGV通过MQTT与调度系统交互,Wi-Fi承载全部自动运行数据流,蓝牙待机,只用于现场工程师主动连接调试。
- Wi-Fi断链,MQTT连着:这个情况说明Wi-Fi信号弱但TCP连接还没断,AGV立即降低车速,并尝试切换AP;如果3秒内恢复,继续执行任务;如果超时,就地等待并上报。
- Wi-Fi+MQTT全断:AGV按预设的"失联降级策略"自动行驶到安全停靠点,之后停车等待。这是底线动作——绝不让AGV在失联状态下继续执行交通管制敏感的路径规划。
- 现场救援:如果车停在过道里挡路,工程师用蓝牙直连车载系统,手动低速把车开到检修区。这个操作要求蓝牙调试通道在车辆失联时仍然有效,所以蓝牙模块的供电不要和主控共用一路电源,否则主控断电,蓝牙也没了。
这个矩阵的核心思想:通信层级越高,越容易出不可控故障;底层必须留一手手动硬能力。我在一个项目里看到过反面教材——调度系统挂了之后,AGV还在执行离线任务,结果因为路径规划失去全局视野,两台车在交叉口撞了。有了"失联即停车"的底线策略,这种事就不可能发生。
5.3 通信中间层的硬件选择:为什么我推荐树莓派/ESP32而不是STM32直连
讲完协同策略,再回到硬件选型。
做AGV通信中间层,市面上常见的方案有:STM32+外挂Wi-Fi模块直连MQTT、ESP32直连MQTT、树莓派/工控机做主控。
我的建议很明确:非必要,不要让STM32直接承担通信中间层职责。原因有几个:
- STM32的实时中断优先级很宝贵,给通信库分走一部分,电机控制、编码器读取的实时性必然受影响,做差了就是震动、丢步、堵转。
- 通信协议栈(MQTT+TLS)对RAM和Flash的要求不低,在STM32上做出来,代码臃肿,Bug排查困难。
- 调试时,树莓派/工控机上可以直接跑Wireshark、MQTT客户端、SSH,很多问题当场能定位;STM32上啥都没有,只能靠串口打印,效率天差地别。
当然,如果你做的是很小的桌面级智能车,成本敏感,ESP32这个级别的方案足够跑通。但一旦进入AGV级别——不论是一两百公斤的搬运车,还是几十公斤的工装小车——通信中间层和运动控制层物理隔离,是必须遵守的架构原则。
6. 实测排障:AGV通信问题排查复盘
6.1 Wi-Fi信号满格但丢包严重,怎么定位是AP还是车载端?
今年我在一个物流分拣中心做过一次现场排障,现象很典型:AGV状态上报延时抖动,调度大屏上几台车的轨迹时不时卡一下,但手机在同一个位置连Wi-Fi刷视频完全正常。
我按这个顺序排查:
- 排除AP覆盖问题:用便携式Wi-Fi分析仪沿AGV路线逐点测信号,结果都在-60dBm左右,信号本身不差。
- 排除信道干扰:现场所有AP固定在信道1/6/11,但产线新增了一批无线扫码枪,和AGV挤在2.4GHz频段。我用Wi-Fi分析仪扫描频谱,发现信道6附近噪声很低,但信道1拥塞严重,而车载网卡默认连的正好是信道1的AP。
- 定位是车载端还是AP端:把同一台AGV上的工控机放到办公室AP旁边,持续ping调度服务器,发现丢包率降为0——说明车载端硬件没问题。问题出在产线2.4GHz信道拥塞和AGV天线在车体内被金属舱盖遮挡。
- 解决方案:把AGV专用SSID强制切到5GHz信道,同时给AGV车顶加装外置天线,用SMA延长线引出。改完后,连续跑了72小时,ping丢包率从2%降到了0.1%以内。
这个案例最大的教训是:AGV车载无线信号不是"连上就好",天线位置、频段规划、现场干扰每一环都可能成为瓶颈。
6.2 MQTT消息偶尔丢,是Broker不行还是客户端不行?
另一个常见问题是:MQTT明明连上了,但调度系统偶尔收不到AGV的状态消息。排查思路如下:
先看Broker日志:EMQX Dashboard的消息统计里,查看PUBLISH消息速率和丢弃消息数量。如果丢弃量很大,通常是客户端发布频率超过Broker处理能力(这种情况很少见),或者有客户端订阅了#这种通配符Topic,导致Broker转发消息量暴增。
再看客户端侧:AGV端MQTT客户端是否启用了QoS 0?如果丢了,客户端不会重发,状态消息就只能等下一帧。如果你确实需要可靠性,可以临时把关键消息调到QoS 1,并配合消息去重。
最后看网络链路:MQTT消息是走TCP的,Wi-Fi网络抖动会导致TCP重传,但不至于丢消息。如果出现"MQTT客户端断线重连"日志,说明TCP在Wi-Fi中断断裂过,MQTT客户端重连后,之间那段时间的消息自然就丢了——这又回到了Wi-Fi链路本身的问题。
所以我的建议是:排查MQTT丢消息,先查链路,再查Broker,最后才怀疑客户端。90%的MQTT问题,根源都是底层网络,而不是MQTT本身。
6.3 蓝牙连不上,是因为Android缓存了旧配对信息
还有一次,AGV调试APP在Android手机上一直配对HC-05失败。我试了各种波特率、模式,都不行。最后发现是手机之前和另一只HC-05配对过,系统缓存了蓝牙地址和配对记录。新的HC-05虽然也是同名设备,但MAC地址不同,Android在自动配对时选中了旧设备,导致配对超时。解决办法很简单:在手机蓝牙设置里"取消保存"所有旧设备,关蓝牙重开,再重新扫描配对。
这个经历说明,在AGV调试工具的文档里,我后来都会专门加一行:"如果出现蓝牙搜索不到或配对失败,先清理手机蓝牙缓存"——这比让用户重刷模块固件省事一亿倍。
7. 最后分享几个通信调优的实战习惯
这篇文章写到这里,核心内容基本都覆盖了。最后再分享几个我长期养成的习惯,不一定是大道理,但对实操非常有用:
第一,给AGV预留独立的调试网口和调试串口,不要和通信链路共用。AGV如果只有一条Wi-Fi,Wi-Fi挂了,你连SSH都进不去,更别提修了。一定要在车上留一个有线网口和一个串口调试口,关键时刻插线直接进系统。
第二,通信模块的供电要独立可控。Wi-Fi模块、蓝牙模块的电源最好单独设计一个开关,或者用GPIO控制通断。为什么?因为通信模块死机了,你需要在远程能给它断电重启,否则出一次现场就要拆车。
第三,日志必须有时间戳和通信事件记录。AGV调试时,把Wi-Fi连接/断开、MQTT连接/断开、蓝牙配对/断开都写到系统日志里,并且打上单调时钟时间戳。出问题时,先看通信事件时间线,往往一眼就能定位是网络崩了还是程序崩了,能省至少一半的排查时间。
AGV通信不是"能通就行",它和运动控制一样,是系统级的设计问题。把Wi-Fi、蓝牙、MQTT放在一张架构图上一起考虑,按真实产线的可靠性要求去设计,你做的智能小车才不会只停留在演示级,而是真正能上线的工业级产品。
