ESP32迷你氣象站:DHT11 溫濕度 + 0.96 吋 OLED 顯示(離線版)
教你用 ESP32 打造「離線版」迷你氣象站。完美呈現經典雙色 OLED 介面,免設網路、隨插即用。內附超詳盡註解,新手也能輕鬆成功,快來動手 DIY 吧!
如果你手邊有一片 ESP32 開發板,想要做點實用的小專題,但又不想一開始就處理複雜的網路設定,那麼這個「迷你氣象站」絕對是你的最佳入門選擇。
在這個教學中,我們將教會你如何將最常見的 DHT11 溫濕度感測器 連接到 ESP32,讀取你房間目前的溫度與濕度,並將數據即時顯示在清晰漂亮的 0.96 吋 OLED 螢幕上。
這個專題完全不需要連接網路,是一個獨立運作的小裝置,非常適合放在書桌上監控環境!
🛠️ 準備材料 (硬體需求)
在開始動手前,請確保你準備好了以下零件:
- ESP32 開發板 x1 (建議 NodeMCU-32S,或其他相容板)
- 0.96 吋 OLED 顯示模組 x1 (解析度 128x64,I2C 介面,驅動晶片 SSD1306)
- DHT11 溫濕度感測器模組 x1 (建議買已焊接在 PCB 板上,有 3 支腳的那種模組,比較方便接線)
- 杜邦線 若干 (公對母)
- 麵包板 x1 (或是擴展板,方便接線用)



Arduino IDE 設定
安裝開發板:如果之前已使用過ESP32開發板,就不用重複進行了。若是第一次,請參考我們另一篇專文教學哦!

🔌 接線圖
接線是新手最容易緊張的部分,別擔心,我們一步一步來。請參考下圖與文字說明,將感測器與螢幕連接到 ESP32。
(注意:接線時請先拔除 USB 電源,避免短路)

1. 連接 OLED 螢幕 (I2C 介面)
OLED 螢幕使用 I2C 通訊協定,只需要兩條訊號線。ESP32 預設的 I2C 腳位是 GPIO 21 和 GPIO 22。
- VCC:接到 ESP32 的 3.3V (或5v)
- GND:接到 ESP32 的 GND
- SCL (或 SCK):接到 ESP32 的 GPIO 22 (D22)
- SDA:接到 ESP32 的 GPIO 21 (D21)
2. 連接 DHT11 感測器
DHT11 只需要一條資料線。在本範例中,我們使用 GPIO 4 來讀取資料。
- VCC (或 +):接到 ESP32 的 3.3V (或5V) — 電源 (DHT11 模組通常 3.3V-5V 皆可)
- GND (或 -):接到 ESP32 的 GND
- DATA (或 OUT/S):接到 ESP32 的 GPIO 4 (D4)

💻 軟體設定 (安裝程式庫)
為了驅動 OLED 螢幕和讀取 DHT11,我們需要安裝幾個 Arduino 程式庫。請開啟 Arduino IDE,按照以下步驟操作:
- 點選選單欄的 「工具 (Tools)」 -> 「管理程式庫 (Manage Libraries...)」。
- 在搜尋框中輸入以下關鍵字並安裝對應的程式庫:
- 搜尋
SSD1306,安裝 Adafruit SSD1306 (由 Adafruit 提供)。 - 搜尋
GFX,安裝 Adafruit GFX Library (由 Adafruit 提供,這是繪圖核心庫)。 - 搜尋
DHT11,安裝 DHT sensor library (由 Adafruit 提供,通常安裝時會提示需要一起安裝 "Adafruit Unified Sensor",請一併安裝)。
- 搜尋
安裝完成後,我們就可以開始寫程式了!
📝 完整的程式碼 (附詳細註解)
將下方的程式碼複製並貼上到你的 Arduino IDE 中。我們在每一行關鍵程式碼旁邊都加上了詳細的中文註解,幫助你理解它在做什麼。
程式其實很簡單,就是從DHT11讀取溫度和濕度,然後顯示在OLED上,只是為了OLED畫面美觀,多了幾行處理格式而已,大家看看註解就可以理解囉!
/*
* ============================================================
* 專題:ESP32 雙欄式溫濕度計 (傑森創工製作)
* 硬體:ESP32 + DHT11 + 0.96" OLED
* ============================================================
*/
// ----- 1. 引入程式庫 (Libraries) -----
#include <Wire.h> // 用來控制 I2C 設備 (OLED 用這個介面)
#include <Adafruit_GFX.h> // Adafruit 的繪圖核心 (畫線、圓、寫字的演算法都在這)
#include <Adafruit_SSD1306.h> // 專門控制 SSD1306 這顆 OLED 晶片的驅動程式
#include <DHT.h> // 專門讀取 DHT 系列溫濕度感測器的驅動程式
// ----- 2. 硬體參數設定 (Constants) -----
// 使用 #define 定義常數,方便之後如果要改腳位,只要改這裡就好
#define DHTPIN 4 // 定義 DHT11 的 Data 腳位接在 GPIO 4
#define DHTTYPE DHT11 // 定義感測器型號 (如果是 DHT22 就改這裡)
#define SCREEN_WIDTH 128 // OLED 螢幕寬度 (像素)
#define SCREEN_HEIGHT 64 // OLED 螢幕高度 (像素)
#define OLED_RESET -1 // 重置腳位 (-1 代表共用 Arduino 的重置鍵,通常不用改)
#define SCREEN_ADDR 0x3C // I2C 位址 (如果螢幕不亮,可以改成 0x3D 試試)
// ----- 3. 建立物件 (Objects) -----
// 這裡我們要創造「虛擬的裝置」來對應「實體的硬體」
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // 建立 OLED 物件
DHT dht(DHTPIN, DHTTYPE); // 建立 DHT 感測器物件
// ==================================================
// setup():開機時只執行一次的設定區
// ==================================================
void setup() {
// 開啟序列埠監控 (鮑率 115200),讓我們能在電腦上看到除錯訊息
Serial.begin(115200);
// 啟動 DHT 感測器
dht.begin();
// 啟動 OLED 螢幕
// SSD1306_SWITCHCAPVCC 代表使用螢幕內建的升壓電路來供電
if (!oled.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDR)) {
Serial.println(F("OLED 啟動失敗!請檢查接線"));
for (;;); // 如果失敗,進入無窮迴圈卡住程式,不讓它往下跑
}
// 剛啟動時先清除畫面 (把螢幕變全黑)
oled.clearDisplay();
oled.display();
}
// ==================================================
// loop():開機後會不斷重複執行的主程式區
// ==================================================
void loop() {
// ----- 步驟 A: 讀取數據 -----
float h = dht.readHumidity(); // 讀取濕度 (float 是浮點數,包含小數)
float t = dht.readTemperature(); // 讀取溫度 (攝氏)
// 檢查數據是否有效 (isnan 代表 "Is Not a Number")
// 如果拔掉線或感測器壞掉,這裡會攔截到錯誤
if (isnan(h) || isnan(t)) {
Serial.println(F("讀取失敗!請檢查 DHT11"));
return; // 直接跳出這次 loop,等下一輪再試
}
// ----- 步驟 B: 開始繪圖 (在緩衝區作畫) -----
oled.clearDisplay(); // 重要!每次畫新圖之前,要把舊的擦掉
// >>> 區塊 1:頂部黃色標題 (反白效果) <<<
// 1. 畫一個實心的白色長方形,填滿上方區域
// 參數:fillRect(x, y, 寬, 高, 顏色)
oled.fillRect(0, 0, 128, 16, SSD1306_WHITE);
// 2. 設定文字顏色為「黑字、白底」
// 第一個參數是字色(Black),第二個是背景色(White)
// 這樣字寫在白色方塊上,就會變成像是鏤空的效果
oled.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
oled.setTextSize(1); // 設定最小字體
// 計算置中:(螢幕寬128 - 字串長度) / 2 = 13
oled.setCursor(13, 4);
oled.print(F("www.jmaker.com.tw"));
// 3. 畫完標題記得把顏色改回「白字」,不然下面藍色區會看不見
oled.setTextColor(SSD1306_WHITE);
// >>> 區塊 2:左側溫度顯示 (藍色區) <<<
// 顯示數值 (大字體)
oled.setTextSize(3); // 設定 3 號字
oled.setCursor(4, 30); // 設定座標 (我們剛剛決定下移到 Y=30)
oled.print((int)t); // (int) 是強制轉型,把 25.6 變成 25,去掉小數點比較簡潔
// 顯示單位 °C (中字體)
oled.setTextSize(2); // 設定 2 號字
oled.setCursor(42, 36); // 設定座標 (Y=36 配合大字的底部)
oled.write(247); // 這是畫出「度數圈圈符號 (°)」的特殊指令 (ASCII 碼 247)
oled.print(F("C"));
// >>> 區塊 3:右側濕度與分隔線 (藍色區) <<<
// 畫分隔線
// 參數:drawFastVLine(x, y, 長度, 顏色) -> VLine 代表垂直線
oled.drawFastVLine(72, 18, 44, SSD1306_WHITE);
// 顯示標籤 "HUMID"
oled.setTextSize(1);
oled.setCursor(82, 27);
oled.print(F("HUMID"));
// 顯示濕度數值
oled.setTextSize(2);
oled.setCursor(82, 37); // Y=37 讓它跟標籤形成垂直置中
oled.print((int)h);
oled.print(F("%"));
// ----- 步驟 C: 送出畫面 -----
// 這行最重要!上面寫了那麼多指令,都只是在記憶體裡畫
// 執行這行,螢幕才會真的亮起來顯示內容
oled.display();
// ----- 步驟 D: 休息 -----
// DHT11 動作比較慢,建議至少休息 2 秒再讀下一次
delay(2000);
}
🚀 上傳與執行
- 將 ESP32 透過 USB 線連接到電腦。
- 在 Arduino IDE 中選擇正確的 開發板 (Board) (例如 "ESP32 Dev Module") 和 序列埠 (Port)。
- 點擊 「上傳 (Upload)」 按鈕 (向右箭頭圖示)。
- 等待編譯和上傳完成。
成果展示: 如果一切順利,你的 OLED 螢幕應該會亮起,上方顯示大字體的溫度,中間顯示濕度,最下方則是你設定的網址。試著對感測器哈一口氣,看看數值會不會變化!

💡 常見問題排除
- 螢幕一片黑,什麼都沒顯示?
- 檢查 VCC 和 GND 是否接反?(非常重要!)
- 檢查 SCL (GPIO 22) 和 SDA (GPIO 21) 是否接對?
- 試著將程式碼中的
SCREEN_ADDR 0x3C改成0x3D再上傳一次試試。
- 序列埠監控視窗顯示「讀取失敗!無法從 DHT 感測器獲取資料」?
- 檢查 DHT11 的 DATA 腳是否確實接到 GPIO 4?
- 檢查 DHT11 是否有供電 (VCC/GND)?
- 杜邦線是否接觸不良?試著重新插拔看看。
- 數值顯示
nan?- 這通常代表感測器沒有正確回傳數據,原因同上,請檢查接線。
恭喜你完成了第一個 ESP32 硬體整合專題!現在你擁有一個專屬的桌面環境監控器了。下一步,試著修改程式碼,改變顯示的位置或文字大小,玩玩看吧!
ESP32處理DHT11目前只是開始,下一篇傑森就要教大家,如何把讀到的溫濕度,透過WIFI,讓手機就可以看到!



