首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >GPRS(Air202) Lua开发: 物联网MQTT ,DTU

GPRS(Air202) Lua开发: 物联网MQTT ,DTU

作者头像
杨奉武
发布2020-05-26 16:42:17
1.1K0
发布2020-05-26 16:42:17
举报
文章被收录于专栏:知识分享知识分享

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-05-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 拷贝官方MQTT源码
  • 修改main.lua
  • 修改mqttTask.lua
  • 修改mqttInMsg.lua 
  • mqttOutMsg.lua 说明
  • 测试
  • 扩展:DTU
  • 扩展1:DTU 测试
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档