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

整体思路:

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


继续上一笔记,这里对Air202模组MQTT的收发程序编写,同样的先贴上代码

MQTT的发送消息处理

module(...,package.seeall)

--数据发送的消息队列
local msgQueue = {}

function insertMsg(topic,payload,qos,user)
    table.insert(msgQueue,{topic=topic,payload=payload,qos=qos,user=user})
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)
    while #msgQueue>0 do
        local outMsg = table.remove(msgQueue,1)
        local result = mqttClient:publish(outMsg.topic,outMsg.payload,outMsg.qos)
        --if outMsg.user and outMsg.user.cb then outMsg.user.cb(result,outMsg.user.para) end
        if not result then return end
    end
    return true
end

开头创建了一个table,这个table就是用作MQTT发送数据缓冲用的,有需要发送数据,先往这个table里面添加。然后table的插入消息,这里面把table进行了一次封装,把MQTT发送数据的格式和参数添加进去了,这样调用这个insertMsg就非常直观了。贴上table的api:

lua脚本 自动化_脚本编程

有了进当然就有出啦,

lua脚本 自动化_lua脚本 自动化_02

然后有一个公共函数来判断缓冲里面有没有消息,有消息就返回true,否则返回false,这个就是用在消息接收里面的,因为消息接收也是个死循环的,他只有通过查询有没有消息需要发送来判断是否跳出自己的死循环。具体如何实现的下面会上代码。最后就是发送消息的实现了,判断有消息需要发送后,从缓冲里面去除老消息,然后调用publish方法发送出去,发送方法会返回一个结果,这个结果用来表示是否发送成功,如果发送不成功,那可能MQTT链路出现问题了,此时return 即可(和return false是一样的)。贴上publish的api:

lua脚本 自动化_lua脚本 自动化_03

发送部分讲完了,接下来就是接收了:

module(...,package.seeall)
require "utils"
--- 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,string.toHex(data.payload))
               
            --TODO:根据需求自行处理data.payload
            uart.write(1,"\r\n topic = "..data.topic .. "  paload = " ..data.payload) --通过串口1发送出去
            --如果mqttOutMsg中有等待发送的数据,则立即退出本循环
            if mqttOutMsg.waitForSend() then return true end
        else
            break
        end
    end
	
    return result or data=="timeout"
end

接收部分的代码量也非常小,就是在一个死循环里面调用recive方法接收,如果接收到数据就通过串口打印出来。虽然是几行代码,但是也要好好分析一下,首先是有数据的情况下,会进到if里面,这时候会串口打印出来接收到的网络数据,同时会判断有没有数据需要发送,如果有的话立马返回,而且返回的值为true,这样不会导致mqtt主任务里面的死循环跳出。然后是其他情况,没有数据或者接收超时就肯定会进到else,而else里面直接break跳出了while,跳出之后返回一个值,当result为true的时候返回的是result(true),当result为false的时候再来看data是不是超时了,超时我们把它理解为是一种正常的运行状态,因为这种情况很常见,不能因为没有数据就认为是系统运行错误。当data不为“timeout”则代表可能mqtt出现问题了,此时返回false。

lua脚本 自动化_lua脚本 自动化_04

lua脚本 自动化_Lua_05

这是次篇幅讲记录MQTT接收和发送消息的实现,接下来的篇幅将介绍ntp和信号强度rssi及定时任务部分和最终的实现效果。

 

月1日 17:17:40