Air780E+AT指令+EMQX:5分钟跑通MQTT双向通信实战
2026/9/17 18:45:27 网站建设 项目流程

Air780E模组用AT指令连EMQX服务器,5分钟跑通MQTT双向通信——这个说法放到实战里,一点不夸张。我在物联网项目里做过不少设备上云的活了,每次做原型验证,首选方案基本都是Air780E + AT指令 + EMQX,因为这套组合的调试速度实在太快。你不需要去啃MQTT协议栈源码,也不用烧录复杂的固件,只要有一块模组、一张SIM卡、一台能跑EMQX的机器,串口工具里敲几行命令,消息就从设备端飞到服务器了,再飞回来。这篇文章就给大家完整梳理这套流程,包含每一步AT指令的含义、EMQX的部署方法、完整可复制的脚本代码,以及我实际调试中踩过的几个坑。

文章的整体脉络我会按照“为什么这么选型 -> 环境怎么准备 -> AT指令怎么敲 -> 完整代码怎么抄 -> 坑怎么避”来推进。不管是刚接触4G模组的嵌入式新手,还是项目里急着联调的老手,按着这篇文章走一遍,基本能把链路跑通,后面再做功能开发就有底了。

1. 方案选型:为什么是Air780E、AT指令和MQTT

1.1 Air780E:便宜能打的Cat.1全网通模组

Air780E是合宙推出的一款基于紫光展锐8910平台的4G通信模组,支持Cat.1标准。Cat.1在物联网圈子里这几年的存在感很强,它的定位很有意思:比NB-IoT带宽大、时延低,比传统Cat.4模组便宜、功耗低,特别适合共享设备、定位追踪、充电桩、智能表计这类中速率、需要移动性又不追求极高带宽的场景。前几年很多2G设备被迫换代,Air780E就是这波切换里出货量非常可观的一款产品。

这块模组支持移动、联通、电信三网,也就是“全网通”,不用像早期2G模组那样去分运营商版本。硬件上封装选择多,核心板只要几十块钱,USB连上电脑就能当4G上网卡用,开发门槛真的低。我很多客户的项目,从拿到模组到打通第一条MQTT消息,基本一两个小时就能完成,这也是我习惯把它推给赶时间团队的原因。如果单纯想验证“设备上云”这件事,Air780E几乎是目前市面上成本最低、路线最短的方案之一。

1.2 AT指令方案和LuatOS/CSDK方案怎么选

Air780E的玩法大体分两种:一种是烧录LuatOS固件,用Lua或者C语言直接在模组内部跑业务逻辑,省掉外部MCU;另一种就是我一直推荐的AT指令方案,模组只负责“无脑联网”,所有业务逻辑放在外部单片机里,通过串口发AT指令来控制模组。

AT指令方案的优势非常明显。第一,MCU端零协议负担,不管是51、STM32还是国产MCU,只要能收发串口数据就行;第二,调试透明,每一行指令的返回都能直接看到,出了问题不用猜;第三,开发人员不需要懂4G协议栈,甚至不需要了解MQTT协议的具体报文格式。缺点也很直接:如果你的业务逻辑很重、对功耗要求极端,外部MCU和模组之间的串口通信会引入额外开销,这时候LuatOS方案会更优。

我的建议是:原型验证、中小规模项目、团队主力是写嵌入式C的,闭眼选AT指令;大规模低功耗设备、想省掉外部MCU的,再考虑LuatOS。这也是这篇文章把重点放在AT指令上的原因——它足够简单,足够快,也足够解决大多数实际问题。

1.3 数据链路:消息从设备到云端到底走了哪几步

动手之前,先把数据链路理清楚,后面排查问题全靠它。整条链路大概是这样的:外部MCU通过串口把AT指令发给Air780E,Air780E将这些指令转换成MQTT协议报文,通过4G网络发送到云端EMQX服务器,EMQX再将消息路由给订阅了同一个主题的客户端,比如MQTTX、微信小程序或者后台服务。

所以你会发现,这条链路里的主角其实有两个:Air780E负责“搬运”,EMQX负责“收转”。MCU、模组、服务器三者各司其职。你在串口工具里看到某条AT指令返回OK,并不代表消息已经到达服务器,只能说明模组接受了这条指令;真正的数据到达验证,要在EMQX的后台或者订阅端去看。这个认知很重要,否则后面排错会被“OK了但没收到消息”这种问题折磨到怀疑人生。

2. 环境准备:硬件接线和EMQX部署

2.1 硬件清单与串口接线的一个常见坑

开始之前,先准备以下东西:

  • Air780E核心板或模组开发板一块,带USB转串口的最省事
  • SIM卡一张,大小卡注意匹配,卡要能正常上网
  • 4G天线,别小看这东西,不接天线信号会差到让你怀疑是模组坏了
  • USB转TTL工具,如果核心板不带USB口就需要自己接
  • 杜邦线若干

接线方面,Air780E的主串口通常是用来做AT指令交互的。如果你用的是合宙官方的开发板,直接用USB线连接电脑就行,板载的USB转串口芯片已经帮你处理好了电平转换。如果是自己打板用模组,注意Air780E的IO电平是按3.3V设计的,外部MCU如果是5V的TTL电平,中间一定要加电平转换芯片,否则长时间运行容易烧模组IO。

串口参数我默认用115200,8位数据位、无校验、1位停止位,这是绝大多数合宙模组的默认设置。上电后串口助手应该能看到模组打印的开机日志,如果看不到,先检查USB转串口的驱动有没有装好,再检查是不是接错了TX/RX——这俩交叉接线是新手最容易犯的错误。记住:模组的TX接你USB转TTL工具的RX,模组的RX接工具的TX。

2.2 EMQX部署:Docker、Windows、云服务器三选一

EMQX是开源的高性能MQTT消息服务器,单台就能支撑海量设备连接。部署方式我推荐三种,按使用场景选就行。

第一种是本地Docker部署,最适合开发和演示。一条命令搞定:

docker run -d --name emqx -p 1883:1883 -p 18083:18083 --restart=always emqx/emqx:5.8

其中1883是MQTT普通协议端口,18083是Dashboard后台端口。容器跑起来之后,浏览器访问 http://localhost:18083 ,默认账号admin,密码public,进去就能看到设备在线状态。

第二种是直接安装在Windows电脑上,适合纯Windows环境的读者。去EMQX官网下载Windows安装包,解压后在命令行进到bin目录,执行 emqx start 就行。Dashboard端口同样是18083。

第三种是部署在云服务器上,适合设备需要在外网访问的场景。你需要在云服务器上放行1883端口和18083端口,注意云厂商的安全组和系统防火墙策略里都要加规则。我身边不止一个人栽在这一步:本地MQTTX能连EMQX,设备就是连不上,查半天发现是安全组没放行1883。这个事看起来基础,但确实是最常见的绊脚石。

2.3 创建MQTT账号并准备好连接参数

EMQX 5.x默认虽然允许匿名连接,但我强烈建议生产环境关掉匿名,用账号密码登录。这里我们创建一个测试账号:打开EMQX Dashboard,找到“访问控制”里的“客户端认证”,添加一个用户,比如用户名iot-test,密码123456。

然后整理一下后面要用的连接参数,最好记在文本里:

  • Broker地址:EMQX所在机器的IP,本地调试填127.0.0.1,云服务器填公网IP
  • 端口:1883
  • 客户端ID:每个设备要唯一,例如air780e_test_01
  • 用户名/密码:iot-test / 123456
  • 订阅主题:device/air780e/up
  • 发布主题:device/air780e/down

这里有个很重要的细节:客户端ID必须全局唯一。如果两台设备用了相同的ClientID,先连上的那台一定会被后连上的挤下线,而且这种互踢在MQTT协议里属于“正常行为”,不会报任何错误。我之前调试时明明设备在线,消息却总是不对,最后发现就是EMQX上的另一个测试客户端偷偷占用了同一个ClientID。

3. AT指令分步实战:从上电到双向通信

这一节我演示Air780E上很经典的一套MQTT指令流程。旧版合宙AT固件常用的是MCONFIG/MIPSTART/MQTTSTART/MQTTSUB/MQTTPUB这套前缀,新版固件有对应的标准AQM指令,比如MQTTCFG/MQTTOPEN。指令名会变,但底层逻辑顺序完全一致。如果你手头的固件指令对不上,先查一下当前固件版本对应的AT指令手册,再替换命令就行。

3.1 第一步:串口通信检查与关闭回显

把串口助手打开,波特率115200,给模组上电。第一步先发个最简单的AT,验证串口链路通不通:

AT OK

如果返回OK,说明MCU到模组的串口通路没问题。顺手再把回显关掉,省得后面指令和返回混在一起看不清:

ATE0 OK

有人可能会问:为什么一开始要关回显?因为MQTT交互的AT脚本命令比较多,开着回显的话,你发出去的每一行命令都会原样回显出来,再叠加各种+MQTT开头的结果码,串口工具里的日志会乱成一锅粥。关掉回显之后,输出就只有模组的主动上报和指令结果,排查问题会清爽很多。

3.2 第二步:确认SIM卡、信号和网络注册

接下来依次执行下面的命令,确保模组已经具备上网条件:

AT+CPIN? +CPIN: READY AT+CSQ +CSQ: 20,99 AT+CEREG? +CEREG: 0,1
  • AT+CPIN? 返回 +CPIN: READY,表示SIM卡已识别。返回ERROR则是卡没插好、卡坏或者卡座接触不良,先放下软件去检查硬件。
  • AT+CSQ 返回的是信号强度,第一个数字越大越好,一般大于10能稳定联网,99表示信号不可用,检查天线或者SIM卡。
  • AT+CEREG? 返回 +CEREG: 0,1,最后一位是网络注册状态,1表示已注册到本地网,5表示已注册但正在漫游,0和2是还在尝试,3表示被拒绝。这个命令值得多执行几次,因为模组上电后注册网络本身需要一定时间。

网络注册状态OK之后,还需要激活PDP上下文,相当于让模组申请一个动态IP。执行:

AT+CGACT=1,1 OK AT+CGPADDR=1 +CGPADDR: 1,"10.10.xx.xx"

拿到IP就说明模组的4G数据链路已经通了,下一步才真正进入MQTT主战场。这一步相当于“宽带装好了,拨号也成功了”,后面才能在网络上跑业务流量。

3.3 第三步:配置MQTT参数并建立连接

到这一步,模组已经能上网了,接下来把它接到EMQX上。首先配置MQTT客户端的基本参数:

AT+MCONFIG="air780e_test_01","iot-test","123456" OK

这条命令的作用是设置MQTT连接的ClientID、用户名和密码。为什么这里不直接连接而是先配置?因为MQTT在建立连接握手时,这三样参数就是身份凭证,EMQX要拿它们做认证;EMQX里配了对应的账号,这里才有权限放行。

然后是建立TCP链路,指定EMQX服务器的IP和端口:

AT+MIPSTART="120.xx.xx.xx",1883 OK

如果EMQX部署在云端,这里填公网IP;如果只是本机测试,也可以填局域网IP。返回OK只表示TCP连接建立成功,不代表MQTT层已经通过认证。真正进入MQTT协议层要执行:

AT+MQTTSTART OK

到这一步,EMQX的Dashboard“连接管理”页面里就能看到你的设备上线了。发完MQTTSTART后如果一直没反应或者返回ERROR,优先回到上一步检查TCP链路和服务器账号密码,别急着往下走。

3.4 第四步:订阅主题,打通下行通道

设备连上EMQX之后,要做的第一件事就是订阅和发布。订阅是所有物联网设备最基础的动作,先来订阅一个上行主题:

AT+MQTTSUB="device/air780e/up",0 OK

命令里的0是QoS等级。MQTT协议里QoS 0是最多一次,QoS 1是至少一次,QoS 2是恰好一次。对于采集上行数据这种允许偶尔丢一条的场景,用QoS 0完全够,还省流量;如果是不允许丢失的控制指令,建议至少用QoS 1。我一般默认写0,定期上报的场景完全没问题。

订阅成功后再用MQTTX这类客户端向这个主题发一条消息,串口助手应该能看到类似这样的主动上报:

+MQTTSUB: "device/air780e/up","hello from mqttx"

看到这条返回,说明“从云端到设备”的下行链路已经打通。这是整个调试过程中最有成就感的一瞬间——设备端和云端终于“互相看得见”了。

3.5 第五步:发布消息,打通上行通道

上行链路同样简单,执行:

AT+MQTTPUB="device/air780e/down","hello from air780e",0,0 OK +MQTTPUB: 0

其中引号里面是消息内容,第一个0是QoS,第二个0是retain标志,表示这条消息是否要由服务器保留给后订阅的客户端。业务上如果需要新设备一订阅就能拿到服务器最后的状态,retain填1很有用,比如上报设备当前开关状态;普通的临时消息填0即可。

发布指令执行后,模组会返回 +MQTTPUB: 0 表示消息发送成功。此时打开MQTTX,订阅同样的主题 device/air780e/down,就能看到设备发上来的消息。至此,设备端和服务器端的双向通信已经全部打通,前后也就五分钟的事。

这里再提醒一个真实处理经验:如果你的消息内容里带了逗号或者双引号,直接写在AT指令里可能会被解析错。比如要发布的内容是"temp,25",建议把消息体做一下URL编码或者改成JSON里不带逗号的写法,实在绕不开就查一下固件手册里对特殊字符的转义规则。这个问题在调试阶段不常见,一旦产品上线,各种带分隔符的数据出现频率会很高。

3.6 关于心跳、断开和重连的工程化处理

MQTT链路测试通过后,别急着把代码固化到产品里,还有一个重要问题:断线重连。Air780E的AT指令里,断开连接是:

AT+MQTTDISCON OK

日常开发中,网络环境没有那么理想,信号波动、服务器重启、IP地址变化都可能导致原有MQTT连接断开。模组断开后,串口会收到类似的主动上报:

+MQTTURC: 1

不同的固件上报格式不一样,处理逻辑是统一的:一旦收到这个上报,就重新执行一遍“配置参数 -> 建立TCP -> 启动MQTT -> 订阅主题”的完整流程。注意MQTT协议本身有keepalive机制,模组会在配置的保活时间内主动发心跳包,判断链路是否还通着,所以业务端一般不需要额外发心跳,关键是针对断线事件做好重连。

4. 完整可直接抄的脚本和代码

上一节是分步骤讲解,这一节直接给一份“抄作业版”的完整脚本和代码框架。我的建议是:先手工在串口助手里把每一步敲通,再做代码集成,这样排查问题时心里有数。

4.1 完整AT指令序列:5分钟跑通的核心

下面是一份经过精简的完整AT脚本,按顺序逐条发送,就能完成一次MQTT连接、订阅和发布。脚本里的IP、ClientID、用户名密码记得换成你自己的:

ATE0 AT+CPIN? AT+CSQ AT+CEREG? AT+CGACT=1,1 AT+MQTTCFG="air780e_test_01","iot-test","123456" AT+MQTTOPEN="120.xx.xx.xx",1883 AT+MQTTSUB="device/air780e/up",0 AT+MQTTPUB="device/air780e/down","hello from air780e",0,0

如果你当前固件不支持MQTTCFG/MQTTOPEN前缀,按照我第3节里的经典指令流程替换即可:AT+MCONFIG配置、AT+MIPSTART建TCP链路、AT+MQTTSTART启动MQTT。整个流程的逻辑骨架就是:确认网络就绪 -> 配置MQTT参数 -> 建立TCP -> 启动MQTT -> 订阅/发布。只要理解了这条主线,不管指令前缀怎么变,你都能快速上手。

4.2 单片机上运行AT指令的代码框架

实测中最常用的做法是单片机通过串口发送AT指令并解析返回值。这里给一个简化版的C语言发送框架,逻辑上可以套用在任意MCU上:

void uart_send_string(const char *str); // 串口发送函数 void uart_receive_irq_handle(void); // 串口接收中断处理 // 发送AT指令并等待预期返回值,timeout_ms为超时时间 uint8_t at_send_cmd(const char *cmd, const char *expect, uint32_t timeout_ms) { uart_send_string(cmd); uart_send_string("\r\n"); // 在循环中接收串口数据,将结果存入缓冲区 // 在timeout_ms时间内,如果缓冲区中匹配到expect字符串,返回1 // 超时未匹配,返回0 }

实际工程中,至少要做好三件事:一是发送指令后不要立刻发下一条,要等上一条返回OK;二是对模组的主动上报(比如+MQTTSUB开头的内容)做异步解析,不能只在同步发指令时才读串口,否则会丢掉服务器推送的消息;三是在主循环里增加一个状态机,把“上电 -> 注网 -> 连MQTT -> 在线运行 -> 断线重连”这几个状态管理起来,不要把所有AT指令堆在main函数里顺序执行。

4.3 用MQTTX做全链路验证

设备端脚本写完之后,别急着收工,我强烈建议用MQTTX这种图形化客户端做一次全链路验证。手机或者电脑装一个MQTTX,新建一个连接,填上EMQX的IP、端口和认证信息,然后订阅 device/air780e/up,向 device/air780e/down 发一条消息。

如果MQTTX能收到设备发来的消息,设备也能收到MQTTX下发的消息,那么恭喜,这条链路已经是“真通”了,不是只在AT指令层面返回OK。我习惯把MQTTX在前台一直开着,调试设备异常时,先看MQTTX能不能发能收,能的话问题就锁定在设备端,不能的话去查服务器和网络。这一个小习惯,能省掉一半的排查时间。

5. 问题速查:我实测中踩过的坑

这一节整理几个我自己实际调试中踩过、或者帮别人排过的典型问题,按“现象 -> 原因 -> 解决”列表出来,方便你直接按图索骥。

5.1 连接问题速查表

现象可能原因排查与解决方案
AT返回ERROR波特率不对、TX/RX接反检查串口参数;交叉换TX/RX
AT+CPIN?返回ERRORSIM卡未识别或卡座接触不良重插SIM卡、检查卡座弹片
+CSQ返回99,99没接天线、天线损坏、信号太差检查天线连接,移动到窗边信号好位置
+CEREG返回0,3SIM卡被停用、套餐停机、运营商不匹配换卡,确认卡能正常上网
MQTT连接失败防火墙/安全组未放行1883端口在云服务器安全组和系统防火墙放行1883
连接成功但收不到消息订阅主题与发布主题不一致检查topic是否大小写、层级完全一致
设备上线后频繁掉线信号弱导致TCP连接不稳定优化天线布局,必要时降低设备放置高度

这张表覆盖了80%的新手问题。我最常遇到的还是端口未放行,因为EMQX本地测试没问题,一搬到云服务器就出问题,排查思路立刻转向网络策略,基本一击即中。

5.2 掉线自动重连:产品上线前必须补上的逻辑

如果你只是做个demo,断线重连可以不做;但产品要跑起来,重连机制就是命根子。我见过太多设备在演示时异常掉线后一直傻等,最后只能断电重启。

最简单的做法是:在单片机里开一个定时任务,周期性发送一条轻量级AT指令(比如AT)查询模组是否还活着;一旦发现MQTT断线上报,或者长时间没有收到模组的任何返回,就调用完整的MQTT重连流程。重连流程要先执行AT+MQTTDISCON,确保上一次连接彻底关闭,再去重新执行AT+MCONFIG、AT+MIPSTART、AT+MQTTSTART、AT+MQTTSUB。这里有个细节:重连后必须重新订阅主题,因为订阅关系不会跨连接保留。

另外,不要做成“死循环式重连”。如果服务器长时间不可用,建议指数退避,第一次等5秒,第二次10秒,最长到5分钟,否则设备一直在最耗电的状态下空转,很快就把电池耗光了。

5.3 固件版本不同,指令别硬抄

Air780E的不同固件版本,AT指令集的差异是真实存在的。合宙官方早年的AT固件里,MQTT用的是MCONFIG/MIPSTART/MQTTSTART这套;后续新固件迭代后有些版本支持MQTTCFG/MQTTOPEN这套更标准的AQM指令,两者在功能上等价,但写法和返回值不完全一样。

所以拿到一块Air780E,第一步一定要查固件版本:执行 AT+CGMR 或者 ATI,把版本信息记下来,再对照官方AT指令手册里的MQTT部分确认指令写法。不要拿着别人文章里的指令直接复制,尤其是网上文章年代跨度大,很容易混入过时信息。我一开始也吃过这个亏,照着旧固件文档敲了半天,新固件全部返回ERROR,最后查版本号才发现问题。

我自己第一次调这块模组的时候,其实卡在了一个特别低级的问题上:EMQX在云服务器上跑着,本地MQTTX连得欢天喜地,Air780E死活连不上。排查了快两个小时,最终发现是云服务器的安全组没放行1883端口。从那以后我就养成了习惯,凡是涉及远程服务器,先把端口策略理一遍再动手。这个经验也说不上多高深,但真的很管用——分享给每一个准备入坑Air780E和MQTT的朋友。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询