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等,因为也会涉及,先参照这个建立固件,等邮件吧,再刷固件。
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¶m=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¶m=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/
网友评论
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)
代码在这。
评论里好像传不了图片,这里是结果和代码。
i2c读取寄存器函数是官方文档上的,写入寄存器函数是自己写的,我觉得可能就是这里出错了,麻烦大神指导指导!