zoukankan      html  css  js  c++  java
  • 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助手发布消息

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 排队打水问题
    Java实现 蓝桥杯VIP 算法提高 排队打水问题
    Java实现 蓝桥杯VIP 算法提高 排队打水问题
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    现在使用控件, 更喜欢继承(覆盖控件已有的函数,很奇怪的一种使用方式)
    Controls 属性与继承 TShape 类的小练习(使用TShape可以解决很多图形问题)
    QT创建窗口程序、消息循环和WinMain函数(为主线程建立了一个QEventLoop,并执行exec函数)
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/12962398.html
Copyright © 2011-2022 走看看