GPRS(Air202) Lua开发: 物联网MQTT ,DTU
拷贝官方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号传递给发布程序
--- 模块功能: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输出
--- 模块功能: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发送
--- 模块功能: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助手发布消息