去年夏天,我在自家地下室发现墙面出现了霉斑,这才意识到温湿度监测的重要性。作为一名物联网爱好者,我决定用最经济的方案搭建一个实时监测系统。经过多次迭代,最终形成了这套基于DHT11传感器和ESP8266的完整解决方案,成本不到50元,却能实现专业级的远程监测功能。
在众多温湿度传感器中,DHT11以极高的性价比脱颖而出:
注意:DHT11的测量范围有限(湿度20-90%RH,温度0-50℃),精度为±5%RH和±2℃。如需更高精度,可考虑DHT22或SHT30。
NodeMCU是最适合初学者的选择:
| 型号 | 价格 | Flash | 内置USB | 引脚兼容性 |
|---|---|---|---|---|
| NodeMCU V3 | 25元 | 4MB | 有 | 优秀 |
| Wemos D1 Mini | 18元 | 4MB | 需转接板 | 良好 |
| ESP-01S | 12元 | 1MB | 无 | 较差 |
推荐使用NodeMCU V3,其GPIO布局与Arduino兼容,开发最便捷。
cpp复制/*
* DHT11与NodeMCU连接方式:
* DHT11 VCC -> NodeMCU 3.3V
* DHT11 GND -> NodeMCU GND
* DHT11 DATA -> NodeMCU D4 (GPIO2)
* 建议在DATA与VCC间加4.7K上拉电阻
*/
实际接线时,我强烈建议使用面包板先进行测试。曾有一次我直接焊接导致接触不良,花了2小时才排查出问题。
要让Arduino支持ESP8266,需要添加开发板支持:
http://arduino.esp8266.com/stable/package_esp8266com_index.json这三个库缺一不可:
在Arduino中点击"项目 > 加载库 > 管理库",搜索安装即可。
优化后的DHT11读取代码增加了错误处理和重试机制:
cpp复制#include <DHT.h>
#define DHTPIN D4 // 数据引脚
#define DHTTYPE DHT11 // 传感器类型
DHT dht(DHTPIN, DHTTYPE);
void readSensor() {
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("读取失败,正在重试...");
delay(2000);
return;
}
Serial.print("湿度: ");
Serial.print(h);
Serial.print("% 温度: ");
Serial.print(t);
Serial.println("℃");
}
使用SmartConfig简化WiFi配置:
cpp复制#include <ESP8266WiFi.h>
#include <PubSubClient.h>
const char* mqtt_server = "broker.emqx.io";
WiFiClient espClient;
PubSubClient client(espClient);
void setup_wifi() {
WiFi.mode(WIFI_STA);
WiFi.beginSmartConfig();
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi连接成功");
Serial.println("IP地址: ");
Serial.println(WiFi.localIP());
}
void reconnect() {
while (!client.connected()) {
String clientId = "ESP8266Client-" + String(random(0xffff), HEX);
if (client.connect(clientId.c_str())) {
client.publish("home/sensor/status", "online");
} else {
delay(5000);
}
}
}
采用JSON格式传输数据,便于网页端解析:
cpp复制void publishData(float h, float t) {
StaticJsonDocument<200> doc;
doc["humidity"] = h;
doc["temperature"] = t;
doc["device"] = "bedroom";
char jsonBuffer[512];
serializeJson(doc, jsonBuffer);
client.publish("home/sensor/data", jsonBuffer);
}
使用HTML+CSS+JS三件套搭建:
html复制<!DOCTYPE html>
<html>
<head>
<title>温湿度监测</title>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.3.2/dist/echarts.min.js"></script>
<style>
#chart { width: 100%; height: 400px; }
.container { max-width: 800px; margin: 0 auto; }
</style>
</head>
<body>
<div class="container">
<h1>卧室环境监测</h1>
<div id="chart"></div>
<div id="current">正在连接...</div>
</div>
</body>
</html>
配置双Y轴折线图展示数据:
javascript复制var chart = echarts.init(document.getElementById('chart'));
var option = {
tooltip: { trigger: 'axis' },
legend: { data: ['温度', '湿度'] },
xAxis: { type: 'category', data: [] },
yAxis: [
{ name: '温度(℃)', type: 'value' },
{ name: '湿度(%)', type: 'value' }
],
series: [
{ name: '温度', type: 'line', data: [] },
{ name: '湿度', type: 'line', yAxisIndex: 1, data: [] }
]
};
使用MQTT.js实现实时数据更新:
javascript复制var client = mqtt.connect('wss://broker.emqx.io:8084/mqtt')
client.on('connect', function() {
client.subscribe('home/sensor/data')
})
client.on('message', function(topic, payload) {
var data = JSON.parse(payload.toString())
updateChart(data.temperature, data.humidity)
})
function updateChart(temp, humi) {
var now = new Date().toLocaleTimeString()
option.xAxis.data.push(now)
option.series[0].data.push(temp)
option.series[1].data.push(humi)
// 保持最近20条数据
if (option.xAxis.data.length > 20) {
option.xAxis.data.shift()
option.series[0].data.shift()
option.series[1].data.shift()
}
chart.setOption(option)
document.getElementById('current').innerHTML =
`当前温度: ${temp}℃ | 当前湿度: ${humi}%`
}
通过深度睡眠降低能耗:
cpp复制#define uS_TO_S_FACTOR 1000000
#define TIME_TO_SLEEP 300 // 5分钟
void setup() {
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
}
void loop() {
// 采集和发送数据后
esp_deep_sleep_start();
}
三种可选的数据存储方式对比:
| 方案 | 实现难度 | 成本 | 查询便利性 | 适用场景 |
|---|---|---|---|---|
| 本地SD卡 | 中等 | 低 | 差 | 无网络环境 |
| MySQL数据库 | 高 | 中 | 优 | 自有服务器 |
| InfluxDB | 中 | 免费 | 优 | 时序数据专业分析 |
完善的错误恢复策略:
cpp复制void setup() {
ESP.wdtEnable(8000); // 8秒看门狗
}
void loop() {
ESP.wdtFeed();
// 业务逻辑...
}
这套系统经过简单修改即可应用于:
我曾帮朋友将其改造为鱼缸监测系统,增加了pH值传感器,通过企业微信接收报警通知。关键在于理解MQTT的发布/订阅机制,任何传感器数据都能用相同模式传输。