《ESP32 入門》NodeMCU-32S 結合 DHT11溫濕度感測器+LCD
上一篇我們學會了用 ESP32 驅動 1602 LCD 顯示文字。這篇續篇要帶你接上 DHT11 溫濕度感測器,先把數據印在 Serial Monitor 上確認感測器有正常運作,再進一步把溫濕度顯示到 LCD 螢幕上。
上一篇我們學會了用 ESP32 驅動 1602 LCD 顯示文字。這篇續篇要帶你接上 DHT11 溫濕度感測器,先把數據印在 Serial Monitor 上確認感測器有正常運作,再進一步把溫濕度顯示到 LCD 螢幕上。
建議大家先回上一篇,了解一下LCD的用法哦!

這篇教學你需要的材料
除了上一篇已經準備好的 ESP32 + 1602 LCD 之外,你還需要:
| 材料 | 數量 | 說明 |
|---|---|---|
| DHT11 溫濕度感測器模組 | 1 | 建議買三腳已焊好電阻的模組版本 |
| 杜邦線(母對母) | 3 條 | 接感測器用 |
💡 DHT11 有兩種版本:模組版(3 腳):藍色小板子上已經焊好上拉電阻,拿到就能用,推薦初學者購買。裸裝版(4 腳):需要自己外接一顆 10KΩ 上拉電阻在 DATA 和 VCC 之間,否則讀取容易失敗。
這篇教學以 3 腳模組版 為例。



認識 DHT11
DHT11 是一顆數位溫濕度感測器,價格便宜、使用簡單,非常適合入門練習。
基本規格
| 項目 | 規格 |
|---|---|
| 溫度範圍 | 0°C ~ 50°C |
| 溫度精度 | ±2°C |
| 濕度範圍 | 20% ~ 80% RH |
| 濕度精度 | ±5% RH |
| 取樣速率 | 每秒 1 次 |
| 工作電壓 | 3.3V ~ 5V |
DHT11 的精度不算高,不適合用在需要精準量測的場合。但拿來做天氣小站、環境監控練習專案已經非常夠用。如果之後需要更高精度,可以升級到 DHT22 或 SHT3X 系列。
腳位說明(3 腳模組版)
正面(有格柵那面朝你)
+----------+
| DHT11 |
| 模組 |
+----------+
| | |
VCC DATA GND
(+) (out) (-)
⚠️ 注意: 不同廠商的模組腳位順序可能不同!拿到手請先看板子上的絲印標示(通常會印+、out、-或VCC、DATA、GND),不要死記順序。
第一步:安裝 DHT 函式庫
- 打開 Arduino IDE
- 到「函式庫管理員」(左邊書本圖示)
- 搜尋
DHT sensor library - 安裝作者是 Adafruit 的那個
- 跳出提示問你要不要安裝相依套件(Adafruit Unified Sensor),選「全部安裝」
這樣就會一次裝好兩個必要的函式庫。

第二步:接線
現在幫我們的ESP32 上要接兩個裝置,LCD和DHT11:
DHT11 感測器:
| DHT11 模組 | NodeMCU-32S |
|---|---|
| VCC (+) | 3.3V |
| DATA (out) | GPIO 4 |
| GND (-) | GND |
1602 LCD(I2C):
| LCD I2C 模組 | NodeMCU-32S |
|---|---|
| GND | GND |
| VCC | VIN (5V) |
| SDA | GPIO 21 |
| SCL | GPIO 22 |
NodeMCU-32S
+--------------+
| |
| 3.3V ------|----- DHT11 VCC
| GPIO 4 -----|----- DHT11 DATA
| |
| VIN ------|----- LCD VCC
| GPIO 21 -----|----- LCD SDA
| GPIO 22 -----|----- LCD SCL
| |
| GND ------|----- DHT11 GND
| \------|----- LCD GND
| |
+--------------+
💡 GND 可以共用,兩個裝置的 GND 都接到 ESP32 的 GND 腳位。如果 GND 腳位不夠,可以用麵包板或杜邦線串接。

第三步:用 Serial Monitor 讀取溫濕度
在接上 LCD 之前,我們先把溫濕度數據印在 Serial Monitor 上。這是一個很重要的除錯習慣:先用 Serial 確認資料正確,再接到其他輸出裝置。這樣如果出問題,你可以馬上判斷是感測器的問題還是顯示的問題。
程式碼
#include <DHT.h> // 引入 DHT 感測器函式庫
// === 設定區 ===
#define DHTPIN 4 // DHT11 的 DATA 腳接到 GPIO 4
#define DHTTYPE DHT11 // 指定感測器型號為 DHT11
// 如果你用的是 DHT22,改成 DHT22 即可
// 建立 DHT 物件
DHT dht(DHTPIN, DHTTYPE);
void setup() {
// 初始化序列埠,鮑率設定 115200
Serial.begin(115200);
// 初始化 DHT 感測器
dht.begin();
// 等待 2 秒讓感測器穩定
// DHT11 剛通電時需要一點時間才能正常讀取
delay(2000);
Serial.println("=== DHT11 溫濕度感測器測試 ===");
Serial.println();
}
void loop() {
// 讀取濕度(回傳值是百分比 %)
float humidity = dht.readHumidity();
// 讀取溫度(預設是攝氏 °C)
float temperature = dht.readTemperature();
// 檢查讀取是否成功
// isnan() = is Not A Number,讀取失敗時會回傳 NaN
if (isnan(humidity) || isnan(temperature)) {
Serial.println("讀取失敗!請檢查接線和感測器");
delay(2000);
return; // 跳過這次,等下一輪再試
}
// 印出溫度
Serial.print("溫度:");
Serial.print(temperature, 1); // 小數點後 1 位
Serial.print(" °C");
// 印出濕度
Serial.print(" | 濕度:");
Serial.print(humidity, 1);
Serial.println(" %");
// 等 2 秒再讀下一次
// DHT11 的取樣速率是每秒 1 次,建議間隔至少 2 秒
delay(2000);
}
上傳與查看結果
- 開發板選 Nodemcu-32s,選好 COM Port
- 上傳程式
- 打開 Serial Monitor,鮑率設
115200
你應該會看到每 2 秒更新一次的溫濕度資料:
=== DHT11 溫濕度感測器測試 ===
溫度:26.0 °C | 濕度:65.0 %
溫度:26.0 °C | 濕度:64.0 %
溫度:27.0 °C | 濕度:63.0 %

🔧 如果一直顯示「讀取失敗」:檢查 DATA 線有沒有確實接到 GPIO 4確認模組版本的腳位順序(看絲印!)試試把 VCC 改接 5V(VIN)確認函式庫有正確安裝(兩個都要裝)
💡 你可能注意到 DHT11 的數值都是整數(例如 26.0、27.0),不會出現 26.3 這種值。這是正常的,DHT11 的解析度就是 1°C / 1%。想要小數精度的話需要升級到 DHT22。
第四步:配合 LCD,同時顯示在螢幕和 Serial
目前確定我們可以從DHT11讀到正確的溫濕度了,那接下來就要把溫濕度顯示在LCD上囉。
完整程式碼
#include <Wire.h> // I2C 通訊(LCD 需要)
#include <LiquidCrystal_I2C.h> // LCD 控制函式庫
#include <DHT.h> // DHT 感測器函式庫
// === 設定區 ===
#define DHTPIN 4 // DHT11 DATA 腳接 GPIO 4
#define DHTTYPE DHT11 // 感測器型號
// 建立物件
LiquidCrystal_I2C lcd(0x27, 16, 2); // LCD 位址 0x27(你的可能是 0x3F)
DHT dht(DHTPIN, DHTTYPE);
void setup() {
// 初始化序列埠(方便同時在電腦上看數據)
Serial.begin(115200);
// 初始化 LCD
lcd.init();
lcd.backlight();
// 初始化 DHT
dht.begin();
// 開機畫面
lcd.setCursor(0, 0);
lcd.print("DHT11 Sensor");
lcd.setCursor(0, 1);
lcd.print("Starting...");
Serial.println("=== DHT11 + LCD 溫濕度顯示器 ===");
Serial.println();
delay(2000); // 等感測器穩定
lcd.clear(); // 清除開機畫面,準備顯示數據
}
void loop() {
// 讀取溫濕度
float temp = dht.readTemperature();
float humi = dht.readHumidity();
// 檢查讀取是否成功
if (isnan(temp) || isnan(humi)) {
// --- 錯誤處理:LCD 顯示 ---
lcd.setCursor(0, 0);
lcd.print("Sensor Error! ");
lcd.setCursor(0, 1);
lcd.print("Check wiring! ");
// --- 錯誤處理:Serial 顯示 ---
Serial.println("讀取失敗!請檢查接線");
delay(2000);
return;
}
// ========== 顯示在 LCD 上 ==========
// 第一行:溫度
lcd.setCursor(0, 0); // 游標移到第一行開頭
lcd.print("Temp: "); // 標籤
lcd.print(temp, 1); // 溫度值,小數 1 位
lcd.print((char)223); // 顯示 ° 符號(ASCII 碼 223)
lcd.print("C "); // 單位,後面空白覆蓋殘留字元
// 第二行:濕度
lcd.setCursor(0, 1); // 游標移到第二行開頭
lcd.print("Humid: "); // 標籤
lcd.print(humi, 1); // 濕度值
lcd.print("% "); // 單位
// ========== 同時印在 Serial ==========
// 保留 Serial 輸出方便除錯,接上電腦就能看
Serial.print("溫度:");
Serial.print(temp, 1);
Serial.print(" °C | 濕度:");
Serial.print(humi, 1);
Serial.println(" %");
// 每 2 秒更新一次
delay(2000);
}
執行結果
LCD 顯示:
+------------------+
| Temp: 26.0°C |
| Humid: 65.0% |
+------------------+
Serial Monitor 同時輸出:
溫度:26.0 °C | 濕度:65.0 %
溫度:26.0 °C | 濕度:64.0 %

程式碼重點解析
如果你是照著打但不太確定每段在做什麼,這邊幫你整理幾個重點:
為什麼要同時保留 Serial 輸出?
就算有了 LCD,保留 Serial 輸出還是很有用的。開發過程中你可以在電腦上看到完整的數據記錄,方便觀察數值變化的趨勢。如果 LCD 顯示怪怪的,也能馬上比對 Serial 的資料來判斷問題出在哪。等專案完成獨立運作時,Serial 的部分不刪也不會影響任何功能。
lcd.print((char)223) 是什麼?
1602 LCD 有內建一組字元表,ASCII 碼 223 對應的就是 ° 符號。用 (char)223 把數字轉成字元就能印出來。
為什麼 lcd.print() 後面要加空白?
例如 lcd.print("% ") 後面多了幾個空格。這是因為 LCD 不會自動清除舊的內容。如果上一次顯示 65.0%,這一次變成 9.0%,少了一個字元,畫面會變成 9.0%0%——舊的 0% 還留在螢幕上。加幾個空白就能把殘留的字元蓋掉。
delay(2000) 可以改短嗎?
不建議低於 2000(2 秒)。DHT11 的硬體取樣速率限制是每秒最多 1 次。如果你讀得太頻繁,它會一直回傳同樣的舊資料,或是直接讀取失敗。
常見問題
Q:溫度數值偏高,放在冷氣房還顯示 30 幾度?
DHT11 本身有 ±2°C 的誤差,加上如果感測器靠近 ESP32 開發板,板子發熱也會影響讀數。試著用杜邦線把 DHT11 拉遠一點再量看看。
Q:濕度一直顯示 99% 或 1%?
感測器可能受潮或損壞了。DHT11 不防水,如果曾經碰到水或長時間放在高濕度環境,可能會失準。試試換一顆新的。
Q:想改成華氏溫度怎麼做?
把 dht.readTemperature() 改成 dht.readTemperature(true),加一個 true 參數就會回傳華氏。記得把 LCD 上的 C 也改成 F。
Q:我用的是 DHT22,程式要改哪裡?
只要把最上面的 #define DHTTYPE DHT11 改成 #define DHTTYPE DHT22 就好,其他完全不用動。DHT22 的精度更高(±0.5°C),而且會有小數值的變化。
下一步可以做什麼?
學會了感測器 + LCD 顯示之後,你可以嘗試:
- 加入蜂鳴器:溫度超過設定值就發出警報
- 記錄數據到 SD 卡:做一個簡易溫濕度記錄器
- 連上 Wi-Fi:把數據傳到手機或雲端平台(這才是 ESP32 的強項!)
- 換上 OLED 螢幕:顯示更多資訊,還能畫圖表
ESP32 的可能性非常多,1602 LCD + DHT11 只是起點。繼續玩下去吧!



