【2G模组Air202开发】Lua脚本编程实现MQTT协议连接Tlink平台(三)

11 篇文章 2 订阅
7 篇文章 3 订阅

【2G模组Air202开发】Lua脚本编程实现MQTT协议连接Tlink平台(三)

 

整体思路:

  1. 在TLINK平台上创建一个MQTT协议的设备
  2. 对Air202模组进行lua编程并烧录
  3. 使用串口向Air202模组发送TLINK平台规定格式的payload数据,Air202接收到数据后进行封装并转发
  4. 观察TLINK平台的设备数据并下发数据观察串口接收到的数据

因为篇幅过长,我这里分成5篇来详细记录。

【2G模组Air202开发】Lua脚本编程实现MQTT协议连接Tlink平台(一)

【2G模组Air202开发】Lua脚本编程实现MQTT协议连接Tlink平台(二)

【2G模组Air202开发】Lua脚本编程实现MQTT协议连接Tlink平台(三)

【2G模组Air202开发】Lua脚本编程实现MQTT协议连接Tlink平台(四)

【2G模组Air202开发】Lua脚本编程实现MQTT协议连接Tlink平台(五)

 

 

对Air202模组MQTT的Lua程序编写,同样的先贴上第一部分的代码

--- 模块功能: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
local mqttip,mqttport,mqttuser,mqttpassword,mqttheartbeat = "mq.tlink.io","1883","MQTT","MQTTPW",60

socket.setSendMode(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
            --是否获取到分配的IP(是否连上网)
            if socket.isReady() then
                local imei = misc.getImei()
                --创建一个MQTT客户端
                local mqttClient = mqtt.client(imei,mqttheartbeat,mqttuser,mqttpassword)
                --阻塞执行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(mqttip,mqttport,"tcp") then
                    --连接成功
                    log.info("mqttTask.mqttClient","Connet ok!","imei = " .. imei) 
                    retryConnectCnt = 0 --失败次数清零
                    --ready = true
                    --订阅主题
                    if mqttClient:subscribe({["xxx".."/+"]=0}) then --xxx代表的是序列号
                        mqttOutMsg.insertMsg("xxx","Iccid = " .. sim.getIccid(),0)--这个没啥用
                        --循环处理接收和发送的数据
                        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
                    end
                    --ready = false
                else
                    log.info("mqttTask.mqttClient","Connet fail!") 
                    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
)

 

贴上部分api:

这个部分就是mqtt任务的核心了,也是最难理解的地方,下面硬着头皮来记录下心得:

mqtt连接都是异步运行的,何时应该发送数据,何时应该接收数据,这些逻辑应该让mqtt收发的进程自己进行控制。一般来说,我们会在模块成功获取基站分配的ip后,才会进行网络的连接操作,所以我们需要使用socket.isReady()函数来判断是否连接网络,然后再进行网络操作,在成功获取ip后,我们才能新建一个mqtt对象,对其进行联网操作。为了增加代码的稳健性,我们可以利用sys.waitUntil()函数,设置五分钟内没有获取到ip就开启飞行模式几秒,再关闭,让模块重新去获取GPRS连接。同样,我们也可以给mqttClient:connect(mqttip,mqttport,"tcp")的连接加上错误次数的判断,连接错误超过五次,强制断开socket连接,等待五秒后重试。这些都理解之后那就是mqtt的收发数据了,这里是直接写在一个死循环里面的。

要注意的是:

在接收和发送函数不返回false的情况下,接收和发送循环会一直进行下去;只有当两个函数之一返回false时,才会触发break导致退出该接收和发送循环。所以接收和发送函数里面还要加上一定的机制才能使得mqtt任务的健全。

好了,此篇就只记录这个mqtt主任务,接收和发送函数留在下一篇。

 

这是次篇幅记录网络MQTT的主任务部分,MQTT的收发消息实现请移步接下来的篇幅。

By Urien 2019年6月29日 09:05:04

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值