美文网首页NODEMCU基于nodemcu的智能电子秤开发
7.实用实例系列2:nodeMcu实现温湿度监测

7.实用实例系列2:nodeMcu实现温湿度监测

作者: yangmouren | 来源:发表于2017-07-30 23:07 被阅读1520次

    7.实用实例系列2:nodeMcu实现温湿度监测

    前言

    之前实现的是对继电器的控制,但智能化控制,还需要一些检测乃至监测,实时反馈环境变化,用来提供控制的依据,这样才更智能。这里开始尝试对用nodeMcu实现温湿度的检测,标题用监测是由于通过Domoticz实现温湿度的显示,通过它进行监测。
    还需要交代的是,由于本人比较菜,很多知识都是不足,最后实现这个也是参考学习了一些网友的代码。下篇文章本人学着通过ESPEasy同样实现了相同的功能,那样操作就更简易了。

    1、温湿度传感器

    要实现这个温湿度检测功能,单单靠nodeMcu显然是不行,它只是处理数据的,具体检测还需要检测传感器。这里选用了SI7021高精度温湿度传感器模块。

    SI7021高精度温湿度传感器模块.png

    之所以说是模块,是因为,它将传感器需要的电路都集成,直接提供了电压端口和检测端口,不用我们买传感器再根据datasheet买电阻电容焊电路。
    选用这个主要考虑到它的精度较高,当然如果对精度要求不高,可以选用其它模块,比如dt11等。

    2、电路连接

    之前这个图,我们可以看到传感器模块上只有 4个接口,分别是CL、
    DA、+、-,+、-明显是电源,这款传感器模块3.3V供电就可以,用nodeMcu上的3.3V电源接口即可, CL、DA是通过I2C协议传输温湿度数据的。nodeMcu是支持这个I2C协议的传输,具体可以参考https://nodemcu.readthedocs.io/en/master/en/modules/i2c/
    其实所有的IO基本都支持使用I2C协议作为SCL和SDA,这里取了D3和D4,主要是方便接线。欢迎大家用其它端口尝试。

    接线图

    3、软件编写

    3.1、重新选择nodeMcu功能模块刷写固件

    这里涉及到一些nodeMcu的模块,比如I2C,Si7021(我也是后来才知道原来本身自带这个温度传感器的软件模块),由于之前没有勾选这些模块,需要重新建立固件刷写,还是采用
    2.NodeMcu上手准备中云固件编译方式,刷写方法是3.关于NodeMcu刷固件遇到的问题及解决注意一下,这里需用支持浮点运算的float版固件(后面涉及一点浮点运算,原来用integer固件出了点问题)。模块选择如图所示吧,其它模块有些也是必选的,比如GPIO、timer、WiFi、net等,因为也会涉及,先参照这个建立固件,等邮件吧,再刷固件。

    sp170724_225520.png

    3.2、编写温湿度检测程序

    对于SI7021传感器,官方就有相关的代码教程,参考https://nodemcu.readthedocs.io/en/master/en/modules/si7021/。我们可以直接使用里面的例子。
    贴一下代码

    local sda, scl = 4, 3
    --设置数据传输端口,这里是D4、D3,即GPIO2、GPIO0
    i2c.setup(0, sda, scl, i2c.SLOW) 
    -- 设置传输协议
    si7021.setup()
    --开启si7021相关功能
    hum, temp, hum_dec, temp_dec = si7021.read()
    --读取湿度、温度、湿度小数值、温度小数值
    print(string.format("Humidity:\t\t%d.%03d\nTemperature:\t%d.%03d\n", hum, hum_dec, temp, temp_dec))
    --integer固件用这个打印温湿度
    print("Humidity: "..hum.."\n".."Temperature: "..temp)
    --Float固件用这个打印温湿度
    
    程序调试.png

    好了,温湿度检测功能实现,那如何将数据上传至Domoticz,实现可以在Domoticz上查看和记录呢?

    3.3、Domoticz设置

    这里直接给出相关设置截图
    1、在硬件里增加传感器


    在硬件里增加传感器 设置成功增加

    2、创建传感器,选择类型

    选择类型 成功增加

    3、查看传感器

    查看新建传感器

    4、查看idx和数据

    注意idx号后续需要用到

    目前还没与nodeMcu连接,数据还没有。注意idx号,后续数据上传接口和这个有关系。

    3.4、编写数据上传程序

    由于之前LED控制是基于http传输,并不知道Domoticz的接口,所以找方法费了些时间,最后找到了什么值得买上面@pufand写的把家装进净化器—90元打造全屋净化新风系统这篇文章,里面网盘附了代码,这里研究百度之后,发现了Domoticz的接口参考,具体可以看Domoticz_API及JSON网址。利用nodeMcu的net模块,通过接口实现数据上传。
    程序如下:

    conn=net.createConnection(net.TCP, 0) 
    --建立一个连接connection
    conn:on("receive", function(conn, payload) print(payload) end )
    conn:connect(8080,'192.168.8.93') 
    --连接Domoticz服务器IP和端口
    conn:send("GET /json.htm?type=command&param=udevice&idx="..idx.."&nvalue=0&svalue="..t..";"..h..";0 HTTP/1.1\r\nHost:  www.local.lan\r\n".."Connection: keep-alive\r\nAccept: */*\r\n\r\n")
    --根据Domoticz连接温湿度端口用GET方式连接
    --idx对应Domoticz中传感器idx
    --t,h对应温度湿度
    --nHost: www.local.lan这个是对主机网址命名
    --目前随意设置
    

    3.5、汇总程序

    总程序是通过分块功能函数的方式,再在主程序进行调用的方式实现。

    function setupwifi(SSID,password)
        wifi.setmode(wifi.STATION)
        wifi.sta.config(SSID,password)
    end
    --设置wifi连接,设置了一个连接wifi函数
    function sendt(t,h,idx)
    tmr.alarm(1, 1000, tmr.ALARM_AUTO,
    --延时函数等待wifi连接       
       function()
                if wifi.sta.getip()== nil then
                    print("not connected, Waiting...")
    --未连接显示等待
                else
                    tmr.stop(1)
                    print("Config done, IP is "..wifi.sta.getip())
     --连接显示IP     
                conn=net.createConnection(net.TCP, 0) 
                conn:on("receive", function(conn, payload) print(payload) end )
                conn:connect(8080,'192.168.8.93') 
    --连接Domoticz服务器IP和端口
                conn:send("GET /json.htm?type=command&param=udevice&idx="..idx.."&nvalue=0&svalue="..t..";"..h..";0 HTTP/1.1\r\nHost:  www.local.lan\r\n".."Connection: keep-alive\r\nAccept: */*\r\n\r\n")
    --利用Domoticz接口发送温湿度数据
                end
          end)
    end  
    --设置连接Domoticz服务器和发送数据函数
    function humtemp()
        local sda, scl = 4, 3
        i2c.setup(0, sda, scl, i2c.SLOW) 
        si7021.setup()
        hum, temp, hum_dec, temp_dec = si7021.read()
        hum1=string.format("%0.2f",hum + hum_dec / 1000)
    --取湿度
        temp1=string.format("%0.2f",temp + temp_dec / 1000)
    --取温度
        print(hum1,temp1)
        return hum1,temp1
    --返回湿度和温度
    end
    --设置读取温湿度函数
    ----------------------------------------------------------------------
    --以下为主程序
    setupwifi("填入你的路由SSID","填入你的路由密码")
    
    tmr.alarm(2, 2000, tmr.ALARM_AUTO,
                      function()
                            hum,temp =humtemp()
    --将温湿度值赋值给hum和temp
                            sendt(temp,hum,6)
    --发送hum和temp到idx为6的传感器
                     end)
    --延时2000ms重复读取温湿度和发送到Domoticz服务器
    

    运行试试吧,记得把中文注释删掉。

    程序运行截图

    运行结果中可以看到湿度温度,还有连接信息。


    Domoticz服务器中温度湿度传感器

    可以观察里面的温度湿度数值数值是变化的。

    结尾

    本文利用SI7021高精度温湿度传感器模块连接nodeMcu实现了温湿度数据的采集,连接Domoticz后实现温度湿度的实时监测。由于本身nodeMcu内嵌了SI7021模块,简化编程。通过学习发现解决了Domoticz接口传输问题。
    当然实现了温度湿度的监测,后面再加传感器比如PM2.5、甲醛、二氧化碳等等,实现起来就照样画葫芦了。
    下一篇再介绍另外一种实现方式,不过要刷ESPEasy固件,但操作更简单,无须编写程序。

    参考

    官方文档:https://nodemcu.readthedocs.io/en/master/en/modules/i2c/
    https://nodemcu.readthedocs.io/en/master/en/modules/si7021/
    Domoticz官方:https://www.domoticz.cn/wiki/Domoticz_API%E5%8F%8AJSON%E7%BD%91%E5%9D%80#.E6.B8.A9.E6.B9.BF.E5.BA.A6
    值友@pufand:https://post.smzdm.com/p/539326/

    相关文章

      网友评论

      • e70c0daab64f:你好,请问下我使用i2c协议读取MPU6050的数据,为什么读取不了正确的数据呢?
        id = 0
        sda = 2
        scl = 1

        -- initialize i2c, set pin1 as sda, set pin2 as scl
        i2c.setup(id, sda, scl, i2c.SLOW)

        -- user defined function: read from reg_addr content of dev_addr
        function read_reg(dev_addr, reg_addr)
        i2c.start(id)
        i2c.address(id, dev_addr, i2c.TRANSMITTER)
        i2c.write(id, reg_addr)
        i2c.stop(id)
        i2c.start(id)
        i2c.address(id, dev_addr, i2c.RECEIVER)
        c = i2c.read(id, 1)
        i2c.stop(id)
        return c
        end

        -- get content of register 0xAA of device 0x77
        tmr.alarm(0,1000,1,function()
        AXH = read_reg(0x68, 0x3B)
        AXL = read_reg(0x68, 0x3C)
        AYH = read_reg(0x68, 0x3D)
        AYL = read_reg(0x68, 0x3E)
        AZH = read_reg(0x68, 0x3F)
        AZL = read_reg(0x68, 0x40)
        print(AXH)
        print(string.byte(AXH))
        print(string.byte(AXL))
        --print(string.byte(AYH))
        --print(string.byte(AYL))
        --print(string.byte(AZH))
        --print(string.byte(AZL))
        end)

        代码在这。
        yangmouren:@毅之力_d4d2 程序没有错误提示,MPU6050模块应该是提供位置或位移数据,这个我也没接触过,请问你读取里面数据有问题吗?我看你是想往里面写东西,再将它读出来?我理解根据官方文档,读写的MPU6050都已经集成在例子里,你不需要在操作写的过程。我手头没有这个MPU6050没法验证。本身自己还是小白,相关内容也可能说错,见谅。
        e70c0daab64f:@yangmouren http://pan.baidu.com/s/1gfCGXiz
        评论里好像传不了图片,这里是结果和代码。
        i2c读取寄存器函数是官方文档上的,写入寄存器函数是自己写的,我觉得可能就是这里出错了,麻烦大神指导指导!
        yangmouren:我手头没有这个模块,你运行后的结果,方便的话也贴一下,并说明一下哪里有问题。也可以尝试ESPEasy固件,里面内置了这个传感器支持,具体参见我的 8、nodeMcu可视化操作固件介绍:ESPEasy

      本文标题:7.实用实例系列2:nodeMcu实现温湿度监测

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