ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于ESP8266与DHT11构建低成本物联网温湿度监测系统

基于ESP8266与DHT11构建低成本物联网温湿度监测系统 1. 项目缘起为什么需要随时随地查看温湿度几年前我接手了一个小项目需要监控一个偏远仓库的环境。当时最头疼的就是每次想知道仓库里的温湿度都得开车跑过去插上数据线连上电脑才能看到读数。费时费力不说遇到极端天气预警心里更是没底。后来ESP8266这颗芯片进入了我的视野它彻底改变了这种局面。这个项目就是教你如何用一块成本不到20块钱的ESP8266开发板搭配一个温湿度传感器构建一个可以让你在世界上任何一个有网络的地方用手机或电脑实时查看环境数据的系统。听起来是不是有点像智能家居的温湿度计没错原理相通但自己做的好处在于数据完全掌握在自己手里没有云端服务的延迟、隐私顾虑或订阅费用。你可以把它放在花房、鱼缸旁、地下室、设备间甚至老家父母的房间里随时掌握环境变化。ESP8266作为一款集成了Wi-Fi功能的微控制器是这类物联网IoT入门项目的绝佳选择它功耗低、价格便宜而且有非常成熟的开发社区支持。2. 核心硬件选型与电路连接要实现这个“随时随地查看”的功能我们需要一个能感知环境的“感官”传感器一个能处理数据并连接网络的“大脑”主控以及为它们供电的“血液”电源。2.1 主控芯片为什么是ESP8266在众多微控制器中我选择ESP8266核心原因就三个字性价比。它内置了完整的TCP/IP协议栈和Wi-Fi功能这意味着你不需要额外购买昂贵的Wi-Fi模块。常见的ESP-12F模组其核心就是ESP8266拥有4MB的Flash存储足以存放复杂的程序。对比传统的Arduino Uno以太网盾的方案ESP8266在成本、体积和功耗上都有巨大优势。对于持续运行的监测设备低功耗至关重要ESP8266在深度睡眠模式下电流可以低至20μA以下。市面上常见的开发板如NodeMCU、Wemos D1 mini都基于ESP8266。我强烈推荐Wemos D1 mini因为它板载了USB转串口芯片CH340无需额外购买下载器体积小巧引脚布局清晰对新手极其友好。它的价格通常在15元人民币左右是入门的不二之选。2.2 传感器DHT11 vs. DHT22 vs. SHT30温湿度传感器的选择决定了数据的精度和稳定性。这里我们分析最常见的三种DHT11入门首选性价比之王。价格通常在5元以内。它能测量20-80%RH的湿度精度±5%RH和0-50°C的温度精度±2°C。对于家庭室内环境监测、判断是否该开加湿器这种应用完全够用。它的通信协议是单总线Single-Bus只需要一根数据线接线简单。DHT22 (AM2302)精度升级版。价格比DHT11贵一倍左右约10-15元。测量范围更广湿度0-100%RH精度±2%RH温度-40~80°C精度±0.5°C。如果你的应用场景对精度要求较高比如需要精确控制发酵环境、或是科研记录DHT22是更好的选择。它同样使用单总线协议。SHT30工业级精度I2C接口。价格更高约20-30元。它是数字传感器通过I2C总线通信抗干扰能力更强精度和长期稳定性远超前两者湿度±2%RH温度±0.2°C。如果你的项目预算充足且对数据可靠性有严苛要求例如精密仪器环境监控SHT30是专业之选。注意DHT系列传感器对读取间隔有要求两次读取之间需要至少2秒的间隔否则可能读取失败。这是由其内部温湿度转换和校准算法决定的。对于绝大多数家庭和爱好者项目DHT11足以胜任。本项目将以DHT11为例进行讲解。2.3 电路连接五分钟搞定连接非常简单只需要三根杜邦线母对母。我们以Wemos D1 mini开发板为例Wemos D1 mini 引脚DHT11 引脚说明3.3VVCC (Pin 1)供电正极。务必接3.3V接5V会烧毁传感器GNDGND (Pin 4)供电负极。D2 (GPIO4)DATA (Pin 2)数据引脚。你可以选择其他数字IO口如D1、D5等代码中相应修改即可。DHT11的Pin 3是NC空脚不用连接。为了信号稳定建议在DHT11的VCC和DATA引脚之间连接一个4.7kΩ - 10kΩ的上拉电阻。很多DHT11模块已经集成了这个电阻如果你购买的是模块通常不需要额外添加如果购买的是单独的传感器则需要自己添加。连接完成后你的硬件部分就准备好了。整个系统可以由一个5V/1A的手机充电器通过Wemos D1 mini的Micro USB口供电非常方便。3. 软件开发环境搭建与核心库硬件搭好了接下来是“注入灵魂”的步骤——编写并上传程序。我们将使用Arduino IDE因为它对新手最友好库生态丰富。3.1 安装Arduino IDE与ESP8266开发板支持首先去Arduino官网下载并安装最新版的Arduino IDE。安装完成后打开IDE进入文件-首选项。在“附加开发板管理器网址”中填入以下地址http://arduino.esp8266.com/stable/package_esp8266com_index.json如果已有其他网址用逗号隔开即可。然后打开工具-开发板-开发板管理器。在搜索框中输入“esp8266”找到并安装“esp8266 by ESP8266 Community”。安装过程可能需要几分钟取决于你的网络速度。安装完成后在工具-开发板选项中就能选择“WeMos D1 R2 mini”对应Wemos D1 mini或其他你使用的ESP8266板子了。3.2 安装必要的库我们需要两个库来简化开发DHT sensor library用于驱动DHT11传感器。Adafruit Unified Sensor前一个库的依赖库。在Arduino IDE中点击项目-加载库-管理库...。在库管理器中分别搜索“DHT sensor library”和“Adafruit Unified Sensor”找到由Adafruit发布的版本进行安装。3.3 代码逻辑深度解析程序的核心逻辑是一个循环读取传感器数据 - 通过Wi-Fi连接网络 - 将数据发送到某个地方供我们访问。这里我们介绍两种最主流、最实用的方案通过HTTP请求发送到云端API以及构建一个简单的Web服务器。方案一HTTP推送至云端API以IFTTT Webhooks为例这种方案适合只想在手机收到通知或在云端表格简单记录数据的场景。我们利用IFTTTIf This Then That这个免费自动化平台。首先你需要注册一个IFTTT账号然后创建一个新的Applet。This选择“Webhooks”服务触发条件选择“Receive a web request”。设置一个事件名例如esp8266_temp_humidity。That可以选择“Google Sheets”来添加一行数据或者选择“Notifications”在手机APP上发送通知。这里以通知为例消息内容可以设置为温度: {{Value1}}°C 湿度: {{Value2}}%。创建完成后去Webhooks的设置页面找到你的专属URL形如https://maker.ifttt.com/trigger/{event}/with/key/{your_key}。下面是核心代码片段#include ESP8266WiFi.h #include ESP8266HTTPClient.h #include WiFiClient.h #include DHT.h #define DHTPIN D2 // 连接DHT11数据脚的GPIO #define DHTTYPE DHT11 // 传感器类型 DHT dht(DHTPIN, DHTTYPE); const char* ssid 你的Wi-Fi名称; const char* password 你的Wi-Fi密码; const char* iftttWebhookKey 你的IFTTT Webhooks Key; const char* eventName esp8266_temp_humidity; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() ! WL_CONNECTED) { delay(500); Serial.print(.); } Serial.println(WiFi连接成功!); dht.begin(); } void loop() { // 读取间隔至少2秒 delay(10000); // 等待10秒避免频繁触发IFTTT限制 float humidity dht.readHumidity(); float temperature dht.readTemperature(); // 读取摄氏温度 // 检查读取是否成功 if (isnan(humidity) || isnan(temperature)) { Serial.println(读取DHT11失败!); return; } Serial.printf(湿度: %.1f%% 温度: %.1f°C\n, humidity, temperature); // 构建IFTTT Webhooks请求URL String url http://maker.ifttt.com/trigger/; url eventName; url /with/key/; url iftttWebhookKey; url ?value1; url String(temperature); url value2; url String(humidity); WiFiClient client; HTTPClient http; http.begin(client, url); // 指定客户端和URL int httpCode http.GET(); // 发送GET请求 if (httpCode 0) { Serial.printf(HTTP请求成功代码: %d\n, httpCode); } else { Serial.printf(HTTP请求失败错误: %s\n, http.errorToString(httpCode).c_str()); } http.end(); }这段代码的关键点与避坑指南连接稳定性WiFi.begin()后的循环等待是必要的。在实际环境中Wi-Fi信号可能不稳定可以增加重试次数判断。数据有效性isnan()函数用于判断读取值是否为“非数字”NaN这是检测DHT11通信失败的重要手段。HTTP请求我们使用了HTTPClient和WiFiClient。注意http.begin(client, url)的用法这是新版本库推荐的方式。务必检查httpCode200表示成功其他代码代表各种错误如404未找到500服务器错误等。频率限制IFTTT免费账户对Webhooks调用有频率限制大概每分钟几次所以loop()中的delay不能太短这里设为10秒是安全的。方案二ESP8266自建Web服务器数据完全本地化如果你希望有一个专属的网页来显示数据并且不想依赖任何第三方服务那么让ESP8266自己作为一个微型Web服务器是最佳选择。你可以在同一个局域网内通过浏览器访问ESP8266的IP地址来查看数据。#include ESP8266WiFi.h #include ESP8266WebServer.h #include DHT.h #define DHTPIN D2 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); const char* ssid 你的Wi-Fi名称; const char* password 你的Wi-Fi密码; ESP8266WebServer server(80); // 在80端口创建服务器对象 float lastHumidity 0; float lastTemperature 0; unsigned long lastReadTime 0; const unsigned long readInterval 2000; // 传感器读取间隔2秒 void handleRoot() { // 动态生成一个简单的HTML页面 String html !DOCTYPE htmlhtmlheadmeta charsetUTF-8; html meta http-equivrefresh content5; // 每5秒自动刷新页面 html titleESP8266温湿度监测/title/headbody; html h1环境监测/h1; html pstrong温度/strong String(lastTemperature) °C/p; html pstrong湿度/strong String(lastHumidity) %/p; html pem最后更新时间: String(millis() / 1000) 秒前/em/p; html /body/html; server.send(200, text/html; charsetutf-8, html); // 发送HTML响应 } void handleData() { // 提供一个纯JSON数据的API接口供其他程序如手机APP调用 String json {; json \temperature\: String(lastTemperature) ,; json \humidity\: String(lastHumidity); json }; server.send(200, application/json, json); } void setup() { Serial.begin(115200); dht.begin(); WiFi.begin(ssid, password); while (WiFi.status() ! WL_CONNECTED) { delay(500); Serial.print(.); } Serial.println(); Serial.print(连接成功! IP地址: ); Serial.println(WiFi.localIP()); // 打印ESP8266获取到的局域网IP // 绑定URL路径对应的处理函数 server.on(/, handleRoot); // 访问根目录显示网页 server.on(/data, handleData); // 访问/data获取JSON数据 server.begin(); // 启动Web服务器 Serial.println(HTTP服务器已启动); } void loop() { server.handleClient(); // 处理来自客户端的请求 // 定时读取传感器避免在handleClient中长时间阻塞 unsigned long currentMillis millis(); if (currentMillis - lastReadTime readInterval) { lastReadTime currentMillis; float h dht.readHumidity(); float t dht.readTemperature(); if (!isnan(h) !isnan(t)) { lastHumidity h; lastTemperature t; Serial.printf(数据已更新: %.1f°C, %.1f%%\n, t, h); } } }这种方案的优点与实操细节完全自主数据不经过任何第三方服务器隐私和安全有保障。实时性高局域网内访问延迟极低。功能可扩展你可以在网页上添加图表如使用Chart.js、控制按钮如控制一个继电器等。IP地址获取程序启动后在串口监视器波特率115200中会打印出类似IP地址: 192.168.1.100的信息。在手机或电脑浏览器中输入这个IP地址即可访问。自动刷新HTML中的meta http-equivrefresh content5实现了页面每5秒自动刷新模拟了实时更新的效果。对于更优雅的“无刷新”更新需要用到AJAX技术这属于进阶内容。并发处理server.handleClient()需要被频繁调用它负责检查并处理新的网络连接和请求。因此在loop()中不能有长时间的delay()否则服务器会无响应。我们采用millis()进行非阻塞的定时读取是标准的物联网编程实践。4. 烧录程序与首次配置代码编写完成后就可以上传到ESP8266了。用Micro USB数据线连接Wemos D1 mini和电脑。在Arduino IDE的工具菜单中确认以下设置开发板WeMos D1 R2 miniUpload Speed921600这个波特率上传最快如果失败可以尝试115200CPU Frequency80 MHzFlash Size4M (3M SPIFFS)对于我们的程序绰绰有余Port选择对应的串口在Windows设备管理器中查看通常是COMx在macOS/Linux上是/dev/cu.usbserial-xxx。点击左上角的“上传”按钮向右的箭头。首次上传可能会比较慢因为需要编译整个ESP8266核心库。上传过程中开发板上的LED可能会快速闪烁这是正常现象。上传成功后打开工具-串口监视器将右下角的波特率设置为115200。然后按一下开发板上的RST复位按钮。你将在串口监视器中看到Wi-Fi连接过程和打印的IP地址。踩坑实录a fatal esptool.py error occurred: failed to connect to esp8266这是新手最常遇到的错误意思是esptool.py工具无法连接到ESP8266。请按以下步骤排查检查驱动确保CH340或CP2102取决于你的板子USB转串口驱动已正确安装。在设备管理器中查看端口是否出现且无感叹号。检查端口在Arduino IDE中选择的端口是否正确。手动进入下载模式ESP8266需要处于下载模式才能烧录。对于Wemos D1 mini通常在上传时自动控制。如果失败可以尝试手动操作先按住板上的FLASH按钮或BOOT按钮不放再按一下RST按钮然后松开RST最后松开FLASH按钮。此时再尝试上传。更换数据线有些数据线只能充电不能传输数据。务必使用可靠的数据线。降低上传波特率在工具-Upload Speed中将921600改为115200或57600再试。5. 实现“从任何地方访问”内网穿透方案二构建的Web服务器只能在局域网内访问。要实现标题所说的“from anywhere”就需要内网穿透技术。简单说就是让公网上的设备能找到你家里局域网中的ESP8266。对于个人项目最经济实用的方法是使用免费的云服务器反向代理或者使用现成的内网穿透服务如花生壳、Ngrok等。这里以使用Ngrok为例因为它配置极其简单。去Ngrok官网注册一个免费账户。根据你的电脑操作系统Windows/macOS/Linux下载对应的Ngrok客户端。在官网获取你的Authtoken。在命令行中运行ngrok authtoken 你的token进行认证。运行命令启动隧道ngrok http 80这里的80是ESP8266 Web服务器运行的端口我们在代码中ESP8266WebServer server(80)设置了80端口。运行后Ngrok会显示一个转发地址比如https://abc123.ngrok.io。这个地址就是你的ESP8266 Web服务器在公网上的临时入口。在任何能上网的设备浏览器中输入这个地址就能访问到你的温湿度监测页面了。重要提示免费版的Ngrok隧道地址每次重启都会变化且有限制。对于长期稳定的需求可以考虑购买一个域名并配置DNS服务。租用一台最基础的云服务器如腾讯云/阿里云轻量应用服务器月费约20-30元。在云服务器上安装并配置Nginx反向代理将你的域名指向云服务器IP再由Nginx将请求转发到Ngrok提供的地址或者使用更稳定的穿透工具如frp。6. 功耗优化与长期部署建议如果你希望这个设备能用电池供电运行数月那么功耗优化是必须考虑的。ESP8266在正常工作模式下Wi-Fi开启电流消耗在70mA左右这对于电池来说是巨大的负担。核心策略深度睡眠Deep Sleep让ESP8266绝大部分时间处于深度睡眠状态只有需要测量和发送数据时才被唤醒。在深度睡眠下电流可以降至20μA以下。硬件修改需要将ESP8266的GPIO16 (D0)引脚与RST复位引脚用导线连接起来。这样当芯片从内部定时器唤醒时GPIO16输出的低电平会触发RST从而实现重启。代码修改以HTTP推送方案为例#include ESP8266WiFi.h #include ESP8266HTTPClient.h #include WiFiClient.h #include DHT.h #define DHTPIN D2 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); const char* ssid 你的Wi-Fi名称; const char* password 你的Wi-Fi密码; void setup() { Serial.begin(115200); Serial.println(从深度睡眠中唤醒); // 连接Wi-Fi和读取传感器数据的代码... // (与之前HTTP方案的代码类似这里省略) // 数据发送完成后进入深度睡眠 Serial.println(准备进入深度睡眠); ESP.deepSleep(30e6); // 睡眠30秒 (30,000,000 微秒) // 注意执行完deepSleep后程序会停止芯片重启后从setup()重新开始 } void loop() { // 由于使用了深度睡眠loop()函数永远不会被执行到。 }部署建议电源对于长期监测建议使用18650锂电池充电保护板供电或者使用太阳能板电池的方案。外壳使用3D打印或防水接线盒为设备制作一个外壳保护电路免受灰尘和潮气影响。天线如果部署位置信号弱可以考虑使用带有外置天线接口的ESP8266模块如ESP-07S并连接一根小天线。数据备份重要的监测数据除了实时查看最好能定期保存。可以在方案一中结合IFTTT的Google Sheets功能自动记录或者自己搭建一个简单的数据库如InfluxDB来存储历史数据用于分析和绘制趋势图。这个项目从硬件连接到软件编程再到网络部署和优化涵盖了一个完整物联网原型开发的核心流程。它不仅仅是一个温湿度计更是一个理解物联网如何工作的绝佳切入点。当你成功在手机上看到来自自己设备的实时数据时那种成就感是无可替代的。希望这份详细的指南能帮你少走弯路顺利搭建起属于自己的第一个物联网监测点。
返回列表