ESP8266与DHT传感器构建低成本物联网温湿度Web服务器
1. 项目概述与核心价值
如果你正在寻找一个能快速上手、成本极低且能独立工作的物联网传感器节点方案,那么将ESP8266与DHT传感器组合,构建一个温湿度Web服务器,无疑是一个绝佳的起点。这个项目完美诠释了现代物联网(IoT)的精髓:用一块比邮票大不了多少的电路板,加上一个几十块钱的传感器,就能创建一个可以通过浏览器随时随地访问的微型数据服务端。我最初接触这个方案是为了监控家里的花房环境,当时市面上成品的环境监测仪要么功能臃肿,要么价格不菲,而这个自制的方案总成本可以控制在百元以内,并且完全自主可控。
ESP8266这颗芯片的出现,可以说彻底改变了创客和嵌入式开发者的游戏规则。它集成了完整的Wi-Fi网络协议栈和一个可编程的微控制器(MCU),价格却仅为传统“Arduino + Wi-Fi扩展板”方案的几分之一。这意味着,你可以将传感器数据直接通过Wi-Fi发送到云端,或者像我们在这个项目里做的一样,让设备自己成为一个Web服务器,直接在局域网内提供数据服务。这种“去中心化”的思路,对于一些不需要复杂云端逻辑、只需在本地网络查看数据的场景(如车间温湿度监控、小型实验室环境记录)来说,既简单又可靠。
DHT22(或更经济的DHT11)温湿度传感器,则是环境监测领域的“常青树”。它采用单总线数字信号输出,只需要一根数据线就能同时读取温度和湿度,极大地简化了硬件连接。虽然它的读取速度不算快(约2秒一次),精度也属于消费级,但对于绝大多数非高精度要求的日常监测应用来说,已经完全足够。将这两者结合,我们得到的是一个能够独立运行、通过Wi-Fi接入网络、并通过标准HTTP协议提供数据的完整终端设备。你不再需要一台始终开机的电脑作为数据中转站,这个火柴盒大小的装置自己就能搞定一切。
2. 硬件选型、电路设计与安全供电
2.1 核心元件深度解析
ESP8266模块选型:ESP-01的利与弊项目原文中使用了经典的ESP-01模块,它仅有8个引脚,体积小巧,价格最低。但正是这种极简设计,带来了几个必须注意的挑战:
- GPIO引脚极度有限:仅GPIO0和GPIO2可供用户使用,GPIO0还兼作启动模式选择脚。这意味着你几乎只能连接一个像DHT这样的单数据线传感器。
- 无内置USB转串口:编程和调试必须依赖外部的USB转TTL串口工具。
- 对电源要求苛刻:ESP8266是纯粹的3.3V器件,其IO口也只能耐受3.3V电平,5V输入会立即损坏芯片。更关键的是,在启动和Wi-Fi通信瞬间,它的峰值电流可能超过300mA,这对电源的瞬态响应能力提出了要求。
因此,对于新手,我强烈建议考虑使用NodeMCU或Wemos D1 mini这类开发板。它们集成了USB转串口芯片、3.3V稳压器以及电平转换电路,通过Micro-USB线即可完成供电和编程,GPIO也通过排针引出,使用起来和Arduino Uno一样方便。虽然成本比裸ESP-01高一些,但节省了大量的调试时间和额外的元器件成本,成功率也高得多。
DHT22 vs DHT11:不只是精度的区别
- DHT22(AM2302):测量范围更广(-40~80°C,0~100%RH),精度更高(温度±0.5°C,湿度±2~5%RH)。响应速度更快一些。
- DHT11:测量范围较小(0~50°C,20~90%RH),精度较低(温度±2°C,湿度±5%RH)。价格通常只有DHT22的一半。 对于室内环境监测,DHT11的数据完全可用。但如果项目涉及可能低于0°C或高于50°C的环境(如车库、阁楼),或者对湿度精度有更高要求(如孵化器、干燥箱),DHT22是更稳妥的选择。两者编程接口完全兼容,更换传感器无需修改代码,只需在代码中
#define DHTTYPE处更改型号即可。
2.2 电路连接与安全供电方案
如果坚持使用ESP-01模块,电路连接需要格外小心。下图是核心连接示意图的精简描述:
电源部分(重中之重):ESP8266的供电必须稳定、干净。绝对不能直接使用未经稳压的5V或更高的电源适配器。推荐方案如下:
- 首选方案:使用一枚AMS1117-3.3或LD1117-3.3稳压芯片。它的输入电压范围(最高可达15V)和800mA的输出能力,足以应对ESP8266的峰值电流。接线时,在稳压芯片的输入和输出端,最好都并联一个10μF的电解电容和一个0.1μF的陶瓷电容,分别用于滤除低频和高频噪声,这对于使用品质一般的手机充电器作为输入电源时尤其重要。
- 简化方案:如果使用NodeMCU等开发板,则直接通过Micro-USB口提供5V输入即可,板载稳压电路会处理好一切。
信号连接部分:
- DHT传感器:VCC接3.3V,GND接GND,DATA引脚接ESP8266的GPIO2(对应ESP-01模块的引脚4)。同时,在DATA引脚和3.3V之间需要连接一个4.7KΩ或10KΩ的上拉电阻,以确保数据线在空闲时保持高电平。大多数DHT传感器模块已经集成了这个电阻,购买时请注意区分。
- 编程接口:使用USB转TTL串口工具(如CP2102、CH340模块)时,务必确认其输出电平是3.3V。连接关系为:
- TTL的TX -> ESP8266的RX (ESP-01的引脚7)
- TTL的RX -> ESP8266的TX (ESP-01的引脚6)
- TTL的GND -> ESP8266的GND
- 切勿连接TTL工具的VCC(通常是5V)到ESP8266!仅使用3.3V电源为ESP供电。
- 启动模式选择:ESP8266需要通过GPIO0的电平来决定启动模式。正常运行时,GPIO0应通过一个10KΩ电阻上拉到3.3V(即悬空或接高电平)。在需要烧录固件时,则需在通电前将GPIO0接地(拉低)。很多开发板通过一个按钮自动实现了这个功能。
重要提示:在给整个系统通电前,请用万用表再三确认3.3V电源线的电压是否准确稳定,并检查是否有任何5V信号线误接到了ESP8266的引脚上。一次误接就可能导致芯片永久损坏。
3. 软件环境搭建与核心代码剖析
3.1 Arduino IDE环境配置详解
虽然现在有PlatformIO等更强大的开发环境,但Arduino IDE对于快速入门依然是最友好的。配置ESP8266支持步骤如下:
- 安装Arduino IDE:确保版本在1.8.x或以上。从Arduino官网下载安装。
- 添加开发板管理器网址:打开
文件 -> 首选项,在“附加开发板管理器网址”框中,填入:
如果有多个网址,用逗号隔开。http://arduino.esp8266.com/stable/package_esp8266com_index.json - 安装ESP8266开发板包:打开
工具 -> 开发板 -> 开发板管理器,在搜索框中输入“esp8266”。找到“esp8266 by ESP8266 Community”,选择最新版本并点击“安装”。这个过程会下载编译工具链和核心库,需要一些时间。 - 选择正确的开发板:安装完成后,在
工具 -> 开发板下,会出现一系列ESP8266型号。根据你的硬件选择:- 如果是ESP-01模块,选择“Generic ESP8266 Module”。
- 如果是NodeMCU,选择“NodeMCU 1.0 (ESP-12E Module)”。
- 如果是Wemos D1 mini,选择“LOLIN(WEMOS) D1 R2 & mini”。
- 配置开发板参数(针对ESP-01):选择开发板后,还需在“工具”菜单下进行关键配置:
Flash Size: 选择“1M (64K SPIFFS)”。大多数ESP-01是1MB闪存。Upload Speed: 选择“115200”。更高的速率可能不稳定。Port: 选择你的USB转TTL工具对应的串口号(如COM3, /dev/ttyUSB0)。CPU Frequency: “80 MHz”。- 其他选项保持默认即可。
3.2 库文件安装与代码逻辑全解
除了ESP8266核心库,我们还需要Adafruit的DHT传感器库。
- 安装DHT库:在Arduino IDE中,点击
项目 -> 加载库 -> 管理库,打开库管理器。搜索“DHT sensor library”,找到由Adafruit提供的库,点击安装。通常它会自动关联安装“Adafruit Unified Sensor”这个依赖库。这是最推荐的方法,能确保库版本兼容。
接下来,我们逐段分析并优化项目提供的代码。我将提供一个增强版的代码,并加入详细注释和实用改进。
/* * ESP8266 DHT Web Server 增强版 * 功能:创建一个Web服务器,提供温度和湿度数据的RESTful API接口 * 改进点:增加自动连接重试、配置页面、JSON格式输出、传感器读取容错 */ #include <ESP8266WiFi.h> #include <ESP8266WebServer.h> #include <DHT.h> // ==================== 用户配置区域 ==================== // 1. 修改你的Wi-Fi凭证 const char* ssid = "你的Wi-Fi名称"; const char* password = "你的Wi-Fi密码"; // 2. 传感器类型与引脚定义 #define DHTPIN 2 // DHT数据线连接的GPIO引脚 (NodeMCU D4, ESP-01 GPIO2) #define DHTTYPE DHT22 // 传感器型号: DHT22 (AM2302), DHT11 // 3. 服务器设置 #define SERVER_PORT 80 // HTTP标准端口 // ==================== 全局对象与变量 ==================== DHT dht(DHTPIN, DHTTYPE); // 初始化DHT传感器对象 ESP8266WebServer server(SERVER_PORT); // 初始化Web服务器对象,监听80端口 // 传感器数据变量 float temperature = 0.0; float humidity = 0.0; bool sensorError = false; // 定时读取传感器 unsigned long previousReadMillis = 0; const long READ_INTERVAL = 3000; // 读取间隔3秒(DHT22最小间隔2秒) // Wi-Fi连接状态 unsigned long previousWiFiCheckMillis = 0; const long WIFI_CHECK_INTERVAL = 30000; // 每30秒检查一次Wi-Fi连接 // ==================== 函数声明 ==================== void readDHTSensor(); void handleRoot(); void handleTemperature(); void handleHumidity(); void handleAllData(); void handleNotFound(); void initWiFi(); void checkWiFiConnection(); // ==================== 初始化设置 ==================== void setup() { Serial.begin(115200); delay(100); // 给串口一点启动时间 Serial.println("\n\n=== ESP8266 DHT Web Server 启动 ==="); // 初始化DHT传感器 dht.begin(); // 对于ESP8266这类高速MCU,需要调整DHT读取的时序容差参数,15是一个经验值 // 如果读取经常失败,可以尝试将这个值从11逐步调高到20 // dht.readHumidity()和dht.readTemperature()内部会使用这个参数 // 连接Wi-Fi initWiFi(); // 配置Web服务器路由 server.on("/", HTTP_GET, handleRoot); // 根目录,返回简单主页 server.on("/temp", HTTP_GET, handleTemperature); // 获取温度 server.on("/humidity", HTTP_GET, handleHumidity); // 获取湿度 server.on("/data", HTTP_GET, handleAllData); // 获取所有数据(JSON格式) server.onNotFound(handleNotFound); // 404处理 // 启动Web服务器 server.begin(); Serial.println("HTTP服务器已启动"); Serial.print("请访问: http://"); Serial.println(WiFi.localIP()); Serial.println("或 http://esp8266-dht.local (如果支持mDNS)"); } // ==================== 主循环 ==================== void loop() { server.handleClient(); // 处理客户端HTTP请求 readDHTSensor(); // 非阻塞方式定时读取传感器 checkWiFiConnection(); // 定期检查并维持Wi-Fi连接 } // ==================== 函数实现 ==================== /** * 初始化Wi-Fi连接 * 包含重试机制,避免启动时因信号问题卡死 */ void initWiFi() { Serial.print("正在连接Wi-Fi: "); Serial.println(ssid); WiFi.mode(WIFI_STA); // 设置为站点模式(客户端) WiFi.begin(ssid, password); int retryCount = 0; while (WiFi.status() != WL_CONNECTED && retryCount < 20) { // 最多重试20次 delay(500); Serial.print("."); retryCount++; } Serial.println(); if (WiFi.status() == WL_CONNECTED) { Serial.println("Wi-Fi连接成功!"); Serial.print("IP地址: "); Serial.println(WiFi.localIP()); Serial.print("信号强度(RSSI): "); Serial.print(WiFi.RSSI()); Serial.println(" dBm"); } else { Serial.println("Wi-Fi连接失败,请检查配置。"); // 在实际项目中,这里可以进入配置模式(如Web配网) } } /** * 定期检查并维持Wi-Fi连接 * 如果断开则尝试重连 */ void checkWiFiConnection() { unsigned long currentMillis = millis(); if (currentMillis - previousWiFiCheckMillis >= WIFI_CHECK_INTERVAL) { previousWiFiCheckMillis = currentMillis; if (WiFi.status() != WL_CONNECTED) { Serial.println("Wi-Fi连接丢失,尝试重连..."); WiFi.disconnect(); WiFi.reconnect(); delay(1000); // 等待重连 if (WiFi.status() == WL_CONNECTED) { Serial.println("Wi-Fi重连成功."); } } } } /** * 非阻塞方式定时读取DHT传感器数据 * 避免因传感器读取慢而阻塞主循环 */ void readDHTSensor() { unsigned long currentMillis = millis(); if (currentMillis - previousReadMillis >= READ_INTERVAL) { previousReadMillis = currentMillis; // 读取湿度(百分比) float h = dht.readHumidity(); // 读取温度(摄氏度),参数true则读取华氏度 float t = dht.readTemperature(); // 检查读取是否成功 if (isnan(h) || isnan(t)) { Serial.println("读取DHT传感器失败!"); sensorError = true; // 可以在这里增加失败计数,超过阈值则重启ESP } else { sensorError = false; humidity = h; temperature = t; // 可选:在串口输出数据用于调试 Serial.print("传感器读数 - 湿度: "); Serial.print(humidity); Serial.print(" %\t温度: "); Serial.print(temperature); Serial.println(" °C"); } } } /** * 处理根目录请求,返回一个简单的HTML页面 */ void handleRoot() { String html = "<!DOCTYPE html><html><head>"; html += "<meta charset='UTF-8'><meta name='viewport' content='width=device-width, initial-scale=1'>"; html += "<title>ESP8266 环境监测</title>"; html += "<style>"; html += "body { font-family: Arial, sans-serif; text-align: center; margin-top: 50px; }"; html += "h1 { color: #333; }"; html += ".data { font-size: 2em; margin: 20px; padding: 20px; border-radius: 10px; display: inline-block; }"; html += ".temp { background-color: #ffcccc; color: #b30000; }"; html += ".humi { background-color: #cce7ff; color: #0066cc; }"; html += "a { display: block; margin: 10px; font-size: 1.2em; }"; html += "</style></head><body>"; html += "<h1>🌡️ ESP8266 环境监测服务器</h1>"; html += "<p>设备IP: " + WiFi.localIP().toString() + "</p>"; if (sensorError) { html += "<p style='color: red;'>⚠️ 传感器读取错误,请检查连接。</p>"; } else { html += "<div class='data temp'>温度: " + String(temperature, 1) + " °C</div><br>"; html += "<div class='data humi'>湿度: " + String(humidity, 1) + " %RH</div>"; } html += "<hr>"; html += "<h3>数据接口 (RESTful API)</h3>"; html += "<a href='/temp'>/temp - 获取温度 (纯文本)</a>"; html += "<a href='/humidity'>/humidity - 获取湿度 (纯文本)</a>"; html += "<a href='/data'>/data - 获取全部数据 (JSON格式)</a>"; html += "<hr><p>数据更新时间: " + String(READ_INTERVAL / 1000) + " 秒</p>"; html += "</body></html>"; server.send(200, "text/html", html); } /** * 处理温度请求,返回纯文本温度值 */ void handleTemperature() { if (sensorError) { server.send(503, "text/plain", "Sensor Error"); } else { // 发送纯文本温度值,保留一位小数 server.send(200, "text/plain", String(temperature, 1)); } } /** * 处理湿度请求,返回纯文本湿度值 */ void handleHumidity() { if (sensorError) { server.send(503, "text/plain", "Sensor Error"); } else { server.send(200, "text/plain", String(humidity, 1)); } } /** * 处理/data请求,返回JSON格式的完整数据 * 这是与外部系统(如手机APP、其他服务器)集成的推荐格式 */ void handleAllData() { if (sensorError) { String errorJson = "{\"status\":\"error\", \"message\":\"Failed to read sensor\"}"; server.send(503, "application/json", errorJson); } else { // 构建JSON字符串,注意JSON的格式要求很严格 String json = "{"; json += "\"status\":\"ok\","; json += "\"temperature\":" + String(temperature, 1) + ","; json += "\"humidity\":" + String(humidity, 1) + ","; json += "\"unit\":{\"temperature\":\"C\", \"humidity\":\"%\"},"; json += "\"timestamp\":" + String(millis()); json += "}"; server.send(200, "application/json", json); } } /** * 处理未找到的页面请求(404) */ void handleNotFound() { String message = "File Not Found\n\n"; message += "URI: "; message += server.uri(); message += "\nMethod: "; message += (server.method() == HTTP_GET) ? "GET" : "POST"; message += "\nArguments: "; message += server.args(); message += "\n"; for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; } server.send(404, "text/plain", message); }3.3 代码核心机制与优化点解读
- 非阻塞式设计:整个代码的核心是
millis()定时器。readDHTSensor()和checkWiFiConnection()函数通过检查时间间隔来执行任务,而不是使用delay()。这保证了Web服务器(server.handleClient())能够及时响应HTTP请求,不会因为传感器读取(耗时约250ms)而卡住。 - Wi-Fi连接健壮性:增加了
checkWiFiConnection()函数,定期检查连接状态并在断开时尝试重连。这对于需要长期稳定运行的应用至关重要。 - 数据接口多样化:
/:提供人性化的HTML页面,方便浏览器直接查看。/temp和/humidity:返回纯文本数值,适用于简单的脚本调用或显示。/data:返回结构化的JSON数据,这是现代API的标准格式,便于被其他程序(如Python脚本、手机App)解析和集成。
- 错误处理:通过
sensorError标志位和HTTP状态码(如503 Service Unavailable)来反馈传感器故障,比直接返回一个NaN或0值更专业。 - 配置集中化:将Wi-Fi凭证、引脚定义、服务器端口等所有可配置项放在文件开头的“用户配置区域”,修改起来非常方便。
4. 程序烧录、调试与服务器访问
4.1 烧录程序(针对ESP-01模块)
对于ESP-01这类没有自动下载电路的模块,烧录程序需要手动操作,步骤必须严格:
- 连接电路:确保USB转TTL工具与ESP-01正确连接(TX-RX交叉,共地),且ESP-01由独立的3.3V/500mA以上电源供电(切记不要从USB转TTL工具取电,其3.3V输出电流通常不足)。
- 进入下载模式:
- 断开ESP-01电源。
- 将GPIO0引脚通过杜邦线接地(拉低)。
- 保持GPIO0接地的状态下,给ESP-01上电。
- 此时,ESP-01上的蓝色LED可能微亮或不亮,表示已进入固件下载模式。
- 松开GPIO0与地的连接(可以拔掉杜邦线,GPIO0内部有上拉电阻会将其拉高)。
- 执行烧录:
- 在Arduino IDE中,点击“上传”按钮。
- 观察IDE底部控制台输出。如果看到“Connecting….”之后出现一连串的点(…),表示正在擦写闪存,最后出现“Leaving… Hard resetting…”则表示烧录成功。
- 切换至运行模式:
- 烧录完成后,完全断开ESP-01的电源。
- 将GPIO0引脚悬空或接3.3V(确保其为高电平)。
- 重新上电,ESP-01将运行你刚烧录的程序。
避坑指南:超过50%的ESP-01烧录失败都源于电源问题。务必使用输出能力足够的3.3V稳压电源,并在电源引脚附近并联一个大电容(如100μF)以应对瞬时大电流。如果始终无法连接,尝试降低Arduino IDE中的“Upload Speed”到“115200”甚至“57600”。
4.2 串口监视器调试
烧录完成后,打开Arduino IDE的串口监视器(工具 -> 串口监视器),将右下角波特率设置为115200。然后给ESP-01重新上电(确保处于运行模式)。你将看到类似以下的输出:
=== ESP8266 DHT Web Server 启动 === 正在连接Wi-Fi: YourWiFiSSID ..... Wi-Fi连接成功! IP地址: 192.168.1.100 信号强度(RSSI): -45 dBm HTTP服务器已启动 请访问: http://192.168.1.100 传感器读数 - 湿度: 45.6 % 温度: 23.4 °C记下这里显示的IP地址,这是你访问Web服务器的钥匙。
4.3 访问Web服务器
确保你的电脑或手机连接到了同一个Wi-Fi网络。然后:
- 基础访问:在浏览器地址栏输入上一步获得的IP地址,如
http://192.168.1.100。你将看到一个简单的网页,显示当前的温湿度数据。 - 调用API接口:
- 获取温度:访问
http://192.168.1.100/temp,浏览器会显示一个纯数字,如“23.4”。 - 获取湿度:访问
http://192.168.1.100/humidity。 - 获取JSON数据:访问
http://192.168.1.100/data,会返回{"status":"ok","temperature":23.4,"humidity":45.6,...}。
- 获取温度:访问
你可以用任何能发送HTTP GET请求的工具来获取这些数据,比如在命令行用curl,或者在Python中用requests库,从而实现数据的自动化采集。
5. 常见问题排查与进阶优化
5.1 硬件连接与供电问题排查表
| 现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| ESP模块完全无反应,LED不亮 | 1. 电源未接通或电压错误。 2. 电源电流不足。 3. 模块损坏。 | 1. 用万用表测量VCC和GND之间电压,确保为3.3V±0.1V。 2. 尝试更换为输出电流大于500mA的3.3V稳压电源。 3. 检查电源正负极是否接反。 |
| 串口监视器无任何输出 | 1. 串口线连接错误(TX/RX接反)。 2. 波特率设置错误。 3. GPIO0未正确上拉(运行时需为高电平)。 | 1. 确认USB转TTL的TX接ESP的RX,RX接ESP的TX。 2. 尝试不同的波特率:115200、74880、9600。 3. 测量GPIO0引脚电压,运行时应为3.3V左右。 |
| Wi-Fi连接失败 | 1. SSID或密码错误。 2. 路由器设置了MAC地址过滤或隐藏了SSID。 3. ESP距离路由器太远,信号弱。 | 1. 仔细检查代码中的SSID和密码,注意大小写和特殊字符。 2. 查看路由器后台,将ESP的MAC地址(可从串口启动信息看到)加入白名单,或尝试连接一个开放的热点测试。 3. 通过 WiFi.RSSI()查看信号强度,低于-70dBm则可能不稳定。 |
| 能连Wi-Fi但无法访问网页 | 1. 电脑/手机与ESP不在同一局域网。 2. 防火墙或杀毒软件拦截。 3. 服务器端口被占用或程序未成功启动。 | 1. 确认设备IP在同一网段(如都是192.168.1.x)。 2. 暂时关闭电脑防火墙尝试。 3. 观察串口日志,确认输出了“HTTP服务器已启动”及IP地址。 |
| DHT传感器读取失败 | 1. 数据线接触不良或接错引脚。 2. 上拉电阻未接或失效。 3. 供电不足(DHT22工作电流峰值可达2.5mA)。 4. 读取间隔太短(小于2秒)。 | 1. 重新插拔接线,确认DATA引脚连接正确。 2. 在DATA和3.3V间增加一个4.7KΩ电阻。 3. 确保传感器VCC由稳定的3.3V供电,而非从GPIO取电。 4. 确保代码中 READ_INTERVAL大于2000毫秒。 |
5.2 软件与代码层面进阶技巧
- 解决DHT读取不稳定:ESP8266运行频率高,有时需要调整DHT库的时序容差。在
dht.begin()后,可以尝试调用dht.read()并传入一个更大的参数,如dht.readHumidity(true, 20),这个参数需要根据实际情况微调。 - 添加Web配网功能:避免将Wi-Fi密码硬编码在代码里。可以使用
WiFiManager库。首次启动时,ESP会创建一个名为“ESP_Config”的热点,手机连接后,浏览器打开192.168.4.1即可配置要连接的Wi-Fi,配置信息会保存到闪存中。 - 启用mDNS服务:这样你就可以通过
http://esp8266-dht.local这样的域名访问设备,而无需记忆IP地址。在setup()中加入if (MDNS.begin("esp8266-dht")) { Serial.println("mDNS responder started"); },并需要包含<ESP8266mDNS.h>头文件。 - 深度睡眠以省电:如果使用电池供电,可以让ESP8266每隔一段时间(如5分钟)唤醒一次,读取传感器数据,通过Wi-Fi发送出去,然后立即进入深度睡眠。这可以将平均电流从几十mA降至几十μA。代码中需要使用
ESP.deepSleep(sleepTimeInMicroseconds)函数,并需要将GPIO16与RST引脚短接来实现定时唤醒。 - 数据上报到云端:除了做本地服务器,你还可以让ESP8266作为客户端,将数据发送到物联网平台(如ThingsBoard、阿里云IoT、Home Assistant)。这通常需要你修改
loop()函数,在读取传感器后,使用WiFiClient或HTTPClient库向云端API发起POST请求。
5.3 项目扩展思路
这个温湿度Web服务器只是一个起点。理解了其核心原理——ESP8266作为网络接入点,通过HTTP协议提供传感器数据——之后,你可以进行无限扩展:
- 多传感器集成:使用I2C或SPI总线,可以连接多个传感器(如大气压BMP280、光照强度BH1750、空气质量SGP30)。NodeMCU等开发板有足够的GPIO来支持这些总线。
- 触发与联动:结合继电器模块,可以实现“当温度高于30°C时自动打开风扇”这样的逻辑。代码中可以在读取温度后添加判断,并通过
digitalWrite()控制继电器引脚。 - 美化Web界面:使用更复杂的HTML、CSS和JavaScript,可以制作出实时刷新的图表界面。ESP8266可以托管这些静态文件(需要用到SPIFFS文件系统),或者直接通过AJAX从
/data接口获取JSON数据并动态更新图表。 - 搭建分布式网络:部署多个这样的节点在房间各处,由一个中心服务器(可以是一个树莓派,或者另一台ESP8266)定期轮询所有节点的
/data接口,将数据汇总存储和展示。
从我个人的经验来看,这个项目的魅力在于其极简的硬件和清晰的软件架构所带来的高度可塑性。它就像一块乐高积木的基础件,你可以用它搭建出从简单的环境监测站到复杂的智能家居中枢等各种应用。第一次看到自己组装的这个小板子,在手机浏览器上显示出实时温湿度时,那种成就感是驱动你继续探索物联网世界的最佳动力。
