美文网首页NodeMCUESP8266 WIFI模块 & NodeMCU
NodeMCU阿里云平台的远程温度查看实现

NodeMCU阿里云平台的远程温度查看实现

作者: 波波2 | 来源:发表于2019-06-16 18:39 被阅读13次

    参考文章

    NodeMCU 通过MQTT 连接阿里云物联网 https://blog.csdn.net/weixin_43368807/article/details/82984796
    谢谢。

    概要

    本文与参考文章有一点的重复,但有几点会不同,一,更加具体的添加了一个实际功能,本文监控了温度与湿度信息;二,对代码进行了重新的组织,更加清晰简单。

    阿里云平台方面的准备工作

    创建产品、创建设备

    可以参考最前边列出的参考文章。另外,阿里云平台也有很好的引导,按着引导下一步下一步就可以了。

    添加功能

    这个是与参考文章不同的地方。对了让读者更容易理解为什么要添加功能,我把产品、设备、功能的关系简单描述下。产品就像一个抽象的概念,例如电视机,只有把电视机变成具体的东西,我们才能具体触摸感知,这个就是设备,很类似于类与对象的概念。而一个产品对普通人来说,主要就是关注与它能做什么,也就是它的功能。功能是在产品中定义的,每个设备都会具备这个功能,这个就类似与类方法。

    首先,选择产品,进入产品查看页面


    选择产品 进入产品查看信息页面

    然后,选择功能定义,在功能定义中选择自定义功能的添加


    添加自定义功能

    最后,进行自定义功能的设置


    自定义功能设置

    信息复制

    后期设备端连接阿里云服务器时有几个信息需要设置,所以现在就要把对应的信息准备好:

    1. 在产品查看页面获取ProductKey与ProductSecret两个信息;
    2. 在功能定义页面获取温度、湿度的标识名,例如:


      功能标识选择

      上图中,温度标识符:CurrentTemperature,湿度标识符:humidity,这两个是读者在前边自己设置。

    3. 在设备查看页面获取DeviceName信息;
    4. 在设备查看页面获取Topic链接信息,是一个类似/sys/*********/DeviceA/thing/event/property/post的字符串。

    到此为止,阿里云端的设置就已经完成了。

    设备端操作

    固件烧写

    请参考本文最前的参考文章的说明,以及本人其他关于NodeMCU操作的文章。但需要注意的是,固件注意选择温度传感器模块,例如我使用了DHT温度传感器模块。
    我的固件包含了如下模块:This was built against the master branch and includes the following modules: crypto, dht, encoder, enduser_setup, file, gpio, http, i2c, mqtt, net, node, pwm, sntp, spi, tmr, uart, wifi, wifi_monitor.

    代码编写逻辑

    在代码设计上,分为了五个文件,一个是初始化wifi逻辑文件,init.lua,另一个是mqtt的连接处理文件,再一个就是配置文件,用来记录不同使用者信息的文件,config.lua,再一个是mqtt的逻辑处理文件,这个是针对一个物联网项目需要编写的逻辑,mqtt_app.lua。最后一个文件是应用模块管理文件application.lua。未来,可能会有其他功能添加,例如添加一个HTTP服务器支持,那么很可能会需要添加新的模块实现,那么就在application.lua中加载新的模块实现。

    配置文件config.lua

    -- WIFI 设置
    SSID = "HiWiFi_**********"
    PASSWORD = "**********"
    
    
    -- MQTT设置
    ProductKey ="************"   
    DeviceName ="*******"  
    DeviceSecret="*********************************************"
    
    RegionId="cn-shanghai"     --华东2
    -- MQTT发送消息的topic
    publish_topic = "/sys/"..ProductKey.."/"..DeviceName.."/thing/event/property/post"
    

    Wifi初始化逻辑文件init.lua

    dofile("config.lua")
    
    
    function startup()
        if file.open("init.lua") == nil then
            print("init.lua deleted or renamed")
        else
            print("Running")
            file.close("init.lua")
            -- the actual application is stored in 'application.lua'
            dofile("application.lua")
        end
    end
    
    -- Define WiFi station event callbacks
    wifi_connect_event = function(T)
      print("Connection to AP("..T.SSID..") established!")
      print("Waiting for IP address...")
      if disconnect_ct ~= nil then disconnect_ct = nil end
    end
    
    wifi_got_ip_event = function(T)
      -- Note: Having an IP address does not mean there is internet access!
      -- Internet connectivity can be determined with net.dns.resolve().
      print("Wifi connection is ready! IP address is: "..T.IP)
      print("Startup will resume momentarily, you have 3 seconds to abort.")
      print("Waiting...")
      tmr.create():alarm(3000, tmr.ALARM_SINGLE, startup)
    end
    
    wifi_disconnect_event = function(T)
      if T.reason == wifi.eventmon.reason.ASSOC_LEAVE then
        --the station has disassociated from a previously connected AP
        return
      end
      -- total_tries: how many times the station will attempt to connect to the AP. Should consider AP reboot duration.
      local total_tries = 75
      print("\nWiFi connection to AP("..T.SSID..") has failed!")
    
      --There are many possible disconnect reasons, the following iterates through
      --the list and returns the string corresponding to the disconnect reason.
      for key,val in pairs(wifi.eventmon.reason) do
        if val == T.reason then
          print("Disconnect reason: "..val.."("..key..")")
          break
        end
      end
    
      if disconnect_ct == nil then
        disconnect_ct = 1
      else
        disconnect_ct = disconnect_ct + 1
      end
      if disconnect_ct < total_tries then
        print("Retrying connection...(attempt "..(disconnect_ct+1).." of "..total_tries..")")
      else
        wifi.sta.disconnect()
        print("Aborting connection to AP!")
        disconnect_ct = nil
      end
    end
    
    -- Register WiFi Station event callbacks
    wifi.eventmon.register(wifi.eventmon.STA_CONNECTED, wifi_connect_event)
    wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, wifi_got_ip_event)
    wifi.eventmon.register(wifi.eventmon.STA_DISCONNECTED, wifi_disconnect_event)
    
    print("Connecting to WiFi access point...")
    wifi.setmode(wifi.STATION)
    wifi.sta.config({ssid=SSID, pwd=PASSWORD})
    -- wifi.sta.connect() not necessary because config() uses auto-connect=true by default
    

    应用模块管理文件application.lua

    -- MQTT 模块 ----
    dofile("mqtt.lua")
    --print("Hello ...")
    

    mqtt的连接处理模块mqtt.lua

    -- 加载配置信息
    dofile("config.lua")
    -- 加载MQTT应用逻辑
    mqtt_app = require("mqtt_app")
    
    -- 连接阿里云
    ClientId =wifi.sta.getmac()  
    
    myMQTTport=1883    
    myMQTT=nil      
    
    myMQTThost=ProductKey..".iot-as-mqtt."..RegionId..".aliyuncs.com"   
    myMQTTusername=DeviceName.."&"..ProductKey         
    
    
    myMQTTtimes='1234567890'
    hmacdata="clientId"..ClientId.."deviceName"..DeviceName.."productKey"..ProductKey.."timestamp"..myMQTTtimes  
    myMQTTpassword=crypto.toHex(crypto.hmac("sha1",hmacdata,DeviceSecret))    
    myMQTTClientId=ClientId.."|securemode=3,signmethod=hmacsha1,timestamp="..myMQTTtimes.."|"      
    
    
    myMQTT=mqtt.Client(myMQTTClientId, 120,myMQTTusername,myMQTTpassword) 
    
    mqtt_app.MQTT_Init(myMQTT)
    
    print("Attempting client connect...")
    local re = myMQTT:connect(myMQTThost, myMQTTport,0, mqtt_app.MQTTSuccess,mqtt_app.MQTTFailed)
    

    mqtt的应用逻辑实现模块mqtt_app.lua

    dofile("config.lua")
    
    local myqq_app = {};
    
    MQTTconnectFlag = 0;
    mClient = nil;
    
    function myqq_app.MQTT_Init(client)
        --[设备offline 事件]-----
        myMQTT:on("offline", function(client) 
            print ("offline") 
            --tmr.start(0)
        end)
    
        --[注册 设备接收到订阅的topic 事件]-----
        myMQTT:on("message", function(client, topic, data) 
            print(topic ..":") 
            if data ~= nil then
                print(data)
            end
        end)
    end
    
    ---[连接成功]---
    function myqq_app.MQTTSuccess(client)
        print("MQTT connected")
        
        -- 注册通道
        --client:subscribe(topic0,0, function(conn)     --注册topic0
        --    print("subscribe success") 
        --end) 
    
        mClient = client;
        MQTTconnectFlag=1
        --tmr.stop(0)        --关闭定时连接
        
        --[topic 定时上传数据]
        tmr.create():alarm(5000, 1, function()    --等待连接上
            if MQTTconnectFlag==1 and mClient~=nil then   
                re,t,s,x = dht.read11(1);
                msg = "{\"id\":\"bc:dd:c2:30:cb:dc\", \"params\":{\"CurrentTemperature\":"..tostring(t)..",\"humidity\":"..tostring(s).."},\"method\":\"thing.event.property.post\"}"
                mClient:publish(publish_topic,msg,0,0,function(client)
                                print("send ok" ) 
                end)
            end
        end)
    end
    
    ---[连接失败]---
    function myqq_app.MQTTFailed(client,reson)
        print("Fail reson:"..reson)
        MQTTconnectFlag=0
        --tmr.start(0)     --重新启动连接
    end
    
    return myqq_app;
    

    相关文章

      网友评论

        本文标题:NodeMCU阿里云平台的远程温度查看实现

        本文链接:https://www.haomeiwen.com/subject/dudwfctx.html