1. 项目概述与核心价值
最近在折腾一个智能花房的小项目,核心需求是能随时随地查看棚内的温度和湿度。市面上成品的环境监测仪要么功能单一,要么价格不菲,而且数据往往封闭在自家的App里,没法和我自己搭建的其他智能设备联动。于是,我决定自己动手,用最经典的ESP8266开发板和DHT11传感器,搭建一个完全由自己掌控的物联网温湿度监测站。这个方案最大的魅力在于,你不需要依赖任何第三方云平台,数据直接在本地处理,并通过ESP8266内置的Wi-Fi功能创建一个微型Web服务器,用手机或电脑的浏览器就能直接访问,实时数据一目了然。
对于刚接触物联网开发的朋友来说,ESP8266搭配DHT11是一个绝佳的入门组合。ESP8266本身集成了Wi-Fi和微控制器,价格低廉且社区资源极其丰富;DHT11则是经过市场长期检验的温湿度传感器,虽然精度不算顶级,但胜在稳定、易用且成本极低,完全能满足家庭环境监测、小型温室、设备机房等场景的需求。整个项目的硬件成本可以控制在30元以内,软件层面也只需基础的Arduino编程知识,非常适合作为第一个物联网实战项目。接下来,我将从硬件选型、电路连接、代码编写到问题调试,完整地复盘我的搭建过程,并分享一些从实际部署中总结出来的宝贵经验。
2. 硬件选型与核心组件解析
2.1 主控板:为什么是NodeMCU ESP8266?
在众多ESP8266开发板中,我选择了NodeMCU LoLin V3版本。这个选择背后有几个关键的考量。首先,NodeMCU板载了USB转串口芯片(通常是CH340或CP2102),这意味着你只需要一根Micro-USB线就能完成供电和程序烧录,无需额外购买USB转TTL模块,极大简化了开发流程。其次,它引出了ESP8266芯片的大部分GPIO引脚,并以Arduino Uno类似的排针形式排列,方便在面包板或洞洞板上进行插接。V3版本通常改进了电源电路,稳定性更好。
这里需要理解一个核心概念:ESP8266本身是一个Wi-Fi SoC(片上系统),它内部包含了一个Tensilica L106微处理器核心。当我们使用Arduino IDE对其进行开发时,实际上是利用Arduino核心库为这个处理器编写程序,从而控制其GPIO、Wi-Fi等功能。NodeMCU开发板为我们做好了所有外围电路,让我们可以像使用一块Arduino板一样去使用ESP8266的强大网络功能。
注意:市面上NodeMCU版本较杂,有V1、V2、V3,也有安信可的ESP-12F模块自行焊装的版本。购买时建议选择明确标注了“LoLin V3”或“CH340/CP2102驱动”的版本,以避免驱动安装不上的麻烦。
2.2 传感器:DHT11的工作特性与局限
DHT11是一款经典的复合温湿度传感器,它内部包含一个电阻式感湿元件和一个NTC测温元件,并通过一个专用的8位单片机进行校准和数字信号输出。其工作电压范围为3.3V到5.5V,输出为单总线数字信号,这使得它只需要一根数据线即可与主控板通信,节省了宝贵的GPIO资源。
然而,必须客观认识它的性能指标,这决定了你的项目适用场景。DHT11的温度测量范围是0-50°C,精度为±2°C;湿度测量范围是20-90%RH,精度为±5%RH。响应时间也较慢,约2秒一次。这意味着它不适合用于需要高精度、快速响应的场合,比如精密工业控制或高速气流监测。但对于室内环境、植物养护箱这类变化缓慢的场景,它的数据是完全可用的。它的真正优势在于极高的性价比和出色的稳定性,我手头有几个已经连续工作了两年多的DHT11,数据依然可靠。
2.3 其他辅助材料清单
除了核心的主控板和传感器,你还需要准备一些基础材料来完成电路搭建:
- 杜邦线:若干,用于连接各组件。建议使用公对公的跳线。
- 面包板或洞洞板:一块,用于固定和连接电路。对于想长期使用的项目,建议使用洞洞板进行焊接,可靠性远高于面包板。
- Micro-USB数据线:一根,用于供电和编程。务必使用质量好的数据线,劣质线可能导致供电不足,使ESP8266工作不稳定甚至无法烧录程序。
- 可选:10kΩ上拉电阻:DHT11的数据手册要求在其数据线(DATA)和电源(VCC)之间连接一个4.7kΩ - 10kΩ的上拉电阻,以确保信号稳定。幸运的是,NodeMCU的某些GPIO(如D5)内部已有上拉电阻,在代码中启用后可以省略这个外部电阻,这简化了我们的电路。但如果你发现数据读取不稳定,第一个要检查的就是这个上拉电阻。
3. 电路连接与硬件搭建实操
硬件连接是整个项目中最简单但也最需要细心的一环,错误的连接可能会损坏传感器或导致主板无法工作。
3.1 引脚对应与连接原理
根据项目描述,我们需要将DHT11的三根引脚(VCC, GND, DATA)连接到NodeMCU上。连接关系如下:
- DHT11 VCC(电源正极)->NodeMCU 3.3V引脚。这里是一个关键点:虽然DHT11可以兼容5V电压,但ESP8266的GPIO引脚耐受电压是3.3V。如果将DHT11的VCC接至5V,而其DATA引脚输出高电平可能接近5V,这有可能损坏ESP8266的GPIO。因此,最安全的做法是统一使用3.3V供电。
- DHT11 GND(电源负极)->NodeMCU GND引脚。
- DHT11 DATA(数据引脚)->NodeMCU D5引脚(对应GPIO14)。选择D5引脚的原因在于,它所在的GPIO14是一个功能通用的引脚,且远离一些用于启动、烧录的特殊功能引脚(如GPIO0, GPIO2, GPIO15),减少了配置冲突的可能性。
3.2 分步搭建与焊接建议
- 规划布局:在面包板或洞洞板上,先规划好NodeMCU和DHT11的位置。尽量让连接线短而整齐,避免交叉。将DHT11的传感头部分伸出,不要被其他元件或板子遮挡,以确保它能接触到流动的空气。
- 固定主控板:将NodeMCU插入面包板,或使用排母焊接在洞洞板上。
- 连接电源:首先连接“地”(GND)和“电源”(3.3V)。用两根跳线分别将NodeMCU的GND和3.3V引脚引到面包板的负电源轨和正电源轨上。这样,DHT11的GND和VCC就可以直接从电源轨取电,使布线更清晰。
- 连接传感器:将DHT11插入面包板。用跳线将其VCC引脚连接到正电源轨(3.3V),GND引脚连接到负电源轨。最后,用一根跳线将其DATA引脚连接到NodeMCU的D5引脚。
- 添加上拉电阻(可选但推荐):如果你使用洞洞板追求长期稳定,或者读取数据时遇到问题,请在DHT11的DATA引脚和VCC引脚之间焊接一个10kΩ的电阻。在面包板上,只需将这个电阻跨接在数据线和电源线之间即可。
- 最终检查:连接USB线之前,务必再次核对所有连接:VCC是否接3.3V?GND是否共地?数据线是否接对?确认无误后再通电。
实操心得:我第一次搭建时,曾将DHT11的VCC误接至NodeMCU的VIN引脚(该引脚直接连接USB的5V)。虽然传感器能工作,但在长时间运行后ESP8266变得异常发热。后来才发现是5V供电导致芯片内部电平转换电路负担过重。改为3.3V供电后,发热问题立刻消失。所以,“统一3.3V供电”是ESP8266外接传感器时一个非常重要的安全原则。
4. 软件开发环境配置与核心库详解
硬件准备就绪后,我们需要在电脑上搭建编程环境,并理解将要使用的核心库。
4.1 Arduino IDE配置与板卡管理
Arduino IDE是完成本项目最便捷的工具。首先,去Arduino官网下载并安装最新版的IDE。安装完成后,需要添加对ESP8266开发板的支持。
- 打开Arduino IDE,进入
文件->首选项。 - 在“附加开发板管理器网址”一栏中,填入以下网址:
http://arduino.esp8266.com/stable/package_esp8266com_index.json。如果已有其他网址,用逗号隔开即可。 - 点击
确定保存。然后进入工具->开发板->开发板管理器...。 - 在搜索框中输入“esp8266”,找到“esp8266 by ESP8266 Community”,点击安装。这个过程需要下载一些核心文件和工具链,耗时可能较长,请保持网络通畅。
- 安装完成后,在
工具->开发板列表中,就能找到“NodeMCU 1.0 (ESP-12E Module)”等选项。选择它。
接下来需要对开发板进行具体配置。在工具菜单下:
Flash Size: 选择“4M (3M SPIFFS)”。这是NodeMCU常见的闪存配置。Upload Speed: 选择“115200”或“921600”。更高的上传速度可以缩短程序烧录时间。Port: 插入NodeMCU的USB线后,这里会出现对应的串口(如COM3, /dev/cu.usbserial-XXXX)。选择它。
4.2 核心库:DHT sensor library与ESP8266WebServer
本项目依赖两个至关重要的库,它们封装了底层复杂的通信协议,让我们用简单的函数调用就能完成传感器读取和网络服务创建。
DHT sensor library:由Adafruit公司维护,是Arduino社区读取DHT系列传感器的标准库。它负责按照严格的时序与DHT11进行单总线通信,并将读取到的原始字节数据转换为我们可以理解的温度和湿度浮点数。在Arduino IDE中,可以通过项目->加载库->管理库...,搜索“DHT sensor library”并安装。通常它会提示你同时安装“Adafruit Unified Sensor”这个依赖库,一并安装即可。
ESP8266WebServer库:这是ESP8266 Arduino核心自带的库,无需额外安装。它是我们构建微型Web服务器的基石。通过这个库,我们可以:
- 让ESP8266连接到一个现有的Wi-Fi网络(STA模式)。
- 或者让ESP8266自身作为一个Wi-Fi热点(AP模式)。
- 定义不同的URL路径(如“/”, “/temperature”),并绑定对应的处理函数。
- 在处理函数中,我们可以生成HTML字符串,当用户用浏览器访问这些路径时,ESP8266就会将这些HTML代码发送给浏览器,从而呈现出我们设计的网页界面。
理解这两个库的分工是关键:DHT库负责“感知”物理世界,WebServer库负责“连接”网络世界。我们的代码就是它们之间的桥梁和指挥官。
5. 代码逐行解析与Web服务器构建
下面,我将结合一个完整的、可运行的示例代码,详细解释每一部分的作用和编写逻辑。你可以将这段代码复制到Arduino IDE中,但更重要的是理解其背后的原理。
// 1. 引入必要的库 #include <ESP8266WiFi.h> // ESP8266核心Wi-Fi库 #include <ESP8266WebServer.h> // Web服务器库 #include <DHT.h> // DHT传感器库 // 2. 定义网络凭证和硬件引脚 const char* ssid = "Your_WiFi_SSID"; // 你的Wi-Fi名称 const char* password = "Your_WiFi_Pass"; // 你的Wi-Fi密码 #define DHTPIN D5 // NodeMCU的D5引脚连接DHT11数据线 #define DHTTYPE DHT11 // 指定传感器类型为DHT11 // 3. 初始化库对象 DHT dht(DHTPIN, DHTTYPE); // 初始化DHT传感器对象 ESP8266WebServer server(80); // 在80端口创建Web服务器对象 // 4. 全局变量,用于存储最新的传感器读数 float temperatureC = 0.0; float humidity = 0.0; unsigned long previousMillis = 0; // 用于定时读取传感器 const long interval = 2000; // 读取间隔,2秒(DHT11最小间隔) // 5. 网页HTML内容(一个非常简单的界面) const char index_html[] PROGMEM = R"rawliteral( <!DOCTYPE HTML><html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> body { font-family: Arial; text-align: center; margin: 40px; } .data { font-size: 2.5rem; font-weight: bold; margin: 20px 0; } .unit { font-size: 1rem; } .label { color: #555; } </style> </head> <body> <h1>ESP8266温湿度监测站</h1> <div> <p class="label">温度</p> <p class="data"><span id="temperatureC">%TEMPERATUREC%</span><span class="unit">°C</span></p> <p class="data"><span id="temperatureF">%TEMPERATUREF%</span><span class="unit">°F</span></p> </div> <div> <p class="label">湿度</p> <p class="data"><span id="humidity">%HUMIDITY%</span><span class="unit">%</span></p> </div> <p><small>数据更新时间: <span id="updateTime">%UPDATETIME%</span></small></p> </body> </html> )rawliteral"; // 6. 处理根目录“/”访问请求的函数 void handleRoot() { // 动态替换HTML模板中的占位符 String html = String(index_html); html.replace("%TEMPERATUREC%", String(temperatureC, 1)); // 保留一位小数 html.replace("%TEMPERATUREF%", String(temperatureC * 1.8 + 32, 1)); html.replace("%HUMIDITY%", String(humidity, 1)); // 获取当前时间并格式化 unsigned long currentMillis = millis(); int seconds = currentMillis / 1000; int minutes = seconds / 60; int hours = minutes / 60; char timeString[20]; sprintf(timeString, "%02d:%02d:%02d", hours % 24, minutes % 60, seconds % 60); html.replace("%UPDATETIME%", String(timeString)); // 将处理好的HTML发送给客户端浏览器 server.send(200, "text/html", html); } // 7. 处理“/data”路径的API请求,返回JSON格式的纯数据(用于未来扩展,如手机App) void handleData() { String json = "{"; json += "\"temperatureC\":" + String(temperatureC, 1) + ","; json += "\"temperatureF\":" + String(temperatureC * 1.8 + 32, 1) + ","; json += "\"humidity\":" + String(humidity, 1); json += "}"; server.send(200, "application/json", json); } // 8. 处理未知路径的请求(404错误) void handleNotFound() { server.send(404, "text/plain", "404: Not Found"); } // 9. 初始化设置,只运行一次 void setup() { Serial.begin(115200); // 启动串口通信,用于调试输出 delay(100); // 短暂延时,等待硬件稳定 dht.begin(); // 初始化DHT传感器 // 连接Wi-Fi WiFi.begin(ssid, password); Serial.print("Connecting to WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nConnected! IP address: "); Serial.println(WiFi.localIP()); // 打印ESP8266获取到的本地IP地址 // 设置服务器路由:当访问特定路径时,调用对应的处理函数 server.on("/", HTTP_GET, handleRoot); // 访问根目录,显示网页 server.on("/data", HTTP_GET, handleData); // 访问/data,获取JSON数据 server.onNotFound(handleNotFound); // 访问其他路径,返回404 server.begin(); // 启动Web服务器 Serial.println("HTTP server started"); } // 10. 主循环,不断重复执行 void loop() { server.handleClient(); // 必须持续调用,以处理来自客户端的网络请求 // 定时读取传感器数据,避免频繁读取导致DHT11响应不过来 unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; // 保存本次读取的时间点 // 读取温湿度。读取失败时,用上一次的有效值。 float newH = dht.readHumidity(); float newT = dht.readTemperature(); // 默认读取摄氏温度 // 检查读数是否有效(非NaN) if (!isnan(newT) && !isnan(newH)) { temperatureC = newT; humidity = newH; Serial.printf("Updated: %.1f°C, %.1f%%\n", temperatureC, humidity); } else { Serial.println("Failed to read from DHT sensor!"); } } }5.1 代码关键逻辑深度剖析
定时读取与非阻塞设计:这是代码中的一个核心技巧。loop()函数会以极快的速度循环执行。如果我们直接在loop里调用dht.readTemperature(),请求频率会远高于DHT11传感器2秒的响应能力,导致大量读取失败。因此,我们采用了非阻塞定时的方法。通过millis()函数获取设备开机后的毫秒数,每次成功读取后记录时间点previousMillis。在下次循环时,只有当当前时间currentMillis与上次记录的时间差超过设定的interval(2000毫秒)时,才执行下一次读取。这样既保证了按需读取,又不会阻塞网络服务等其他任务的执行。
Web服务器路由机制:ESP8266WebServer库的路由功能非常直观。server.on(“/”, HTTP_GET, handleRoot)这行代码注册了一个“路由规则”:当有客户端通过HTTP GET方法访问服务器的根路径“/”时,就自动调用我们编写的handleRoot函数。在这个函数里,我们生成了最终的HTML页面。同理,/data路径被映射到handleData函数,用于提供纯数据接口。这种设计实现了前后端分离的雏形:一个接口负责展示界面(/),一个接口提供数据(/data),为后续功能扩展(如自动刷新、图表绘制)打下了基础。
HTML模板与字符串处理:为了动态显示数据,我们没有将HTML写死,而是使用了“模板替换”的方法。在index_html字符串中,我们预先放置了像%TEMPERATUREC%这样的占位符。在handleRoot函数中,使用String.replace()方法,将这些占位符替换为最新的传感器数值字符串。这种方法比在代码中拼接复杂的HTML字符串要清晰、安全得多。PROGMEM关键字用于将常量字符串存储在Flash程序存储器中,而不是宝贵的RAM中,这对于内存有限的ESP8266来说是一个重要的优化手段。
6. 程序烧录、配置与首次访问
代码理解透彻后,就可以将其部署到硬件上了。
- 修改配置:在代码开头,将
Your_WiFi_SSID和Your_WiFi_Pass替换成你实际使用的2.4GHz Wi-Fi网络名称和密码。ESP8266不支持5GHz频段。 - 编译与上传:点击Arduino IDE左上角的“验证”(对勾图标)检查代码有无语法错误。确认无误后,点击“上传”(右箭头图标)。上传过程中,NodeMCU板上的LED可能会快速闪烁,这是正常现象。上传成功后,IDE底部状态栏会显示“上传完毕”。
- 查看IP地址:上传完成后,打开Arduino IDE的串口监视器(右上角的放大镜图标)。确保右下角的波特率设置为115200。然后按下NodeMCU上的RST(复位)按钮。你将在串口监视器中看到程序输出的日志信息。重点关注类似
Connected! IP address: 192.168.1.123这样的一行,这就是你的ESP8266在局域网中的IP地址。记下它。 - 访问Web界面:确保你的手机或电脑连接的是同一个Wi-Fi网络。然后打开浏览器,在地址栏输入上一步获取的IP地址,例如
http://192.168.1.123。按下回车,一个简洁的温湿度监测页面就应该呈现在你面前了!
实操心得:第一次访问时,页面可能加载缓慢或显示不全,这通常是ESP8266处理能力有限导致的,属于正常现象。刷新一下即可。如果完全无法访问,请回到串口监视器,检查Wi-Fi连接是否成功,以及IP地址是否打印正确。一个常见的错误是手机使用了移动数据网络,而非与ESP8266相同的Wi-Fi。
7. 系统优化与功能扩展思路
基础功能实现后,我们可以从稳定性、用户体验和功能层面进行优化和扩展。
7.1 稳定性优化:自动重连与看门狗
在实际部署中,Wi-Fi网络可能偶尔波动,程序也可能因未知原因“卡死”。我们需要增加 robustness(鲁棒性)。
- Wi-Fi自动重连:可以在
loop()函数中加入对WiFi.status()的检查。如果发现连接断开,则尝试重新连接。为了避免重连过程阻塞主循环,重连逻辑也应使用非阻塞的定时方式。void checkWiFiConnection() { if (WiFi.status() != WL_CONNECTED) { Serial.println(“WiFi连接丢失,尝试重连...”); WiFi.disconnect(); WiFi.begin(ssid, password); delay(2000); // 等待一下再检查 } } // 在loop()中定时调用此函数 - 软件看门狗:ESP8266 Arduino核心提供了
ESP.wdtFeed()函数来“喂狗”。可以在loop()循环的末尾调用它。如果程序跑飞,看门狗定时器超时,会自动重启芯片。更高级的用法是使用Ticker库定时喂狗。
7.2 用户体验优化:页面自动刷新与美化
当前的页面是静态的,需要手动刷新才能更新数据。我们可以通过简单的JavaScript实现自动刷新。
- Meta标签刷新:最简单的方法是在HTML的
<head>部分加入:<meta http-equiv=“refresh” content=“5”>,这会让浏览器每5秒刷新整个页面。但这种方式体验不佳,页面会闪烁。 - AJAX异步更新:更好的方法是使用JavaScript定时向服务器的
/data接口发起请求,获取JSON数据,然后只更新页面中显示数据的部分(DOM元素)。这需要在前端HTML中加入一些JS代码。例如:<script> setInterval(function() { fetch(‘/data’) .then(response => response.json()) .then(data => { document.getElementById(‘temperatureC’).innerText = data.temperatureC.toFixed(1); document.getElementById(‘humidity’).innerText = data.humidity.toFixed(1); // 更新时间显示... }); }, 2000); // 每2秒更新一次 </script> - 界面美化:可以利用Bootstrap、Chart.js等前端库来构建更美观、更专业的仪表盘界面,甚至绘制温湿度变化曲线图。这些库文件可以存放在ESP8266的SPIFFS文件系统中,通过Web服务器提供访问。
7.3 功能扩展:数据持久化与远程访问
- 本地数据记录:可以添加一个SD卡模块,或者利用ESP8266的SPIFFS(闪存文件系统),定期将温湿度数据连同时间戳保存为CSV或JSON文件。这样就能追溯历史数据,分析变化趋势。
- 接入智能家居平台:通过MQTT协议,将数据发布到本地的Home Assistant、Node-RED或者云端的阿里云、腾讯云IoT平台。这样就能实现更复杂的自动化联动,例如“当温度超过30度时,自动打开风扇”或“湿度低于40%时,发送手机通知”。
- OTA升级:配置Arduino OTA功能后,你就可以通过网络直接给ESP8266上传新程序,而无需再插拔USB线,这对于安装在隐蔽位置的设备来说简直是福音。
8. 常见问题排查与深度调试指南
即使按照步骤操作,你也可能会遇到一些问题。下面是我在多次项目中总结的排查清单。
8.1 传感器读数失败或为NaN
这是最常见的问题,现象是串口监视器不断打印“Failed to read from DHT sensor!”。
- 检查接线:这是首要步骤。确认VCC、GND、DATA三根线是否连接牢固,特别是DATA线是否接对了GPIO引脚。尝试换用其他GPIO口(如D2、D6),并在代码中相应修改
DHTPIN的定义。 - 检查供电:确保DHT11的VCC连接的是3.3V,而非5V。使用万用表测量3.3V引脚和GND之间的电压是否稳定。
- 添加上拉电阻:如果之前没加,在DATA线和3.3V之间连接一个4.7kΩ - 10kΩ的电阻。这是解决信号不稳定的最有效方法之一。
- 调整读取间隔:DHT11两次读取之间需要至少2秒的间隔。检查代码中的
interval是否小于2000毫秒。如果读取太频繁,传感器会无响应。 - 检查库版本:确保你安装的
DHT sensor library是最新版本。旧版本可能存在兼容性问题。
8.2 无法连接到Wi-Fi
串口监视器显示一直在打印“Connecting to WiFi…”,无法获得IP地址。
- 确认SSID和密码:大小写、特殊字符是否正确?Wi-Fi名称是否包含中文或特殊字符?建议先设置为一个简单的英文名称和纯数字密码进行测试。
- 检查网络频段:ESP8266只支持2.4GHzWi-Fi。确保你的路由器2.4GHz网络已开启,并且手机/电脑能连接上它。
- 检查路由器设置:有些路由器的“无线隔离”或“AP隔离”功能会阻止局域网内设备互访,需要关闭。确保DHCP服务正常,能为ESP8266分配IP。
- 信号强度:将ESP8266靠近路由器测试。信号太弱会导致连接不稳定。
8.3 能连Wi-Fi但无法访问网页
串口打印出了IP地址,但浏览器访问时提示“无法连接”或“超时”。
- 确认IP地址:再次核对串口打印的IP地址是否输入正确。
- 关闭防火墙:临时关闭电脑的防火墙和杀毒软件,测试是否是它们阻止了访问。
- 更换浏览器或设备:用手机浏览器试试,排除电脑浏览器缓存或插件问题。
- 检查端口占用:确保局域网内没有其他设备占用了80端口(可能性较小)。
- 查看串口日志:访问网页时,观察串口监视器是否有新的访问日志输出。如果没有,说明请求根本没到达ESP8266,问题出在网络层面;如果有日志但浏览器没反应,可能是ESP8266处理请求时卡死或崩溃了。
8.4 设备运行一段时间后死机或无响应
- 电源问题:这是首要怀疑对象。USB线过长或质量差、电脑USB口供电不足、移动电源输出不稳定,都可能导致ESP8266在Wi-Fi全功率工作时电压跌落而重启。建议使用5V/2A以上的手机充电头和短而粗的优质USB线供电。
- 内存泄漏:在
handleRoot等函数中,如果动态创建了大量String对象而没有及时释放,会导致内存耗尽。优化方法是使用char数组或String的保留空间功能,减少内存碎片。 - 看门狗超时:如果某段代码(如复杂的字符串处理、文件读写)执行时间过长,没有及时“喂狗”,看门狗定时器会触发复位。确保
loop()循环执行时间不要太长,或在耗时操作中插入yield()或ESP.wdtFeed()。
通过这个从硬件到软件、从原理到实操的完整流程,你应该已经拥有了一个稳定工作的物联网温湿度监测站。这个项目虽然小,但它涵盖了物联网开发的经典范式:感知(Sensor)-> 处理(MCU)-> 传输(Wi-Fi)-> 展示(Web)。以此为起点,你可以更换更精确的传感器(如DHT22、BME280),添加更多执行器(如继电器控制加湿器),或者将数据推送至云端进行大数据分析,探索物联网世界的无限可能。