MQTT
一、MQTT 介绍
MQTT 是一种低开销、低带宽占用的即时通讯协议,可以用极少的代码和带宽为远程设备提供实时可靠的消息服务。它适用于硬件性能低下的设备以及网络状况不佳的环境,因此在物联网(IoT)小型设备和移动应用等方面有广泛应用。
MQTT 采用发布/订阅通信模型,客户端可以发布消息到主题(Topic),也可以订阅主题来接收消息。这种模式解耦了消息的发送者和接收者。
MQTT 的消息传递质量分为三种:最多一次(QoS 0)不保证交付,至少一次(QoS 1)确保至少到达但可能重复,只有一次(QoS 2)确保仅到达一次。
二、演示功能概述
本 demo 通过使用 Air201模组,带你快速体验通过 MQTT 协议进行数据接收与发送。
三、准备硬件环境
3.1 Air201 模组
使用 Air201 模组,如下图所示:
点击链接购买:合宙Air201模组淘宝购买链接 ;
此模组的详细使用说明参考:Air201 产品手册 。
3.2 TYPE-C 数据线
四、准备软件环境
注:以下软件下载链接,请复制后,粘贴到浏览器 URL 地址栏进行下载;
4.1 MQTT.fx
4.2 Luatools
4.3 core 固件和源码脚本
注:core 固件,是基础环境,该固件由合宙官方提供,用户不可修改;源码脚本,为应用程序,可由客户自行修改;官网下载,底层 core 下载地址:LuatOS 底层 core 注:本 demo 使用如图所示固件
脚本链接:https://gitee.com/openLuat/LuatOS-Air201/tree/master/demo/socket/mqtt
五、软硬件资料
1、此模组的详细使用说明参考:Air201 产品手册
5.1 开发板按钮与指示灯图示与说明
5.2 硬件安装与连接
5.2.1 SIM 卡安装
通常,插入 SIM 卡的步骤如下:
- 将 SIM 卡的金属接触面朝下,对准卡槽的开口。
- 用力平稳地将 SIM 卡推入卡槽,直至推到最底端,表示 SIM 卡已正确安装到位。
5.2.2 实物连接图
注:开发板与电脑通过 TYPE-C 线连接,用于通信与供电,所以必须使用支持USB通信的TYPE-C数据线才可以;
六、代码示例介绍
6.1 DEMO 软件流程图
6.2 配置
6.2.1 MQTT 的 4 个重要配置
- local mqtt_host = "lbsmqtt.airm2m.com"(MQTT 服务器地址,这里使用合宙提供公用测试服务器)
- local mqtt_port = 1884(MQTT 端口)
- local user_name = "user"(MQTT 服务器登录用户名)
- local password = "password"(MQTT 服务器登录密码)
6.2.2 MQTT 的 2 个重要主题
- local pub_topic = "/luatos/pub/123"-- .. (mcu.unique_id():toHex())(设备发布主题,以下方源码 47 行,可自行修改)
- local sub_topic = "/luatos/sub/123"-- .. (mcu.unique_id():toHex())(设备订阅主题,以下方源码 48 行,可自行修改)
6.2 完整程序清单
注:完整复制后保存为 main.lua,可直接使用
-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = "mqttdemo"
VERSION = "1.0.0"
--[[
本demo需要mqtt库, 大部分能联网的设备都具有这个库
mqtt也是内置库, 无需require
]]
-- sys库是标配
_G.sys = require("sys")
--[[特别注意, 使用mqtt库需要下列语句]]
_G.sysplus = require("sysplus")
local netLed = require("netLed")
--根据自己的服务器修改以下参数
local mqtt_host = "lbsmqtt.airm2m.com"
local mqtt_port = 1884
local mqtt_isssl = false
local client_id = "mqttx_b55c41b7"
local user_name = "user"
local password = "password"
local pub_topic = "/luatos/pub/123"-- .. (mcu.unique_id():toHex())
local sub_topic = "/luatos/sub/123"-- .. (mcu.unique_id():toHex())
local mqttc = nil
local netLed = require("netLed")
--红色灯开机后长亮
local LEDA= gpio.setup(16, 1, gpio.PULLUP)
-- 统一联网函数
sys.taskInit(function()
local device_id = mcu.unique_id():toHex()
device_id = mobile.imei()
-- 默认都等到联网成功
sys.waitUntil("IP_READY")
sys.publish("net_ready", device_id)
end)
sys.taskInit(function()
-- 等待联网
local ret, device_id = sys.waitUntil("net_ready") --device_id为设备的IMEI号
client_id = device_id
pub_topic = device_id .. "/up" -- 设备发布的主题,开发者可自行修改
sub_topic = device_id .. "/down" -- 设备订阅的主题,开发者可自行修改
-- 打印一下上报(pub)和下发(sub)的topic名称
-- 上报: 设备 ---> 服务器
-- 下发: 设备 <--- 服务器
-- 可使用mqtt.x等客户端进行调试
log.info("mqtt", "pub", pub_topic)
log.info("mqtt", "sub", sub_topic)
-- 打印一下支持的加密套件, 通常来说, 固件已包含常见的99%的加密套件
-- if crypto.cipher_suites then
-- log.info("cipher", "suites", json.encode(crypto.cipher_suites()))
-- end
if mqtt == nil then
while 1 do
sys.wait(1000)
log.info("bsp", "本bsp未适配mqtt库, 请查证")
end
end
--配置上网指示灯
gpio.setup(1, 1, gpio.PULLUP) --配置为输出,带上拉
-------------------------------------
-------- MQTT 演示代码 --------------
-------------------------------------
mqttc = mqtt.create(nil, mqtt_host, mqtt_port, mqtt_isssl, ca_file)
mqttc:auth(client_id,user_name,password) -- client_id必填,其余选填
-- mqttc:keepalive(240) -- 默认值240s
mqttc:autoreconn(true, 3000) -- 自动重连机制
mqttc:on(function(mqtt_client, event, data, payload)
-- 用户自定义代码
log.info("mqtt", "event", event, mqtt_client, data, payload)
if event == "conack" then
-- 联上了
--gpio.set(1, 0) --输出低电平
sys.publish("mqtt_conack")
mqtt_client:subscribe(sub_topic)--单主题订阅
-- mqtt_client:subscribe({[topic1]=1,[topic2]=1,[topic3]=1})--多主题订阅
elseif event == "recv" then
log.info("mqtt", "downlink", "topic", data, "payload:", payload)
log.info("mqtt", "uplink", "topic", pub_topic, "payload:", payload)
sys.publish("mqtt_pub", pub_topic, payload) --将收到的数据,通过发布主题目,进行发送
elseif event == "sent" then
log.info("mqtt", "sent", "pkgid", data)
elseif event == "disconnect" then
--gpio.set(1, 1) --输出高电平
-- 非自动重连时,按需重启mqttc
-- mqtt_client:connect()
end
end)
-- mqttc自动处理重连, 除非自行关闭
mqttc:connect()
sys.waitUntil("mqtt_conack")
while true do
-- 演示等待其他task发送过来的上报信息
local ret, topic, data, qos = sys.waitUntil("mqtt_pub", 300000)
if ret then
-- 提供关闭本while循环的途径, 不需要可以注释掉
if topic == "close" then break end
mqttc:publish(topic, data, qos)
end
-- 如果没有其他task上报, 可以写个空等待
--sys.wait(6000)
end
mqttc:close()
mqttc = nil
end)
-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!
七、功能验证
7.1 开机
按图 1 所示通过 TYPE-C 线将开发板与电脑连接无误后,此时按下开机键,约 2 秒后释放,等待几秒指示灯常亮,即开机成功,如下图:
此时电脑设备管理器中会发现下图所示几个设备COMXX(每台电脑的端口会有所不同),即代表开机成功!
7.2 打开 Luatool 软件工具并进入项目管理测试页面
7.3 按序号步骤创建项目
7.4 按如下步骤进行程序烧录
Air201进入boot下载模式,烧录固件和程序,需要将预留的测试点(Air201板子 B面图) 的BOOT 上拉到vdd_ext(A面USB旁边),之后上电开机,即可进入下载模式,下载完程序后将boot脚悬空。
Air201板子 A面图
Air201板子 B面图
判断是否进入 BOOT 模式:模块上电,此时在电脑的设备管理器中,查看串口设备, 会出现一个端口表示进入了 BOOT 下载模式,如下图所示:
7.5 观察下载过程后确认烧录结果
下载中
下载成功
7.6 查看调试日志,获取设备发布与订阅主题
7.7 打开 MQTT 客户端 MQTT.fx 应用程序并配置
7.7.1 MQTT 客户端基本配置
ProfileName:合宙(可修改为你想要的名称)
BrokerAddress:http://lbsmqtt.airm2m.com (合宙提供的免费测试服务器,也可修改为自己的服务器)
BrokerPort:1884 (端口号)
UserName:user
Password:password
7.7.2 两个重要主题
设备发布主题:864536072621004/up (设备向服务器发送数据使用)
设备订阅主题:864536072621004/down (接收服务器数据主题)
7.8 订阅设备主题
7.9 MQTT 客户端给开发板发送数据
7.10 查 MQTT 客户端订阅的设备数据
总结
至此,我们已使用 Air201模组完成了 MQTT 通信的基本功能。