在上一篇我們玩過了許多視覺特效,今天我們要回歸「實用主義」,教大家如何用 ESP32 製作一個真正的智慧溫控系統。
想像一下:夏天睡覺時,如果室溫變高,風扇就會自動開啟;等到夜深溫度降低後,風扇又會自動關閉,省電又舒適。這個專案將教會你如何整合 環境感測 (DHT22)、數據顯示 (LCD) 與 家電控制 (Relay) 三大核心技能。
Table of Contents
Toggle硬體清單 (Wokwi 模擬器元件)
這次的電路非常簡潔,請在 Wokwi 中準備以下元件:
ESP32 DevKit V1:大腦。
DHT22:高精度的溫濕度感測器。
LCD 1602 (I2C):顯示目前的溫度與濕度,讓你一目了然。
Relay Module (繼電器):這是用小電流控制大電流(如 110V 風扇)的關鍵開關。
接線圖說明 (Wiring)
1. I2C LCD 螢幕 (顯示數據)
ESP32 的 I2C 腳位是固定的,請記住這組黃金搭檔:
SDA: 接 GPIO 21
SCL: 接 GPIO 22
VCC/GND: 接 5V / GND
2. DHT22 感測器 (讀取溫濕度)
SDA (Data): 接 GPIO 15
VCC/GND: 接 3.3V / GND
3. Relay 繼電器 (控制風扇)
IN (訊號腳): 接 GPIO 4
VCC/GND: 接 5V / GND
自動化邏輯
我們的程式邏輯設計如下:
讀取:ESP32 每隔一小段時間讀取一次 DHT22 的溫度。
顯示:將溫度與濕度即時顯示在 LCD 螢幕上。
判斷:
如果溫度 高於 28°C 👉 開啟 Relay (啟動風扇散熱)。
如果溫度 低於或等於 28°C 👉 關閉 Relay (風扇停止,節能)。
完整程式碼
請複製以下程式碼到 Wokwi 的 sketch.ino。
小提醒:在 Wokwi 中,請記得在 Library Manager 加入 DHT sensor library 和 LiquidCrystal I2C 這兩個函式庫。
#include
#include
#include
/* --- 硬體腳位設定 --- */
// DHT22 設定
#define DHTPIN 15 // DHT22 連接到 GPIO 15
#define DHTTYPE DHT22 // 指定型號為 DHT22
// Relay 設定
#define RELAY_PIN 4 // Relay 連接到 GPIO 4
/* --- 物件初始化 --- */
DHT dht(DHTPIN, DHTTYPE);
// LCD 位址通常是 0x27,大小為 16行 2列
LiquidCrystal_I2C lcd(0x27, 16, 2);
/* --- 變數區 --- */
const float TEMP_THRESHOLD = 28.0; // 設定啟動風扇的溫度門檻
void setup() {
Serial.begin(115200);
// 1. 啟動 DHT 感測器
dht.begin();
// 2. 啟動 LCD
lcd.init();
lcd.backlight(); // 開啟背光
// 3. 設定 Relay 腳位為輸出模式
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW); // 預設先關閉風扇
// 開機畫面
lcd.setCursor(0, 0);
lcd.print("Smart Fan Sys.");
lcd.setCursor(0, 1);
lcd.print("Starting...");
delay(2000);
lcd.clear();
}
void loop() {
// --- 步驟 1: 讀取數據 ---
// 讀取溫度 (攝氏)
float t = dht.readTemperature();
// 讀取濕度 (%)
float h = dht.readHumidity();
// 檢查讀取是否失敗 (例如線沒接好)
if (isnan(t) || isnan(h)) {
Serial.println("Failed to read from DHT sensor!");
lcd.setCursor(0, 0);
lcd.print("Sensor Error!");
return; // 離開這次迴圈,重試
}
// --- 步驟 2: 更新 LCD 顯示 ---
updateLCD(t, h);
// --- 步驟 3: 自動溫控邏輯 ---
if (t > TEMP_THRESHOLD) {
// 溫度太高,開風扇
digitalWrite(RELAY_PIN, HIGH);
// 在 Serial Monitor 印出狀態方便除錯
Serial.print("Temp: "); Serial.print(t);
Serial.println("C -> Fan ON (Too Hot)");
}
else {
// 溫度舒適,關風扇
digitalWrite(RELAY_PIN, LOW);
Serial.print("Temp: "); Serial.print(t);
Serial.println("C -> Fan OFF (Comfortable)");
}
// 每 2 秒更新一次,避免感測器讀取太頻繁
delay(2000);
}
// 獨立出來的 LCD 顯示函式,讓主程式更整潔
void updateLCD(float temp, float humi) {
// 第一行顯示溫度
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(temp, 1); // 顯示小數點後1位
lcd.print(" C "); // 多加空格是為了蓋掉舊的字
// 第二行顯示濕度與風扇狀態
lcd.setCursor(0, 1);
lcd.print("Humi: ");
lcd.print(humi, 1);
lcd.print(" %");
// 在右下角顯示一個小小的狀態提示
lcd.setCursor(13, 1);
if (temp > TEMP_THRESHOLD) {
lcd.print("ON "); // 風扇運轉中
} else {
lcd.print("OFF"); // 風扇靜止
}
}
程式碼重點教學
1. 為什麼要用 Relay (繼電器)?
ESP32 的接腳輸出只有 3.3V,電流也非常小,根本推不動家用電風扇。Relay 就像是一個「電磁開關」,我們用 ESP32 的微小電流去控制 Relay 內部的電磁鐵,電磁鐵吸合後,就能導通另一端的高電壓電路。
程式碼中:digitalWrite(RELAY_PIN, HIGH) 就是給電讓開關吸合(風扇通電)。
2. 關於 delay(2000)
你可能會想,為什麼不讓它跑快一點?這是因為 DHT22 這種感測器有物理極限,它的採樣頻率大約是每 2 秒一次。如果你讀取得太快,數值也不會變,甚至可能讀取失敗。
3. 模組化的好處
我們把 LCD 顯示的部分拉出來寫成 updateLCD() 函式。這樣主程式 loop() 看起來就非常乾淨,邏輯一目了然:讀取 -> 顯示 -> 判斷開關。這是一個非常好的程式撰寫習慣喔!
測試與觀察
在 Wokwi 模擬器中按下綠色執行鍵:
點擊 DHT22 元件:你會看到一個滑桿。
調整溫度:
試著將溫度拉到 28.1°C 以上
你會看到 Relay 旁邊的小燈亮起(代表導通/風扇轉動),LCD 右下角顯示 “ON”。
將溫度拉回 27°C
Relay 燈熄滅,LCD 顯示 “OFF”。
這就是智慧家居最基礎的雛形!學會這個,你也可以把風扇換成「除濕機」(改用濕度判斷),原理完全一樣喔!趕快動手試試看吧!
💻 Wokwi 專案程式碼 (直接玩): [https://wokwi.com/projects/451472281453862913]
🛠️ ESP32 開發板介紹: [DIY 智慧溫室教學:用 ESP32 + 光敏電阻 + DHT11 監測光照與溫濕度]
