《ESP32 入門》NodeMCU-32S 結合 DHT11溫濕度感測器+LCD

上一篇我們學會了用 ESP32 驅動 1602 LCD 顯示文字。這篇續篇要帶你接上 DHT11 溫濕度感測器,先把數據印在 Serial Monitor 上確認感測器有正常運作,再進一步把溫濕度顯示到 LCD 螢幕上。

《ESP32 入門》NodeMCU-32S 結合 DHT11溫濕度感測器+LCD

上一篇我們學會了用 ESP32 驅動 1602 LCD 顯示文字。這篇續篇要帶你接上 DHT11 溫濕度感測器,先把數據印在 Serial Monitor 上確認感測器有正常運作,再進一步把溫濕度顯示到 LCD 螢幕上。

建議大家先回上一篇,了解一下LCD的用法哦!

《ESP32 入門》NodeMCU-32S 連接 1602 LCD 顯示螢幕(I2C)
你是否剛入手 ESP32,想讓它在螢幕上顯示文字?1602 LCD 是最經典的入門顯示元件,便宜、好買、接線簡單。這篇教學會帶你從零開始,一步一步完成 ESP32 + 1602 LCD 的第一個專案。

這篇教學你需要的材料

除了上一篇已經準備好的 ESP32 + 1602 LCD 之外,你還需要:

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

這篇教學以 3 腳模組版 為例。
NodeMCU-32S 相容版本 ESP32開發板 WiFi 藍牙 可用Arduino IDE
全腳位引出,還保持迷你的身型,插上麵包後還能插杜邦線,真的是太棒了! 和NodeMCU V2幾乎一樣尺寸! 有5V供電輸出,非常方便! 有了ESP32開發板,真的可以忘記原來的那些Arduino板子了! 可以用Arduino IDE開發,但效能更強大,還內建WiFi 傑森實測記錄,大家可以到 F 粉 絲 團 B 看貼文哦! ESP32-D0WDQ6 內置兩個低功耗 Xtensa® 32-bit LX6 MCU。片上存儲包括: • 448 KB 的 ROM,用於程序啟動和內核功能
DHT11模組 DHT-11 溫濕度感測器
產品內容 一、尺寸:長30.5mmX寬12mmX高7.2mm 二、傳感器型號: DHT11溫濕度傳感器 三、工作電壓:直流5V 四、特點: 1、濕度測量範圍:20---90%RH 2、濕度測量精度:±5%RH 3、溫度測量範圍:0---50℃ 4、溫度測量精度:±2℃ 5、工作電壓:DC5V/3.3V 6、數字信號輸出 7、數據端口帶上拉電阻 8、帶3mm固定螺絲孔,方便安裝 五、接線方法: VCC → 3.3V/5V電源正極 GND →電源負極 DATA →單片機IO口
藍底 黃綠 1602 LCD 顯示器 已焊2004轉接板 IIC/I2C
原來的1602顯示器需要7個IO介面才能驅動起來,本產品附的這個轉接板,可以幫你省下5個pin 附程式庫及範例程式 商品特色 支持I2C協議 帶背光電源控制,可以通過跳線帽設置是否連接背光電源。插上跳線帽為連接背光電源,拔掉跳線帽為斷開背光電源 對比度可調節,旋轉藍色電位器,順時針增強,逆時針減弱。電位器設計在正面,方便客戶隨時隨地自由調節 模組可級聯,最多可級聯8個。通過短路A0/A1/A2修改設備地址。

認識 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-VCCDATAGND),不要死記順序。

第一步:安裝 DHT 函式庫

  1. 打開 Arduino IDE
  2. 到「函式庫管理員」(左邊書本圖示)
  3. 搜尋 DHT sensor library
  4. 安裝作者是 Adafruit 的那個
  5. 跳出提示問你要不要安裝相依套件(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);
}

上傳與查看結果

  1. 開發板選 Nodemcu-32s,選好 COM Port
  2. 上傳程式
  3. 打開 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 只是起點。繼續玩下去吧!