拷贝官方MQTT源码
修改main.lua
打开看门狗,网络指示灯功能
修改mqttTask.lua
本人服务器信息
IP地址: mnif.cn
端口号: TCP:1883 TCPS:8883
用户名: yang
密 码: 11223344
修改连接信息如下:
修改mqttInMsg.lua
修改为直接打印接收的数据,去掉hex转换
mqttOutMsg.lua 说明
1.连接上MQTT以后 mqttTask.lua调用了mqttOutMsg 里面的 mqttOutMsg.init() 函数
2.官方给的例子是每隔10S发布主题为 /qos0topic 消息为 qos0data 的消息
每隔20S发布主题为 /中文qos1topic 消息为 中文qos1data 的消息
测试
1.安装手机卡,安装天线,下载程序
2.打开我提供的调试助手
连接,订阅,设置发布的主题如下
发布的主题:111111 订阅的主题:/qos0topic
扩展:DTU
模块接收的MQTT信息转发到485/422输出
485/422接收的数据转发给MQTT发送
设备订阅的主题:user/设备的imei号码
设备发布的主题:device/设备的imei号码
1.修改 mqttTask 初始化串口;修改订阅的主题为:user/设备的imei号;把IMEI号传递给发布程序
代码语言:javascript复制--- 模块功能:MQTT客户端处理框架
-- @author openLuat
-- @module mqtt.mqttTask
-- @license MIT
-- @copyright openLuat
-- @release 2018.03.28
module(...,package.seeall)
require"misc"
require"mqtt"
require"mqttOutMsg"
require"mqttInMsg"
local ready = false
--- MQTT连接是否处于激活状态
-- @return 激活状态返回true,非激活状态返回false
-- @usage mqttTask.isReady()
function isReady()
return ready
end
uart.setup(1, 115200, 8, uart.PAR_NONE, uart.STOP_1)
--启动MQTT客户端任务
sys.taskInit(
function()
local retryConnectCnt = 0
while true do
if not socket.isReady() then
retryConnectCnt = 0
--等待网络环境准备就绪,超时时间是5分钟
sys.waitUntil("IP_READY_IND",300000)
end
if socket.isReady() then
local imei = misc.getImei()
--创建一个MQTT客户端
local mqttClient = mqtt.client(imei,30,"yang","11223344")
--阻塞执行MQTT CONNECT动作,直至成功
--如果使用ssl连接,打开mqttClient:connect("lbsmqtt.airm2m.com",1884,"tcp_ssl",{caCert="ca.crt"}),根据自己的需求配置
--mqttClient:connect("lbsmqtt.airm2m.com",1884,"tcp_ssl",{caCert="ca.crt"})
if mqttClient:connect("mnif.cn",1883,"tcp") then
retryConnectCnt = 0
ready = true
--订阅主题
if mqttClient:subscribe({["user/"..imei]=0}) then --订阅主题:
mqttOutMsg.init(imei)
--循环处理接收和发送的数据
while true do
if not mqttInMsg.proc(mqttClient) then log.error("mqttTask.mqttInMsg.proc error") break end
if not mqttOutMsg.proc(mqttClient) then log.error("mqttTask.mqttOutMsg proc error") break end
end
mqttOutMsg.unInit()
end
ready = false
else
retryConnectCnt = retryConnectCnt 1
end
--断开MQTT连接
mqttClient:disconnect()
if retryConnectCnt>=5 then link.shut() retryConnectCnt=0 end
sys.wait(5000)
else
--进入飞行模式,20秒之后,退出飞行模式
net.switchFly(true)
sys.wait(20000)
net.switchFly(false)
end
end
end
)
2.修改 mqttInMsg 接收的数据串口1输出
代码语言:javascript复制--- 模块功能:MQTT客户端数据接收处理
-- @author openLuat
-- @module mqtt.mqttInMsg
-- @license MIT
-- @copyright openLuat
-- @release 2018.03.28
module(...,package.seeall)
--- MQTT客户端数据接收处理
-- @param mqttClient,MQTT客户端对象
-- @return 处理成功返回true,处理出错返回false
-- @usage mqttInMsg.proc(mqttClient)
function proc(mqttClient)
local result,data
while true do
result,data = mqttClient:receive(2000)
--接收到数据
if result then
log.info("mqttInMsg.proc",data.topic,data.payload)
--TODO:根据需求自行处理data.payload
uart.write(1, data.payload) --串口输出接收的数据
--如果mqttOutMsg中有等待发送的数据,则立即退出本循环
if mqttOutMsg.waitForSend() then return true end
else
break
end
end
return result or data=="timeout"
end
3.大幅度裁剪 mqttOutMsg 串口接收的数据,转发给MQTT发送
代码语言:javascript复制--- 模块功能:MQTT客户端数据发送处理
module(...,package.seeall)
-- 串口ID,串口读缓冲区
local sendQueue = {} --接收数据缓存
local uartimeout=25 -- 串口接收超时时间
local recvReady = "UART_RECV_ID" --串口准备好后发布的消息
local myimei="";
-- MQTT
local msgQueue = {} --数据发送的消息队列
function init(imei)
myimei = imei; --获取IMEI
end
--- 清空对象存储
function unInit()
while #msgQueue>0 do
local outMsg = table.remove(msgQueue,1)
end
end
--- MQTT客户端是否有数据等待发送
-- @return 有数据等待发送返回true,否则返回false
-- @usage mqttOutMsg.waitForSend()
function waitForSend()
return #msgQueue > 0
end
--- MQTT客户端数据发送处理
-- @param mqttClient,MQTT客户端对象
-- @return 处理成功返回true,处理出错返回false
-- @usage mqttOutMsg.proc(mqttClient)
function proc(mqttClient,imei)
while #msgQueue>0 do--有消息
local outMsg = table.remove(msgQueue,1)--提取一条消息
local result = mqttClient:publish(outMsg.t,outMsg.p,outMsg.q)--发送
if not result then return end--发送失败返回空
end
return true
end
-- 串口
uart.on(1, "receive", function(uid)
table.insert(sendQueue, uart.read(uid, 1460))
sys.timerStart(sys.publish, uartimeout, recvReady)
end)
sys.subscribe(recvReady, function()
local str = table.concat(sendQueue) --把每一条数据拼接成一条数据
table.insert(msgQueue,{t="device/"..myimei,p=str,q=0})--串口接收的消息,插入MQTT发送缓存
sendQueue = {} -- 串口的数据读完后清空缓冲区
end)
扩展1:DTU 测试
1.下载本节程序
2.接上485/422模块
A ,A- 作为485通信时的接收和发送数据接口,另作为422通信时的发送数据接口
B ,B- 作为422通信时的接收数据接口
用485模块连接如下:
3.打开MQTT调试助手
提示:设备的IMEI可看自己模块上的
订阅的主题: device/设备的imei号
发布的主题: user/设备的imei号
4.MQTT助手发布消息