ESP32迷你氣象站:DHT11 溫濕度 + 0.96 吋 OLED 顯示(離線版)

教你用 ESP32 打造「離線版」迷你氣象站。完美呈現經典雙色 OLED 介面,免設網路、隨插即用。內附超詳盡註解,新手也能輕鬆成功,快來動手 DIY 吧!

ESP32迷你氣象站:DHT11 溫濕度 + 0.96 吋 OLED 顯示(離線版)

如果你手邊有一片 ESP32 開發板,想要做點實用的小專題,但又不想一開始就處理複雜的網路設定,那麼這個「迷你氣象站」絕對是你的最佳入門選擇。

在這個教學中,我們將教會你如何將最常見的 DHT11 溫濕度感測器 連接到 ESP32,讀取你房間目前的溫度與濕度,並將數據即時顯示在清晰漂亮的 0.96 吋 OLED 螢幕上。

這個專題完全不需要連接網路,是一個獨立運作的小裝置,非常適合放在書桌上監控環境!


🛠️ 準備材料 (硬體需求)

在開始動手前,請確保你準備好了以下零件:

  1. ESP32 開發板 x1 (建議 NodeMCU-32S,或其他相容板)
  2. 0.96 吋 OLED 顯示模組 x1 (解析度 128x64,I2C 介面,驅動晶片 SSD1306)
  3. DHT11 溫濕度感測器模組 x1 (建議買已焊接在 PCB 板上,有 3 支腳的那種模組,比較方便接線)
  4. 杜邦線 若干 (公對母)
  5. 麵包板 x1 (或是擴展板,方便接線用)
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,用於程序啟動和內核功能
0.96吋 OLED 128x64 低耗電 高解析 可顯示點陣圖 大勝LCD
尺寸:0.96吋 解析度:128x64 使用電源:3.3v~5v (實測3.3v即可) 顏色:上方1/4為黃色,以下為藍色 傑森實際,效果非常好! 送完整範例程式,一看就會。 大家可以利用LCDAssistant等程式,將點陣圖轉為Byte Array,即可顯示在螢幕上!
ESP32S擴展板 適用於Nodemcu-32s 38Pin全引出
※ 不含ESP32S開發板,需另購! ESP32S專用擴展板 適用於Nodemcu-32s,其它型號都不相容哦!請留意。 38Pin全引出,無敵方便!

Arduino IDE 設定

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

在Arduino IDE中新增ESP32的開發板-以Nodemcu-32s為例
雖然Arduino Uno方便好用,如果真的需要WiFi功能,傑森一律建議直接換塊ESP32的板子,這是最直接的方法。 但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,按照以下步驟操作:

  1. 點選選單欄的 「工具 (Tools)」 -> 「管理程式庫 (Manage Libraries...)」
  2. 在搜尋框中輸入以下關鍵字並安裝對應的程式庫:
    • 搜尋 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); 
}

🚀 上傳與執行

  1. 將 ESP32 透過 USB 線連接到電腦。
  2. 在 Arduino IDE 中選擇正確的 開發板 (Board) (例如 "ESP32 Dev Module") 和 序列埠 (Port)
  3. 點擊 「上傳 (Upload)」 按鈕 (向右箭頭圖示)。
  4. 等待編譯和上傳完成。

成果展示: 如果一切順利,你的 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,讓手機就可以看到!