拷貝官方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助手發布消息