ระดับกลาง
สร้างตัวอย่างการใช้งานเทอร์โมสตัทแบบดิจิทัล
เซ็นเซอร์ระบบอัตโนมัติแอคชูเอเตอร์
อ่านค่าอุณหภูมิที่เกิดขึ้นจริง เปรียบเทียบกับค่าเกณฑ์ และสั่งให้พัดลมทำงาน ซึ่งเป็นการควบคุมแบบวนซ้ำที่คุณสามารถมองเห็นและสัมผัสได้จริง
รวมชิ้นส่วนจริง 8 รายการ
ราคารวมชุดนี้: 1,895.00 ฿
ยังไม่รวมส่วนลดคำสั่งซื้อที่คุณอาจได้รับตอนชำระเงิน
สิ่งที่คุณต้องใช้
เป้าหมายของโครงการ
โครงการนี้สร้างระบบควบคุมแบบวงปิดขนาดเล็ก: อ่านอุณหภูมิจริง เปรียบเทียบกับค่าเกณฑ์ และเปิดหรือปิดพัดลมตามการตอบสนอง ซึ่งเป็นการควบคุมที่คุณสามารถมองเห็นและสัมผัสได้จริง ไม่ใช่แค่การอ่านเป็นตัวเลขบนหน้าจอ เป็นการยกระดับจากโครงการที่เพียงแค่ตรวจจับหรือแสดงผลเท่านั้น เพราะที่นี่การตัดสินใจของตัวควบคุมจะเปลี่ยนแปลงบางสิ่งในโลกทางกายภาพ
สิ่งที่ตัวควบคุมทำ
ESP32-C3 จะอ่านอุณหภูมิปัจจุบันจากเซ็นเซอร์อย่างต่อเนื่อง เปรียบเทียบกับค่าเกณฑ์ที่กำหนดในโค้ด อัปเดตการแสดงผลด้วยค่าที่อ่านได้ปัจจุบัน และเปิดหรือปิดพัดลมตามการเปรียบเทียบนั้น เป็นส่วนเดียวของระบบที่ตัดสินใจได้ — เซ็นเซอร์ จอแสดงผล และพัดลมเพียงแค่รายงานและตอบสนองเท่านั้น
สิ่งที่เซ็นเซอร์ทำ
AHT20 ให้ค่าอุณหภูมิปัจจุบัน (พร้อมกับความชื้น หากคุณเลือกที่จะใช้) ซึ่งตัวควบคุมจะอ่านผ่านบัส I2C เดียวกันที่ใช้สำหรับจอแสดงผล นี่คือส่วนอินพุตของวงจรควบคุม — หากไม่มีการอ่านค่าจริง ตัวควบคุมก็ไม่มีสิ่งใดที่มีความหมายให้เปรียบเทียบกับค่าเกณฑ์
สิ่งที่จอแสดงผลทำ
OLED แสดงทั้งอุณหภูมิปัจจุบันและค่าเกณฑ์ที่กำลังเปรียบเทียบ ทำให้พฤติกรรมของระบบมองเห็นได้และตรวจสอบได้ง่าย — คุณสามารถดูอุณหภูมิที่แสดงผลเข้าใกล้ค่าเกณฑ์และยืนยันว่าพัดลมตอบสนองในเวลาที่เหมาะสม แทนที่จะคาดเดาว่าตรรกะทำงานถูกต้องหรือไม่
สิ่งที่ MOSFET และพัดลมทำ
โมดูล MOSFET ระดับลอจิกจะเปิดหรือปิดพัดลมตามการเปรียบเทียบของตัวควบคุม MOSFET ถูกใช้ที่นี่แทนรีเลย์เชิงกลโดยเฉพาะเนื่องจากพัดลมเป็นโหลดกระแสตรง และ MOSFET สลับกระแสตรงอย่างเงียบ ๆ โดยไม่มีชิ้นส่วนเคลื่อนที่และไม่มีเสียงคลิก และไม่มีการสึกหรอของหน้าสัมผัสเมื่อเวลาผ่านไป โมดูลนี้ได้รับการยืนยันว่าเป็นระดับลอจิก ซึ่งหมายความว่ามันสลับได้อย่างสมบูรณ์ที่ 3.3-5V — ช่วงแรงดันไฟฟ้าเดียวกันกับที่ขา GPIO ของ ESP32-C3 ส่งออกโดยตรง — แทนที่จะต้องการแรงดันเกตที่สูงกว่าซึ่งจะต้องการวงจรขับเคลื่อนเพิ่มเติม
ทำไมต้องใช้ MOSFET แทนรีเลย์
นอกเหนือจากความเงียบและไม่มีชิ้นส่วนที่เคลื่อนที่แล้ว MOSFET ระดับลอจิกยังสามารถสลับได้โดยตรงจากขา GPIO โดยไม่มีขั้นตอนไดรเวอร์กลาง เนื่องจากเกตของมันเปิดได้อย่างสมบูรณ์ภายในช่วงแรงดันเอาต์พุตของตัวควบคุมเอง ในทางตรงกันข้าม รีเลย์เชิงกลมาตรฐานต้องการกระแสคอยล์ที่ขา GPIO มักจะไม่สามารถจ่ายได้โดยตรง บวกกับการป้องกันฟลายแบ็คสำหรับคอยล์ และสึกหรอทางกลจากการสลับซ้ำ ๆ สำหรับพัดลม DC ขนาดเล็กที่สลับบ่อยครั้งโดยวงจรควบคุมอุณหภูมิ MOSFET ระดับลอจิกเป็นทางเลือกที่ง่ายกว่าและทนทานกว่า
แนวคิดซอฟต์แวร์และไลบรารี
ตรรกะหลักคือการเปรียบเทียบค่าเกณฑ์ แต่การใช้งานที่เรียบง่าย — พัดลมเปิดเมื่ออุณหภูมิสูงกว่า X° ปิดเมื่อต่ำกว่า X° — ทำให้เกิดปัญหาจริง: ฮิสเตอรีซิส หากอุณหภูมิคงที่อยู่เหนือค่าเกณฑ์พอดี การผันผวนเล็กน้อยจะทำให้พัดลมเปิดและปิดอย่างรวดเร็วเมื่อค่าที่อ่านได้ข้ามไปมาเหนือจุดเดียวนั้น การแก้ไขคือช่องว่างบัฟเฟอร์ขนาดเล็กระหว่างเกณฑ์การเปิดและปิด — ตัวอย่างเช่น เปิดพัดลมเมื่ออุณหภูมิสูงกว่า 28° แต่ปิดเมื่ออุณหภูมิต่ำกว่า 27° เท่านั้น ช่องว่างหนึ่งองศานั้นหมายความว่าการผันผวนรอบ ๆ ตัวเลขใดตัวเลขหนึ่งจะไม่ทำให้เกิดการหมุนวนอย่างรวดเร็ว เพราะพัดลมจะต้องผ่านช่องว่างทั้งหมดในทิศทางเดียวก่อนที่จะเปลี่ยนสถานะอีกครั้ง นี่เป็นแนวคิดที่สำคัญอย่างแท้จริงของระบบควบคุม ไม่ใช่แค่รายละเอียดการใช้งานเล็กน้อย — หากไม่มีสิ่งนี้ การสลับพัดลมที่เหมือนรีเลย์จะสึกหรอเร็วขึ้นอย่างเห็นได้ชัด และพฤติกรรมจะดูผิดปกติแม้ว่าตรรกะพื้นฐานจะถูกต้อง
การทดสอบและการแก้ไขปัญหา
- พัดลมไม่เปิดแม้ว่าอุณหภูมิจะสูงกว่าค่าเกณฑ์อย่างชัดเจน — ตรวจสอบสายไฟควบคุมสัญญาณของโมดูล MOSFET และยืนยันว่าโค้ดกำลังเปรียบเทียบกับค่าเกณฑ์ที่ถูกต้องจริง ๆ ไม่ใช่ค่าเริ่มต้นที่เหลืออยู่
- พัดลมไม่ปิดหรือกะพริบอย่างรวดเร็วรอบ ๆ ค่าเกณฑ์ — เกือบจะเสมอเป็นช่องว่างฮิสเตอรีซิสที่ขาดหายไป เพิ่มเกณฑ์การเปิดและปิดแยกกันห่างกันหนึ่งหรือสององศา
- อุณหภูมิที่แสดงผลและพฤติกรรมของพัดลมดูไม่ตรงกัน — ตรวจสอบหน่วยและค่าเกณฑ์ที่ใช้ในโค้ดอีกครั้งเทียบกับสิ่งที่เซ็นเซอร์รายงานจริง (AHT20 รายงานเป็นเซลเซียสโดยค่าเริ่มต้น)
- การอ่านอุณหภูมิดูค้างหรือไม่สมเหตุสมผล — ยืนยันว่า AHT20 เริ่มต้นสำเร็จผ่าน I2C และไม่ขัดแย้งกับ OLED บนบัสเดียวกัน การเริ่มต้นเซ็นเซอร์ล้มเหลวมักจะส่งคืนค่าคงที่หรือค่าขยะอย่างเงียบ ๆ แทนที่จะเป็นข้อผิดพลาด
การอัปเกรดเสริมในอนาคต: การควบคุมความเร็วพัดลมแบบสัดส่วน
แทนที่จะเปิดหรือปิดพัดลมอย่างสมบูรณ์ เวอร์ชั่นในอนาคตสามารถขับเคลื่อนมันด้วย PWM และปรับความเร็วของพัดลมให้เป็นสัดส่วนกับระยะห่างที่อุณหภูมิสูงกว่าค่าเกณฑ์ — ลมเบา ๆ เหนือเส้นเล็กน้อย ความเร็วเต็มที่เมื่ออุณหภูมิสูงขึ้นไปอีก สิ่งนี้สร้างขึ้นโดยตรงบนการเดินสาย MOSFET เดียวกันที่มีอยู่แล้ว เนื่องจาก MOSFET ระดับลอจิกที่รองรับ PWM สามารถจัดการรอบการทำงานที่แตกต่างกันได้เช่นเดียวกับการจัดการสัญญาณเปิด/ปิดอย่างง่าย
การเดินสาย
- AHT20 sensor VCC → ESP32-C3 3V3
- AHT20 sensor GND → ESP32-C3 GND
- AHT20 sensor SDA → ESP32-C3 GPIO8 — บัส I2C ที่ใช้ร่วมกัน (SDA เริ่มต้นบน ESP32-C3/S3 Arduino core)
- AHT20 sensor SCL → ESP32-C3 GPIO9 — บัส I2C ที่ใช้ร่วมกัน (SCL เริ่มต้น)
- OLED display VCC → ESP32-C3 3V3
- OLED display GND → ESP32-C3 GND
- OLED display SDA → ESP32-C3 GPIO8 — บัสเดียวกับ AHT20 (ที่อยู่ I2C ต่างกัน: AHT20 = 0x38, OLED = 0x3C, จึงไม่มีความขัดแย้ง)
- OLED display SCL → ESP32-C3 GPIO9 — บัสเดียวกับ AHT20
- MOSFET module SIG → ESP32-C3 GPIO3 — สัญญาณควบคุมดิจิทัลสำหรับสวิตช์พัดลม
- MOSFET module VCC → ESP32-C3 3V3 — แหล่งจ่ายไฟลอจิกสำหรับวงจรขับเกตของโมดูล
- MOSFET module GND → ESP32-C3 GND — ต้องใช้กราวด์ร่วมกับทั้ง ESP32 และแหล่งจ่ายไฟของพัดลม
- Fan red wire (+) → 5V (ขา 5V ของบอร์ด, มีอยู่เมื่อจ่ายไฟผ่าน USB-C)
- Fan black wire (−) → ขั้วเอาต์พุตโหลดของโมดูล MOSFET, โดยที่ขั้วโหลดอีกด้านของโมดูล → GND — ซึ่งจะส่งกระแสย้อนกลับของพัดลมผ่านสวิตช์ MOSFET
ติดตั้ง AHT20 และ OLED ก่อน และยืนยันว่าทั้งสองตอบสนองบนบัส I2C ที่ใช้ร่วมกัน ก่อนที่จะเดินสายส่วน MOSFET/พัดลม — ความขัดแย้งของที่อยู่ I2C หรือการเดินสายที่ไม่ถูกต้องจะแก้ไขข้อผิดพลาดได้ง่ายกว่าเมื่อไม่มีพัดลมหมุนในวงจร แถบฮิสเตอรีซิส ±0.5°C คือสิ่งที่ช่วยให้พัดลมไม่เปิด/ปิดอย่างรวดเร็วที่ค่าเกณฑ์ ขยายมันหากพัดลมยังคงทำงานติดขัดในการตั้งค่าของคุณ ห้ามจ่ายไฟให้พัดลมโดยตรงจากขา GPIO — ต้องสลับผ่านโมดูล MOSFET เสมอ
แผนภาพการต่อสาย
โค้ดเริ่มต้น
// Digital Thermostat Demo — ESP32-C3 SuperMini + AHT20 + OLED + MOSFET fan
#include <Wire.h>
#include <Adafruit_AHTX0.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// --- Pins — adjust to match your board's silkscreen if different ---
#define SDA_PIN 8
#define SCL_PIN 9
#define FAN_MOSFET_PIN 3
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C
Adafruit_AHTX0 aht;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
const float TEMP_THRESHOLD_C = 27.0; // fan turns on above this
const float HYSTERESIS_C = 0.5; // fan turns off once temp drops this far below threshold
bool fanOn = false;
void setup() {
Serial.begin(115200);
Wire.begin(SDA_PIN, SCL_PIN);
pinMode(FAN_MOSFET_PIN, OUTPUT);
digitalWrite(FAN_MOSFET_PIN, LOW); // fan off at boot
if (!aht.begin()) {
Serial.println("AHT20 not found — check wiring");
while (1) delay(1000);
}
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
Serial.println("SSD1306 not found — check wiring");
while (1) delay(1000);
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
}
void updateFan(float tempC) {
if (!fanOn && tempC >= TEMP_THRESHOLD_C) {
fanOn = true;
} else if (fanOn && tempC <= (TEMP_THRESHOLD_C - HYSTERESIS_C)) {
fanOn = false;
}
digitalWrite(FAN_MOSFET_PIN, fanOn ? HIGH : LOW);
}
void loop() {
sensors_event_t humidity, temp;
aht.getEvent(&humidity, &temp);
float tempC = temp.temperature;
float rh = humidity.relative_humidity;
updateFan(tempC);
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0, 0);
display.print(tempC, 1);
display.println(" C");
display.setTextSize(1);
display.setCursor(0, 20);
display.print("Humidity: ");
display.print(rh, 0);
display.println(" %");
display.setCursor(0, 35);
display.print("Threshold: ");
display.print(TEMP_THRESHOLD_C, 1);
display.println(" C");
display.setCursor(0, 50);
display.print("Fan: ");
display.println(fanOn ? "ON" : "OFF");
display.display();
Serial.print("Temp: "); Serial.print(tempC);
Serial.print(" C Humidity: "); Serial.print(rh);
Serial.print(" % Fan: "); Serial.println(fanOn ? "ON" : "OFF");
delay(1000);
}
ไม่แน่ใจขั้นตอนไหน?
ถามเรา