把 DHT11 模块的信号脚接到 ESP32 的 GPIO4,OLED 的 SDA 和 SCL 分别接 GPIO21 和 GPIO22,两个模块都从 3V3 脚供电,再烧录一个用 Adafruit DHT 和 SSD1306 库的 sketch 就完成了。整个电路都跑 3.3V,不需要外加任何电阻——3 针版 DHT11 模块的上拉电阻(pull-up)已经做在板上。
这个 ESP32 温湿度监测器需要哪些零件?
NodeMCU-32S ESP32 开发板是整个项目的大脑:自带 WiFi、3.3V 逻辑电平,对第一次上手的人也很友好。它用的是 micro-USB 而不是 USB-C,所以请准备一条 micro-USB 数据线。板上的 USB 芯片是 CP2102,电脑要装 Silicon Labs CP210x 驱动——不是其他板子常用的 CH340 驱动。
如果装了驱动还是看不到 COM 口,先照我们的 ESP32 无法识别排查指南一步步检查,别急着怪代码。
零件清单
DHT11 和 OLED 要怎么接到 ESP32?
0.96 寸 OLED 走 I2C,而 ESP32 在 Arduino 里的默认 I2C 引脚就是 GPIO21(SDA)和 GPIO22(SCL),不需要重新映射。DHT11 用自己的单总线协议,任何空闲 GPIO 都行;我们用 GPIO4。
| 模块引脚 | ESP32 引脚 | 说明 |
|---|---|---|
| OLED GND | GND | 这块屏的第一个 pin——认准丝印 |
| OLED VCC | 3V3 | 第二个 pin,不是第一个 |
| OLED SCL | GPIO22 | Arduino 默认 I2C 时钟 |
| OLED SDA | GPIO21 | Arduino 默认 I2C 数据 |
| DHT11 S(信号) | GPIO4 | 任何空闲 GPIO 都行;sketch 用 4 |
| DHT11 VCC | 3V3 | 模块支持 3.3–5.5V |
| DHT11 GND | GND | — |
插线之前先提醒一件事:这块 OLED 的排针从左到右是 GND、VCC、SCL、SDA——跟很多模块 VCC 排第一的顺序正好相反。凭习惯把红线插到第一个 pin,等于把电源反接到屏幕上,这正是这类 OLED 烧坏的经典死法。永远认板上的丝印,别照别人照片里的线色接。

接下来是好消息:大多数 DHT11 教程叫你加的 10k 上拉电阻,这里直接省掉。那是给 4 针裸传感器的做法;我们卖的是 3 针模块版,上拉电阻已经做在那块小黑色 PCB 上。接好 S、VCC、GND 三条线,接线就完成了——而且全程 3.3V,也不需要任何电平转换。
要装哪些库、代码怎么写?
两个模块都由 Adafruit 的库来驱动,直接在 Arduino IDE 的 Library Manager(Sketch → Include Library → Manage Libraries)安装。搜 Adafruit 的 DHT sensor library,弹窗问要不要一并安装 Adafruit Unified Sensor 依赖时选同意,然后再装 Adafruit SSD1306,它会用同样方式带上 Adafruit GFX。
Sketch 用 millis() 而不是 delay(),每两秒读一次,loop 不会被卡住。Aosong 的 DHT11 数据手册规定采样周期至少两秒,Adafruit 库内部也强制同样的两秒下限——读得再快,拿到的也只是缓存值或失败值。两秒本来就是这颗传感器自己的节奏——而且同一份 sketch 不用改就能跑 DHT22。
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C // 屏幕一直黑就跑一次 I2C 扫描
#define DHTPIN 4 // DHT11 模块的 S 脚
#define DHTTYPE DHT11 // 买的是 DHT22 就改成 DHT22
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
DHT dht(DHTPIN, DHTTYPE);
const unsigned long READ_INTERVAL = 2000; // DHT11 两次读取之间至少隔 2 秒
unsigned long lastRead = 0;
void setup() {
Serial.begin(115200);
dht.begin();
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
Serial.println("SSD1306 not found - check wiring and address");
while (true) delay(10); // 卡在这里,没东西可显示
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.println("DHT11 monitor ready");
display.display();
}
void loop() {
if (millis() - lastRead < READ_INTERVAL) return; // 非阻塞等待
lastRead = millis();
float h = dht.readHumidity();
float t = dht.readTemperature(); // 摄氏度
display.clearDisplay();
display.setCursor(0, 0);
if (isnan(h) || isnan(t)) {
display.setTextSize(1);
display.println("Sensor read failed");
display.println("Check DHT11 wiring");
} else {
display.setTextSize(1);
display.println("Temperature:");
display.setTextSize(2);
display.print(t, 1);
display.println(" C");
display.setTextSize(1);
display.println("Humidity:");
display.setTextSize(2);
display.print(h, 1);
display.println(" %");
}
display.display();
}
OLED 地址是 0x3D 而不是 0x3C 怎么办?
SSD1306 这类屏幕只会落在两个 I2C 地址之一——0x3C 或 0x3D,由控制器的 SA0 地址位决定。0x3C 是最常见的默认值,sketch 里用的也是它。
屏幕不亮的话别猜——直接扫。ESP32 Arduino core 自带扫描器:File → Examples → Wire → WireScan,烧录后打开 Serial Monitor,它会把找到的每个 I2C 地址都打印出来。扫到什么就把什么填进 OLED_ADDR;一个都扫不到,那是接线问题,不是地址问题。
该买 DHT11 还是 DHT22?
DHT11 和 DHT22 是同一颗传感器的两个版本——我们的商品页两种都有——老实说各有各的用武之地。下表数据来自 Adafruit 的 DHT 指南;采样率则按 Aosong 官方 DHT11 数据手册,它比 Adafruit 写的 1 Hz 更严格。
| 规格 | DHT11 | DHT22 |
|---|---|---|
| 温度范围 | 0–50°C | −40 到 80°C |
| 温度精度 | ±2°C | ±0.5°C |
| 湿度范围 | 20–80% RH | 0–100% RH |
| 湿度精度 | ±5% | ±2–5% |
| 最高采样率 | 0.5 Hz(每 2 秒一次) | 0.5 Hz(每 2 秒一次) |
在马来西亚的房间、办公室或种植箱里,DHT11 的 0–50°C 量程和 ±2°C 精度完全够用。要测 0°C 以下(比如记录冰箱温度)、湿度超出 20–80%,或者像孵化箱那样需要更高精度,就选 DHT22。代码里唯一要改的是 #define DHTTYPE DHT22。
为什么屏幕全黑或读数是 “nan”?
nan(not a number)表示 DHT 库去问了传感器,却没有得到回应。按顺序检查三样:S 线是不是真的接在 GPIO4 而且插紧了,DHTTYPE 是否跟手上的传感器一致(把 DHT11 当 DHT22 读一定失败),以及 VCC/GND 有没有接到 3V3 和 GND。抄来的代码也常常读得太快——两次读取之间至少留两秒。
传感器正常、OLED 却全黑,几乎都是 I2C 那边的问题:SDA 和 SCL 接反、OLED_ADDR 填错,或者在那个顺序反转的排针上把 GND/VCC 插反了。先跑 WireScan——十秒钟就能告诉你屏幕活不活、住在哪个地址。

读数跟冷气遥控器差个 1–2°C 也不算故障——这在 DHT11 的 ±2°C 规格之内。
可以用 Arduino Uno 代替 ESP32 吗?
Arduino Uno 用同样三个库就能跑这个项目,只需改引脚:OLED 的 SDA 接 A4、SCL 接 A5,DHT11 信号接数字 pin 2(记得更新 DHTPIN)。两个模块都从 Uno 的 5V 脚供电——DHT11 模块支持 3.3–5.5V,而这块 OLED 模块板上自带稳压,所以经典的 Uno OLED 接法都是直接喂 5V。
你失去的是 WiFi:Uno 能在本地显示读数,但永远没办法把数据发到你的手机。如果最终目标是联网气象站,一开始就上 ESP32——我们的 ESP32、ESP8266 和 Uno 对比讲清楚了每块板各自适合什么场景。
真实客户最常犯的错误
代价最高的一种,是凭肌肉记忆把 OLED 的红线插到第一个 pin。在这块屏上,那等于把 VCC 接到 GND 脚,电源反接可以当场烧掉模块——这是整个项目里唯一一个硬件不会原谅你的错误。
其次是拿着 4 针裸传感器的接线图来接 3 针模块:到处找那个不存在的第四个 pin、加了根本不需要的上拉电阻,或者只认图里的线色、不认模块上印的 S、VCC、GND。永远以模块自己的丝印为准。
软件方面,最常见的坑是贴来的代码里留着 DHTTYPE DHT22,让一颗好好的 DHT11 永远返回 nan。还有不少人第一步就卡住:用了只能充电、不能传数据的 micro-USB 线,板子有电却怎么都上传不了。

FAQ
DHT11 能测冰箱那样的零下温度吗?
不能。DHT11 的量程是 0–50°C,到冰点就到底了。要记录冰箱或冷冻室温度,请选 DHT22 版本,它可以测到 −40°C——接线和 sketch 都一样,只改一行代码。
DHT11 需要外加 10k 电阻吗?
用我们的模块不需要。3 针 DHT11 模块的上拉电阻已经做在 PCB 上,三条线直接接 ESP32 就行。只有 4 针裸传感器才需要外接上拉电阻。
代码上传成功了,为什么 OLED 什么都不显示?
通常是 I2C 地址或接线的问题。跑一次 ESP32 core 自带的 WireScan 例程:如果打印出 0x3D,就把 OLED_ADDR 改过来;如果什么都扫不到,就重新检查 SDA 在 GPIO21、SCL 在 GPIO22,以及 GND 和 VCC 有没有按这块屏 GND 在前的顺序接。
这个项目可以用 power bank 供电吗?
可以——整个电路耗电很小,power bank 插到 micro-USB 口就能随身带着走。有些 power bank 遇到轻负载会自动断电;我们的 ESP32 供电方案指南讲了这个问题和更长期的供电选择。
这个项目需要面包板吗?
不需要。ESP32 开发板、DHT11 模块和 OLED 都自带公排针,七条母对母 jumper 线就能全部接好。想装得更整齐、或以后打算加更多传感器,才需要考虑面包板。
最后更新:2026年8月。有问题?WhatsApp 联系我们。



NodeMCU ESP32 Wi-Fi + Bluetooth Development Board CH340/CP2012 - For IOT Project - ESP-32(CP2102)
DHT 11 DHT 22 Temperature and Humidity Sensor DHT22 High Sensitivity Sensor DHT11 For Aduino IOT - DHT11 SENSOR
0.96‘ OLED Display Module Blue White Screen I2C IIC Serial 128X64 LCD Display Board - 0.96' OLED WHITE
40pcs Dupont Wire 10cm 20cm 30cm for Breadboard DIY Experiment Jumper Wire Breadboard wire - DUPONT WIRE F-F 20CM