赞
踩
硬件外观,某宝购入,挑了一个便宜的,4.75元一个,宽压 DC 3.3 ~ 5.5 V 均可。
参考资料 :电容式湿度传感器 - DFROBOT,该文档讲解非常详细。
湿度传感器的板子上一共出来三根线,VCC 和 GND 正常接供电和接地即可,我这个传感器 3.3V 和 5V 输入都可以。
重点就是数据输出的那根线,接一个不用的 GPIO 口即可,注意避开有特殊功能的口,接口定义参见 01 篇博客,这里我连接了 GPIO 4
,对应我板子上标识的 G4
(这个 ESP32 的标识可能与你的不同,请参照你自己的电路图确定 GPIO 号),这里注意,如果同时使用 wifi 可能会有 GPIO 口冲突问题,简单的解决方法就是换不冲突的口来读,见 3.4。
只需利用 analogRead()
函数,读取该 GPIO 口上的模拟数据。
请注意,该数据并不是相对湿度,而是一个参考值,这里引用 dfrobot 官网的一段解释:
问题:为什么我们不能用防水的相对湿度传感器去测量土壤湿度?
解释:土壤湿度的定义是取1公斤土样,彻底烘干,减少的重量(水的重量)与1公斤的比值成为土壤湿度。空气相对湿度的定义是当前温度下的绝对湿度与当前温度下的饱和湿度的百分比。综上土壤湿度跟空气湿度不是一个概念,也不是一个数量级,土壤湿度10%时土壤中空气的湿度已经100%了。注意:利用防水型相对湿度传感器,将其埋在土壤里是不会损坏的,即使带电再水里煮也不会损坏,但当面对湿度稍大的土壤,土壤中空气湿度会长期是100%,测量就失去了意义。
极简代码
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println(analogRead(4));//湿度传感器接ESP32上的GPIO号
delay(100);
}
**参考 电容式湿度传感器 - DFROBOT 文档中对该传感器的标定建议,我们采用 空气中的读数 和 水中的读数 ,作为 干、湿的参考区间 ,步骤如下:
首先,烧录读取传感器数据的代码,参考 3.2 极简代码即可,并打开 Arduino 上的串口监视器。
在空气中观察读数,我手头这个传感器的读数大约稳定在 2590 。
把传感器下半部分插入水中,观察读数,大约稳定在 1090,至此我们就获得了两个极值。
从上述测量值我们可以看出,模拟输出的数值与湿度是成反比的,我们可以根据两次测量值构造一个简单的线性函数,实际上湿度与电容式传感器测量值不一定是线性关系,如果想要得出稍微准确的对应关系,应该在不同湿度的土壤中做多次试验来拟合曲线。
这里,我们就理想化的认为它符合线性关系,那么读数 1090 记为
c
m
a
x
c_{max}
cmax , 对应土壤湿度 100% 记为
m
m
a
x
m_{max}
mmax; 读数 2590 记为
c
m
i
n
c_{min}
cmin ,对应土壤湿度 0% 记为
m
m
i
n
m_{min}
mmin,当前土壤含水量为
m
c
u
r
m_{cur}
mcur,ESP32 读数为
c
c
u
r
c_{cur}
ccur,构造线性函数如式(1):
m
c
u
r
=
(
c
c
u
r
−
c
m
i
n
)
∗
(
m
m
a
x
−
m
m
i
n
)
(
c
m
a
x
−
c
m
i
n
)
(1)
m_{cur} = (c_{cur} - c_{min})* \frac{(m_{max}-m_{min})}{(c_{max}-c_{min})} \tag 1
mcur=(ccur−cmin)∗(cmax−cmin)(mmax−mmin)(1)
推荐的插入深度如下图,绿色区间为建议的深度,不可越过红色线。
wifi 与 adc 冲突问题,目前我偷懒解决,换了一个不冲突的 pin 口就好了,之前的 GPIO 4 无法读取数据。
例程代码
#include <WiFi.h>
const char *ssid = "***";
const char *password = "***";
float c_min = 2590.0; //readings in air
float c_max = 1090.0; //readings in water
float m_min = 0.0; //min soil moisture
float m_max = 100.0; //max soil moisture
const int m_Pin = 32; //与wifi不冲突的pin
WiFiUDP Udp;
IPAddress remote_IP(192, 168, 1, 22);
unsigned int remoteUdpPort = 6060; // 自定义远程监听端口
void setup()
{
Serial.begin(9600);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(200);
Serial.print(".");
}
Serial.println("Connected");
Serial.print("IP Address:");
Serial.println(WiFi.localIP());
}
void loop()
{
Udp.beginPacket(remote_IP, remoteUdpPort);//配置远端ip地址和端口
int c_cur = analogRead(m_Pin);//读取GPIO上的模拟数据
int m_cur = (c_cur - c_min) * (m_max - m_min) / (c_max - c_min);//公式(1)
String str_m_cur(m_cur);
Udp.println(str_m_cur);//把数据写入发送缓冲区
Udp.endPacket();//发送数据
delay(1000);
}
测试结果正常,空气中 UDP 远端收到 0,水中收到 100 。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。