IoT คืออะไร ?
IoT ย่อมาจากคำว่า Internet of Things ถ้าแปลตรงตัวคือ “อินเทอร์เน็ตของสรรพสิ่ง” แต่ความหมายจริงๆ ของมันสนุกกว่านั้นมาก
ให้นักศึกษาลองจินตนาการว่า ปกติแล้วสิ่งของรอบตัวเรา (Things) เช่น หลอดไฟ พัดลม ปั๊มน้ำ หรือแปลงผัก มันเป็นสิ่งไม่มีชีวิตที่ “พูดไม่ได้” และ “คิดเองไม่เป็น” เราต้องเดินไปกดสวิตช์หรือลงมือทำด้วยตัวเองมันถึงจะทำงาน
แต่จะเกิดอะไรขึ้น… ถ้าเราจับสิ่งของธรรมดาๆ พวกนี้ มาติด “สมองกล” และเชื่อมต่อ Wi-Fi ให้มัน
สิ่งของเหล่านั้นจะตื่นขึ้นมา “คุยกันเองได้” และ “รายงานสถานะให้เรารู้ได้” ทันที นี่แหละคือหัวใจของ IoT
💡 ตัวอย่าง IoT ในชีวิตจริงที่เราพบบ่อย
- Smart Farm (ฟาร์มอัจฉริยะ) เซนเซอร์ตรวจจับได้ว่าดินในแปลงผักแห้งเกินไป ระบบจึงสั่งเปิดปั๊มน้ำอัตโนมัติ
- Smart Home (บ้านอัจฉริยะ) นักศึกษาออกมาจากบ้านแล้วเพิ่งนึกได้ว่าลืมปิดแอร์ ก็แค่หยิบมือถือขึ้นมากดปิดแอร์ผ่านแอปพลิเคชันได้เลย
- Smart Band (นาฬิกาสุขภาพ) นาฬิกาที่ใส่อยู่คอยวัดอัตราการเต้นของหัวใจ แล้วส่งข้อมูลไปเก็บในมือถือ เพื่อวิเคราะห์สุขภาพของเรา
🎯 สรุปสั้นๆ IoT คือการทำให้ “สิ่งของธรรมดา” กลายเป็น “ของฉลาด” โดยจับมันเชื่อมต่อเข้ากับอินเทอร์เน็ต เพื่อให้เรารับรู้ข้อมูลและสั่งงานมันได้จากทุกที่บนโลก ช่วยลดภาระและทำให้ชีวิตเราสะดวกสบายขึ้นนั่นเอง
3 โครงสร้างหลักของระบบ IoT (3-Layer Architecture)
ก่อนที่เราจะเริ่มจับสายไฟหรือเขียนโค้ดลงบอร์ด สิ่งสำคัญที่สุดคือเราต้องเห็นภาพรวมก่อนว่าระบบ IoT ที่เรากำลังจะสร้างนั้น ประกอบด้วยชิ้นส่วนอะไรบ้าง และมันคุยกันอย่างไร
ให้นึกภาพว่าระบบ IoT ทำงานประสานกันเหมือน “ร่างกายมนุษย์” ซึ่งสามารถแบ่งออกเป็น 3 ส่วนหลักๆ ดังนี้
1. Perception Layer (ชั้นรับรู้ข้อมูล) 🦾
- เปรียบเสมือน อวัยวะรับสัมผัส และกล้ามเนื้อของร่างกาย
- หน้าที่หลัก คอยดักจับข้อมูลจากสภาพแวดล้อมรอบตัว และลงมือทำงานตามคำสั่ง
- อุปกรณ์ในงานจริง
- ฝ่ายรับรู้ เซนเซอร์วัดความชื้นในดิน เซนเซอร์วัดอุณหภูมิ เซนเซอร์รับแสง
- ฝ่ายลงมือทำ รีเลย์ (Relay) ปั๊มน้ำ พัดลมระบายอากาศ
2. Network Layer (ชั้นเครือข่ายสื่อสาร) ⚡
- เปรียบเสมือน ระบบเส้นประสาทที่คอยวิ่งส่งสัญญาณไปทั่วร่างกาย
- หน้าที่หลัก เป็นสะพานเชื่อม ส่งต่อข้อมูลจากเซนเซอร์ไปหาหน้าจอ และรับคำสั่งจากหน้าจอส่งกลับมาที่อุปกรณ์ควบคุม
- อุปกรณ์ในงานจริง ตัวบอร์ดไมโครคอนโทรลเลอร์ เช่น บอร์ด ESP32 สัญญาณ Wi-Fi Bluetooth หรือสาย LAN ที่ทำหน้าที่เป็นตัวกลางส่งข้อมูลขึ้นอินเทอร์เน็ต
3. Application Layer (ชั้นประยุกต์ใช้งาน) 🧠
- เปรียบเสมือน สมองที่ใช้สั่งการ และหน้าจอที่ให้เราสื่อสารกับระบบได้
- หน้าที่หลัก นำข้อมูลที่ได้มาแสดงผลให้มนุษย์เข้าใจง่ายๆ และเป็นศูนย์กลางให้เรากดปุ่มสั่งงานระบบทั้งหมด
- อุปกรณ์ในงานจริง แอปพลิเคชันบนมือถือ หน้า Dashboard สรุปข้อมูล
💡 ตัวอย่างขั้นตอนการทำงาน เซนเซอร์อ่านค่าความชื้นดิน (Layer 1) ➡️ ส่งข้อมูลผ่าน Wi-Fi ของบอร์ด (Layer 2) ➡️ ไปโชว์กราฟบนแอปมือถือ (Layer 3)
ทำความรู้จัก บอร์ด ESP32
บอร์ด ESP32 คืออะไร

ESP32 (อี-เอส-พี-สาม-สิบ-สอง) คือ ไมโครคอนโทรลเลอร์ (Microcontroller) เรียกง่ายๆว่า “สมองกลขนาดจิ๋ว” ที่ถูกสร้างขึ้นมาเพื่อควบคุมการทำงานของอุปกรณ์อิเล็กทรอนิกส์ต่างๆ
สิ่งที่ทำให้ ESP32 แตกต่างและล้ำหน้ากว่าบอร์ดรุ่นเก่าๆ คือมัน มี Wi-Fi และ Bluetooth ในตัว ทำให้มันเปรียบเสมือนกุญแจสำคัญที่ทำให้อุปกรณ์ธรรมดาๆสามารถเชื่อมต่ออินเทอร์เน็ตและกลายเป็นอุปกรณ์ IoT (Internet of Things) ได้ทันที
จุดเด่นที่ทำให้ ESP32 ได้รับความนิยม
- เก่งและเร็ว มีหน่วยประมวลผลแบบ Dual-Core (ทำงานได้ 2 แกนสมองพร้อมกัน) ทำให้ประมวลผลคำสั่งหรือเซนเซอร์หลายตัวได้ลื่นไหล
- เชื่อมต่อไร้สายได้ทันที ไม่ต้องซื้อโมดูล Wi-Fi หรือ Bluetooth มาต่อเพิ่มให้วุ่นวาย เพราะฝังมาให้แล้วในชิปเดียว
- ขั้วต่อ (GPIO) หลากหลาย มีขาเสียบสายไฟสำหรับต่อกับเซนเซอร์ มอเตอร์ หลอดไฟได้เยอะมาก รองรับการอ่านค่าทั้งแบบดิจิทัล (Digital) และอนาล็อก (Analog)
- ประหยัดพลังงาน มีโหมด Deep Sleep ที่กินไฟน้อยมาก เหมาะสำหรับการนำไปทำอุปกรณ์ที่ต้องใช้แบตเตอรี่
- ราคาคุ้มค่า เมื่อเทียบกับความสามารถระดับนี้ ESP32 ถือว่ามีราคาที่เข้าถึงได้ง่ายมากสำหรับนักศึกษาและนักพัฒนา (ประมาณ 200 บาท)
ESP32 นำไปสร้างโปรเจกต์อะไรได้บ้าง
ด้วยความที่มันต่ออินเทอร์เน็ตได้ การประยุกต์ใช้งานจึงไร้ขีดจำกัด
- ระบบสมาร์ทฟาร์ม (Smart Farm) นำบอร์ดไปต่อกับเซนเซอร์วัดความชื้นในดินและเซนเซอร์วัดอุณหภูมิ เพื่อประมวลผลและสั่งเปิด-ปิดปั๊มน้ำอัตโนมัติ
- ระบบควบคุมผ่านแอปพลิเคชัน (Blynk IoT) สร้างระบบรดน้ำต้นไม้อัจฉริยะที่สามารถดูสถานะและกดสั่งการผ่านหน้าจอมือถือได้จากทุกที่บนโลก
- ระบบแจ้งเตือน (Notification System) ทำระบบตรวจจับผู้บุกรุก และให้บอร์ดส่งข้อความแจ้งเตือนเข้าแอปพลิเคชัน LINE
ส่วนประกอบพื้นฐานบนบอร์ดที่ควรรู้จัก
เมื่อหยิบบอร์ด ESP32 ขึ้นมาดู จะพบกับส่วนประกอบหลักๆ ดังนี้
- ชิป ESP32 กล่องสี่เหลี่ยมโลหะตรงกลาง คือหัวใจหลักที่ใช้ประมวลผลและส่งสัญญาณไร้สาย
- พอร์ต USB (Micro-USB หรือ Type-C) ใช้สำหรับเสียบสายเชื่อมต่อกับคอมพิวเตอร์เพื่ออัปโหลดโค้ดโปรแกรม และใช้เป็นช่องรับไฟเลี้ยงบอร์ด
- ปุ่ม EN (Enable) ใช้สำหรับกดเพื่อรีเซ็ต (Reset) การทำงานของบอร์ด
- ปุ่ม BOOT ใช้กดค้างไว้ในบางกรณีที่บอร์ดไม่ยอมรับการอัปโหลดโค้ดจากคอมพิวเตอร์
- ขา GPIO (General Purpose Input/Output) ขาเข็มโลหะรอบๆบอร์ด ใช้สำหรับเสียบสายไฟจัมเปอร์ (Jumper) เพื่อรับข้อมูลจากเซนเซอร์ หรือส่งไฟไปสั่งการอุปกรณ์อื่น
เราจะสั่งงาน ESP32 ได้อย่างไร
บอร์ด ESP32 ไม่สามารถคิดเองได้ เราต้องเป็นคนเขียนคำสั่ง (Code) ลงไปให้มัน โดยเครื่องมือที่นิยมใช้กันมากที่สุดในหมู่นักศึกษา คือ Arduino IDE ซึ่งใช้ภาษา C/C++ ในการเขียนคำสั่ง นอกจากนี้ยังรองรับการเขียนด้วยภาษา Python (MicroPython) ด้วย
เตรียมความพร้อมก่อนเริ่มเขียนโค้ด
ขั้นตอนที่ 1 ติดตั้งโปรแกรม Arduino IDE
- ไปที่เว็บไซต์ทางการ arduino.cc
- เลือกดาวน์โหลดเวอร์ชันล่าสุด แล้วทำการ Install ลงเครื่องตามปกติเหมือนลงโปรแกรมทั่วไป
ขั้นตอนที่ 2 ติดตั้ง Driver สำหรับสื่อสารกับบอร์ด
คอมพิวเตอร์จะคุยกับบอร์ด ESP32 ผ่านสาย USB ได้ ต้องมี Driver ก่อน ซึ่งบอร์ดส่วนใหญ่ในท้องตลาดจะใช้ชิปสื่อสารอยู่ 2 ยี่ห้อ
- ชิป CP2102 (Silicon Labs) ส่วนใหญ่บอร์ดจะมีชิปตัวสี่เหลี่ยมจัตุรัสเล็ก ๆ
- ชิป CH340 (QinHeng) บอร์ดรุ่นประหยัดมักใช้ชิปตัวสี่เหลี่ยมผืนผ้าขนาดยาว
ขั้นตอนที่ 3 การเพิ่มบอร์ด ESP32 ลงใน Arduino IDE
โปรแกรมเริ่มต้นจะยังไม่รู้จักบอร์ด ESP32 เราต้องไปลงทะเบียนบอร์ดเพิ่มตามขั้นตอนนี้
3.1 เพิ่ม URL ของบอร์ด (Additional Boards Manager URLs)
- เปิดโปรแกรม Arduino IDE
- ไปที่เมนู File > Preferences
- มองหาช่องที่ชื่อว่า Additional Boards Manager URLs
- คัดลอกลิงก์ด้านล่างนี้ไปวางในช่องนั้น (หากมีลิงก์อื่นอยู่ก่อนแล้ว ให้กดปุ่มด้านขวาของช่องเพื่อขึ้นบรรทัดใหม่แล้ววางลิงก์เพิ่มเข้าไป)
https//raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
3.2 ติดตั้งบอร์ดผ่าน Boards Manager
- ไปที่แถบเครื่องมือด้านซ้าย เลือกไอคอน Boards Manager (หรือไปที่ Tools > Board > Boards Manager…)
- ในช่องค้นหา ให้พิมพ์คำว่า “esp32”
- เลือกตัวที่พัฒนาโดย Espressif Systems และกดปุ่ม Install
- รอจนโปรแกรมดาวน์โหลดและติดตั้งสำเร็จ (อาจใช้เวลา 1-3 นาทีขึ้นอยู่กับความเร็วอินเทอร์เน็ต)
ขั้นตอนที่ 4 การเลือกบอร์ดและพอร์ตก่อนเริ่มงาน
- ไปที่เมนู Tools > Board > esp32
- เลือกชื่อบอร์ดให้ตรงกับที่เราใช้ (ส่วนใหญ่คือ DOIT ESP32 DEVKIT V1 หรือ ESP32 Dev Module)
- ไปที่เมนู Tools > Port
- เลือกหมายเลข COM Port เช่น COM3 หรือ COM5
Lab 1 ควบคุมสวิตช์ไฟฟ้า (Relay Module)

https://wokwi.com/projects/461608713858843649
เป้าหมาย เพื่อให้นักศึกษาสามารถเขียนโค้ดควบคุมขา Digital Output ของ ESP32 เพื่อสั่งเปิด-ปิด Relay ซึ่งเปรียบเสมือนสวิตช์อัจฉริยะในฟาร์มของเรา
อุปกรณ์ที่ใช้
- บอร์ด ESP32
- Relay Module (1-Channel)
- สาย Jumper (แบบ M-F)
การต่อวงจร (Wiring Diagram)
ให้นักศึกษาต่อสายสัญญาณระหว่าง ESP32 และ Relay ตามรายละเอียดดังนี้
| ขาของ Relay | เชื่อมต่อกับ ESP32 | หน้าที่ |
| VCC | VIN (5V จาก USB) | จ่ายไฟเลี้ยงให้ขดลวดใน Relay |
| GND | GND | ต่อสายดินร่วมกัน |
| IN / Signal | GPIO 2 | รับคำสั่ง Digital (0 หรือ 1) จากบอร์ด |
ข้อควรระวัง บอร์ด ESP32 ทำงานที่แรงดันไฟฟ้า 3.3V เท่านั้น ห้ามเอาไฟ 5V ป้อนเข้าขา Input อื่น ๆ โดยตรง เพราะบอร์ดอาจพังได้ทันที
โค้ดตัวอย่าง
void setup() {
// ตั้งค่าขา GPIO 2 ให้ทำหน้าที่เป็น "ขาออก" (Output)
pinMode(2, OUTPUT);
}
void loop() {
// สั่งให้ Relay ทำงาน (เปิดปั๊มน้ำ)
digitalWrite(2, HIGH);
delay(5000); // หน่วงเวลาให้ปั๊มทำงาน 5 วินาที
// สั่งให้ Relay หยุดทำงาน (ปิดปั๊มน้ำ)
digitalWrite(2, LOW);
delay(5000); // หน่วงเวลาให้ปั๊มหยุดพัก 5 วินาที
}คำอธิบายการทำงาน
- pinMode(2, OUTPUT) เป็นการบอก ESP32 ว่าเราจะส่งกระแสไฟฟ้าออกที่ขา 2 นะ
- digitalWrite(2, HIGH) ส่งไฟออกไป (Logic 1) เพื่อกระตุ้นให้ Relay ทำงาน
- digitalWrite(2, LOW) ตัดไฟ (Logic 0) เพื่อให้ Relay หยุดทำงาน
- delay(5000) สั่งให้บอร์ดรอ โดยหน่วยเป็นมิลลิวินาที (5000 ms = 5 วินาที)
- คำสั่ง
pinMode(2, OUTPUT) - เปรียบเสมือนการตั้งค่าหน้าที่ให้กับขา GPIO ของบอร์ดไมโครคอนโทรลเลอร์ เพื่อเปลี่ยนสถานะจากค่าเริ่มต้นที่เป็นทางรับสัญญาณ (Input) ให้กลายเป็นทางส่งสัญญาณไฟฟ้า (Output) ซึ่งจะไปช่วยเปิดวงจรภายในให้สามารถจ่ายกระแสไฟออกมาได้เพียงพอสำหรับขับอุปกรณ์ภายนอกอย่าง Relay หากเราลืมประกาศคำสั่งนี้ ขาพินจะไม่มีกำลังไฟพอที่จะสั่งให้ Relay ทำงาน แม้ว่าเราจะเขียนโค้ดสั่งให้เป็น HIGH แล้วก็ตาม
💡 โจทย์ท้าทาย (Smart Farm Challenge)
เมื่อนักศึกษาทำ Lab 1 สำเร็จแล้ว ลองจินตนาการว่าหากเราต้องการรดน้ำต้นไม้แบบ “สั้น ๆ แต่บ่อย” ให้นักศึกษาลองแก้โค้ดให้ เปิดปั๊มน้ำ 2 วินาที และปิดพัก 10 วินาที ลองดูว่าต้องเปลี่ยนตัวเลขที่บรรทัดไหนบ้าง
คำแนะนำ สังเกตไฟ LED บนบอร์ด ESP32 จะกระพริบไปพร้อมกับเสียง “แต๊ก” ของ Relay แสดงว่าระบบทำงานถูกต้อง
Lab 2 การอ่านค่าเซนเซอร์ความชื้นดิน (Analog Input)
เป้าหมาย เรียนรู้การรับสัญญาณแบบ Analog เพื่อวัดความชื้นในดิน และทำความเข้าใจระบบการแปลงสัญญาณของ ESP32
ทฤษฎีไอที ADC Resolution คืออะไร
เนื่องจากคอมพิวเตอร์เข้าใจแต่เลข 0 กับ 1 แต่โลกแห่งความเป็นจริงมีความละเอียดมากกว่านั้น
- ESP32 มีความละเอียดของตัวแปลงสัญญาณ (ADC) อยู่ที่ 12-bit
- นั่นหมายความว่ามันจะเปลี่ยนแรงดันไฟฟ้าจากเซนเซอร์ให้เป็นตัวเลขดิจิทัลได้ตั้งแต่ 0 ถึง 4095 ระดับครับ
ทำไมต้อง Map ค่าให้เป็น 0-100%
ในงาน IoT การวัดความชื้นดินด้วยบอร์ด ESP32 มีความละเอียดของ ADC อยู่ที่ 12-bit ซึ่งจะแปลงแรงดันไฟฟ้าเป็นตัวเลข 0 ถึง 4095
ความละเอียดแบบ 12-bit สามารถสร้างขั้นบันไดของข้อมูลได้ทั้งหมด 4,096 ระดับ (แต่ในทางคอมพิวเตอร์เราเริ่มนับระดับแรกที่เลข 0 จึงได้เลขสุดท้ายเป็น 4,095 ระดับ)
- ค่า 4095 หมายถึง ดินแห้งสนิท
- ค่า 0 หมายถึง ดินเปียกที่สุด
- ปัญหา ตัวเลข 4095 นั้น อ่านเข้าใจยากสำหรับผู้ใช้งานทั่วไปหรือเกษตรกร การแปลงให้เป็น 0-100% จึงช่วยให้สื่อสารได้เข้าใจง่ายกว่ามาก
อุปกรณ์ที่ใช้
- บอร์ด ESP32
- เซนเซอร์ความชื้นดิน (Soil Moisture Sensor)
- สาย Jumper (แบบ M-F)
การต่อวงจร (Wiring Diagram)
ให้นักศึกษาต่อสายเซนเซอร์เข้ากับบอร์ดตามตารางนี้
| ขาของเซนเซอร์ | เชื่อมต่อกับ ESP32 | หน้าที่ |
| VCC | 3.3V | จ่ายไฟเลี้ยงเซนเซอร์ (ห้ามต่อ 5V) |
| GND | GND | ต่อสายดินร่วมกัน |
| AO (Analog Out) | GPIO 34 | ส่งสัญญาณแรงดันไฟฟ้า (Analog) |
โค้ดตัวอย่าง
ดูค่าที่เซนเซอร์อ่านได้ผ่านทาง Serial Monitor
void setup() {
// เริ่มการสื่อสารกับคอมพิวเตอร์ที่ความเร็ว 115200
Serial.begin(115200);
}
void loop() {
// อ่านค่าจากขา Analog 34
int rawValue = analogRead(34);
// แปลงค่า 0-4095 ให้เป็น 0-100% เพื่อให้อ่านง่าย
// สมมติว่า 4095 คือแห้งสนิท และ 0 คือเปียกที่สุด
int percent = map(rawValue, 4095, 0, 0, 100);
Serial.print("Raw Value ");
Serial.print(rawValue);
Serial.print(" | Moisture ");
Serial.print(percent);
Serial.println("%");
delay(1000); // อ่านค่าทุกๆ 1 วินาที
}โครงสร้างของฟังก์ชัน map()
ในภาษา C++ ของ Arduino เราใช้ฟังก์ชันสำเร็จรูปที่มีรูปแบบดังนี้
map(value, fromLow, fromHigh, toLow, toHigh)
| พารามิเตอร์ | ความหมาย |
| value | ตัวแปรที่เก็บค่า “ต้นทาง” ที่อ่านได้จากเซนเซอร์ |
| fromLow | ค่าต่ำสุดของช่วงต้นทาง เช่น 0 |
| fromHigh | ค่าสูงสุดของช่วงต้นทาง เช่น 4095 |
| toLow | ค่าต่ำสุดของช่วงปลายทางที่เราต้องการ เช่น 0% |
| toHigh | ค่าสูงสุดของช่วงปลายทางที่เราต้องการ เช่น 100% |
ขั้นตอนการทดลอง
- เปิด Serial Monitor ไปที่เมนู Tools > Serial Monitor และปรับความเร็วเป็น 115200 baud
- สังเกตค่าในอากาศ เมื่อเซนเซอร์แห้ง ค่าตัวเลขดิจิทัล (Raw Value) ควรจะสูงใกล้เคียง 4095
- สังเกตค่าในน้ำ ลองนำเซนเซอร์ไปจุ่มในแก้วน้ำ ค่าตัวเลขจะลดต่ำลง
💡 โจทย์ท้าทาย (IT Integration)
ให้นักศึกษานำความรู้จาก Lab 1 มาผสมกับ Lab 2 “เขียนเงื่อนไข If-Else ให้ Relay ทำงาน”
Lab 2.1 ระบบรดน้ำอัตโนมัติ (Basic Auto-Watering)
โจทย์ ให้นักศึกษาเขียนโปรแกรมให้ระบบรดน้ำทำงานเองโดยไม่ต้องใช้คนสั่ง
จุดประสงค์ ฝึกการใช้เงื่อนไข if-else มาควบคุมอุปกรณ์ตามค่าที่อ่านได้จากเซนเซอร์จริง
กำหนดเงื่อนไข
- หากค่าความชื้นดินที่อ่านได้ ต่ำกว่า 40% ให้สั่งเปิด Relay (ปั๊มน้ำ) ทันที
- หากค่าความชื้นดิน มากกว่า 80% ให้สั่งปิด Relay เพื่อประหยัดน้ำ
โค้ดตัวอย่าง
//การประกาศตัวแปร เป็นการตั้งชื่อเล่นให้กับขา (Pin) ของบอร์ด ESP32
//int (Integer)ใช้เก็บข้อมูลตัวเลขจำนวนเต็ม
int soilPin = 34; // ขาอ่านค่าความชื้นดิน
int relayPin = 2; // ขาสั่งงาน Relay
void setup() {
Serial.begin(115200);
pinMode(relayPin, OUTPUT);
}
void loop() {
int rawValue = analogRead(soilPin);
// แปลงค่า 4095 (แห้ง) - 0 (เปียก) เป็น 0-100%
int percent = map(rawValue, 4095, 0, 0, 100);
if (percent < 40) {
digitalWrite(relayPin, HIGH); // ดินแห้งเกินไป เปิดปั๊ม
Serial.println("ดินแห้ง กำลังรดน้ำ...");
} else if (percent > 80) {
digitalWrite(relayPin, LOW); // ดินเปียกชุ่มพอแล้ว ปิดปั๊ม
Serial.println("ดินชุ่มพอแล้ว หยุดรดน้ำ");
}
delay(1000);
}Lab 2.2 ระบบไฟเตือนสถานะดิน (Visual Status Monitor)
โจทย์ นำไฟ LED (แดง เหลือง เขียว) มาเพิ่ม เพื่อแสดงสถานะความชื้นในดินให้ชัดเจน
จุดประสงค์ ฝึกการจัดการขา Output หลายตัวพร้อมกันตามช่วงข้อมูลที่ซับซ้อนขึ้น
กำหนดเงื่อนไข
- ไฟสีแดง ติดเมื่อดินแห้งวิกฤต (ความชื้น < 20%) และสั่งเปิดปั๊มน้ำ
- ไฟสีเหลือง ติดเมื่อความชื้นอยู่ในระดับที่เหมาะสม (20% – 70%) และสั่งปิดปั๊มน้ำ
- ไฟสีเขียว ติดเมื่อดินเปียกมาก (> 70%) เพื่อเตือนว่าไม่ต้องรดน้ำเพิ่ม
โค้ดตัวอย่าง
int soilPin = 34;
int relayPin = 2;
int ledRed = 25, ledYellow = 26, ledGreen = 27; // กำหนดขา LED
void setup() {
pinMode(relayPin, OUTPUT);
pinMode(ledRed, OUTPUT);
pinMode(ledYellow, OUTPUT);
pinMode(ledGreen, OUTPUT);
}
void loop() {
int percent = map(analogRead(soilPin), 4095, 0, 0, 100);
// ปิดไฟทุกดวงก่อนเพื่อรีเซ็ตสถานะ
digitalWrite(ledRed, LOW); digitalWrite(ledYellow, LOW); digitalWrite(ledGreen, LOW);
if (percent < 20) {
digitalWrite(ledRed, HIGH); // สถานะวิกฤต
digitalWrite(relayPin, HIGH);
} else if (percent >= 20 && percent <= 70) {
digitalWrite(ledYellow, HIGH); // สถานะปกติ/เฝ้าระวัง
digitalWrite(relayPin, LOW);
} else {
digitalWrite(ledGreen, HIGH); // สถานะเปียกมาก
digitalWrite(relayPin, LOW);
}
delay(1000);
}Lab 2.3 ระบบรดน้ำอัจฉริยะพร้อมเสียงเตือน (Safety Alert System)
โจทย์ เพิ่มระบบเสียงแจ้งเตือนความปลอดภัยให้กับฟาร์มของเรา
จุดประสงค์ ฝึกการบริหารจัดการเวลา (Time Management) ในโค้ด และการใช้สัญญาณเสียงแจ้งเตือนสถานะวิกฤต
กำหนดเงื่อนไข
- ทำงานคล้าย Lab 2.2 แต่เพิ่ม Buzzer (ลำโพง)
- หากดินแห้งวิกฤตจนไฟสีแดงติด ให้ส่งเสียงเตือน Buzzer เป็นจังหวะสั้นๆ เพื่อเรียกเจ้าของฟาร์มมาดู
- แสดงผลค่าความชื้นเป็นตัวเลขออกทาง Serial Monitor ทุกๆ 2 วินาที
ตารางเปรียบเทียบ Active vs Passive Buzzer

| หัวข้อเปรียบเทียบ | Active Buzzer | Passive Buzzer |
| วงจรภายใน | มีวงจรสร้างความถี่ (Oscillator) ในตัว | ไม่มี วงจรสร้างความถี่ในตัว |
| การทำงาน | ป้อนไฟกระแสตรง (DC) แล้วดังทันที | ต้องป้อนสัญญาณความถี่ (Square Wave) ถึงจะดัง |
| เสียงที่ได้ | เสียงโทนเดียว (มักจะเป็นเสียง Beep แหลมๆ) | เปลี่ยนความถี่ได้ (เล่นเป็นเพลง/โน้ตดนตรีได้) |
| คำสั่งที่ใช้ | digitalWrite() | tone() หรือ PWM |
| ราคา | สูงกว่าเล็กน้อย | ถูกกว่า |
การต่อวงจร (Wiring Diagram)
| อุปกรณ์ | ขาอุปกรณ์ | ต่อกับ ESP32 | หน้าที่ |
| เซนเซอร์ดิน | VCC | 3.3V | จ่ายไฟให้เซนเซอร์ |
| GND | GND | ต่อสายดิน | |
| AO | GPIO 34 | ส่งค่าความชื้นแบบ Analog | |
| Relay | VCC | VIN (5V) | จ่ายไฟเลี้ยงขดลวด |
| GND | GND | ต่อสายดิน | |
| IN | GPIO 2 | รับคำสั่งเปิด-ปิดปั๊ม | |
| Buzzer | VCC (บวก) | GPIO 5 | รับคำสั่งส่งเสียง (Digital Output) |
| GND (ลบ) | GND | ต่อสายดิน |
ตัวอย่างโค้ด เมื่อใช้การแจ้งเตือผ่าน Active Buzzer
int soilPin = 34;
int relayPin = 2;
int buzzerPin = 5; // ขาสำหรับ Buzzer
unsigned long lastPrint = 0; // สำหรับตั้งเวลาส่งข้อมูลออก Serial
void setup() {
Serial.begin(115200);
pinMode(relayPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
}
void loop() {
int percent = map(analogRead(soilPin), 4095, 0, 0, 100);
// เงื่อนไขแจ้งเตือนด้วยเสียงเมื่อดินแห้งวิกฤต
if (percent < 15) {
digitalWrite(relayPin, HIGH); // เปิดปั๊มน้ำ
// ส่งเสียง Beep เป็นจังหวะ
digitalWrite(buzzerPin, HIGH); delay(100);
digitalWrite(buzzerPin, LOW); delay(100);
} else if (percent > 40) {
digitalWrite(relayPin, LOW); // ปิดปั๊มน้ำ
digitalWrite(buzzerPin, LOW);
}
// ส่งค่าออก Serial Monitor ทุกๆ 2 วินาที (ไม่ใช้ delay หลักเพื่อให้ Buzzer ทำงานต่อเนื่อง)
if (millis() - lastPrint > 2000) {
Serial.print("Current Soil Moisture ");
Serial.print(percent);
Serial.println("%");
lastPrint = millis();
}
}การหน่วงเวลาแบบไม่หยุดรอ (Non-Blocking Code)
การเขียนโค้ดจับเวลาที่อนุญาตให้สมองกลข้ามไปทำงานอื่นๆต่อได้ทันทีโดยไม่ต้องหยุดค้างรอเวลา
ใช้คำสั่ง millis() เพื่อจับเวลาในส่วนของลูป (Loop) แทนการใช้คำสั่ง delay()
คำอธิบาย
unsigned long (ชนิดของตัวแปร) ปกติเรามักจะคุ้นเคยกับ int แต่การจับเวลาในสมองกลจะนับเป็น “มิลลิวินาที” (1 วินาที = 1,000 มิลลิวินาที) หมายความว่าบอร์ดเปิดทำงานแค่แป๊บเดียว ตัวเลขเวลาก็จะพุ่งขึ้นไปสูงมาก การใช้ unsigned long จึงเปรียบเสมือนการสร้าง “กล่องเก็บของขนาดมหึมาที่เก็บได้เฉพาะเลขบวก” (เก็บค่าได้สูงสุดถึงประมาณ 4 พันล้าน) เพื่อไม่ให้ตัวเลขเวลาล้นกล่องจนโปรแกรมรวน
lastPrint (ชื่อตัวแปร) ตั้งชื่อให้สื่อความหมายว่า แสดงครั้งล่าสุด ทำหน้าที่จำว่า เราส่งข้อมูลออกหน้าจอครั้งล่าสุดตอนเวลาเท่าไหร่
เปรียบเทียบให้เห็นภาพง่ายๆ
การใช้ delay(2000) เหมือนเราสั่งให้ยามเฝ้าประตูว่า พอมองหน้าต่างเสร็จ ให้หลับตาไปเลย 2 วินาที แล้วค่อยตื่นมาเขียนรายงาน ซึ่งระหว่างที่หลับตา ถ้ามีขโมยเดินผ่าน ยามก็จะไม่เห็น = ระบบเตือนภัยรวน
การใช้ millis() ร่วมกับ lastPrint เหมือนแจกนาฬิกาข้อมือให้ยาม แล้วสั่งว่า ให้ลืมตาเฝ้าประตูตลอดเวลาเลยนะ (เสียง Buzzer จึงดังต่อเนื่องได้) แต่ให้คอยเหลือบดูนาฬิกา ถ้าเวลาผ่านไปครบ 2 วินาทีเมื่อไหร่ ให้เขียนรายงานแจ้งเตือน 1 ครั้ง
กลไกการทำงานในโค้ด
if (millis() - lastPrint > 2000) { // เอาเวลาปัจจุบันตั้งแล้วลบด้วยเวลาที่แสดงครั้งล่าสุด
...
lastPrint = millis(); // อัปเดตเวลาแสดงครั้งล่าสุดเป็นเวลาปัจจุบัน เพื่อเริ่มจับเวลาใหม่
}บรรทัดนี้คือการเช็คว่า เวลาปัจจุบัน (millis()) ลบกับ เวลาที่แสดงครั้งล่าสุด (lastPrint) มันห่างกันเกิน 2,000 มิลลิวินาที (2 วินาที) หรือยัง ถ้าเกินแล้วก็ให้ส่งค่าความชื้นออกหน้าจอ แล้วทำการจดเวลาปัจจุบันทับลงไปใน lastPrint เพื่อเริ่มจับเวลา 2 วินาทีรอบถัดไป
ตัวอย่างโค้ด เมื่อใช้การแจ้งเตือผ่าน Passive Buzzer (เสียงดนตรี)
// 1. กำหนดโน้ตดนตรี
#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_C5 523
// 2. กำหนดขาอุปกรณ์
int soilPin = 34; // ขาอ่านค่าเซนเซอร์ดิน
int relayPin = 2; // ขาสั่งงาน Relay (ปั๊มน้ำ)
int buzzerPin = 5; // ขาสั่งงาน Passive Buzzer
// 3. ตัวแปรสถานะ
bool isWatering = false;
int melody[] = { NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_F4, NOTE_E4 }; // ท่อนแยกเพลง
int durations[] = { 4, 8, 4, 4, 4, 2 };
void setup() {
Serial.begin(115200);
pinMode(relayPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
}
// ฟังก์ชันสำหรับเล่นเพลง Success
void playSuccessMelody() {
for (int i = 0; i < 6; i++) {
int duration = 1000 / durations[i];
tone(buzzerPin, melody[i], duration);
delay(duration * 1.30);
noTone(buzzerPin);
}
}
void loop() {
// อ่านค่าและ Map เป็น 0-100%
int rawValue = analogRead(soilPin);
int percent = map(rawValue, 4095, 0, 0, 100);
Serial.print("Moisture ");
Serial.print(percent);
Serial.println("%");
// เงื่อนไข 1 ดินแห้งวิกฤต
if (percent < 15) {
digitalWrite(relayPin, HIGH); // เปิดปั๊ม
isWatering = true;
// เสียงเตือน Alert (Beep สั้น)
tone(buzzerPin, 1000, 100);
delay(100);
noTone(buzzerPin);
}
// เงื่อนไข 2 รดน้ำจนพอใจแล้ว
else if (percent > 80 && isWatering == true) {
digitalWrite(relayPin, LOW); // ปิดปั๊ม
isWatering = false;
Serial.println("รดน้ำสำเร็จ! กำลังเล่นเพลงแสดงความยินดี...");
playSuccessMelody(); // เล่นเพลง 1 รอบ
}
delay(500); // หน่วงเวลาเล็กน้อยเพื่อให้ระบบเสถียร
}
💡 สรุปความล้ำที่นักศึกษาจะได้เห็น
- Lab 2.1 บอร์ดเริ่มมี “ความคิด” ตัดสินใจรดน้ำเองได้
- Lab 2.2 ระบบสื่อสารกับมนุษย์ผ่าน “แสง” (User Interface พื้นฐาน)
- Lab 2.3 ระบบมีความปลอดภัยและสื่อสารผ่าน “เสียง” รวมถึงการจัดการเวลาในโค้ด (Time Management) เพื่อเตรียมความพร้อมไปสู่ระบบเครือข่ายในวันถัดไป
Project 1 ระบบเฝ้าระวังโรงเรือน (Smart Monitor)
เป้าหมาย สร้างหน้าจอแสดงผลสถานะอากาศในฟาร์ม โดยใช้ DHT22 วัดอุณหภูมิ/ความชื้น และ OLED แสดงผลผ่านโปรโตคอล I2C
I2C Protocol คืออะไร

I2C (Inter-Integrated Circuit) คือ มาตรฐานการสื่อสารแบบดิจิทัลที่นิยมใช้กันมากที่สุดในงาน IoT เพราะประหยัดสายไฟและใช้งานง่ายมาก โดยใช้สายสัญญาณเพียง 2 เส้น ในการรับ-ส่งข้อมูลระหว่างบอร์ด ESP32 กับอุปกรณ์ต่างๆ เช่น จอ OLED หรือเซนเซอร์อื่นๆ ต่อเข้า Pin เดียวกันได้เลย
สายสัญญาณ 2 เส้นที่เป็นหัวใจหลัก
- SDA (Serial Data) เปรียบเสมือน “ถนน” ที่ใช้ส่งตัวข้อมูลจดหมายวิ่งไปมา
- SCL (Serial Clock) เปรียบเสมือน “จังหวะเคาะสัญญาณนาฬิกา” เพื่อคุมจังหวะให้ผู้ส่งและผู้รับทำงานพร้อมกัน (Synchronize)
การต่อใช้งานจริงกับ ESP32
- SDA ต่อตรงกับขา GPIO 21
- SCL ต่อตรงกับขา GPIO 22
อุปกรณ์ที่ใช้ใน Project 1 ระบบเฝ้าระวังโรงเรือน
- บอร์ด ESP32
- เซนเซอร์ DHT22 (วัดอุณหภูมิและความชื้นอากาศ)
- จอ OLED Display 0.96″ (I2C)
- สาย Jumper (M-M และ M-F)
การต่อวงจร (Wiring Diagram)

https://wokwi.com/projects/461653573565557761
ในโปรเจคนี้เราจะใช้ทั้งการสื่อสารแบบสายเดียว (Single Data) และแบบ I2C
| อุปกรณ์ | ขาอุปกรณ์ | ต่อกับ ESP32 | หน้าที่ |
| DHT22 | VCC | 3.3V | จ่ายไฟเลี้ยงเซนเซอร์ |
| GND | GND | ต่อสายดิน | |
| DATA | GPIO 4 | ส่งข้อมูลอุณหภูมิ/ความชื้น | |
| OLED (I2C) | VCC | 3.3V | จ่ายไฟเลี้ยงหน้าจอ |
| GND | GND | ต่อสายดิน | |
| SDA | GPIO 21 | สายรับ-ส่งข้อมูล I2C | |
| SCL | GPIO 22 | สายสัญญาณนาฬิกา I2C |
Project นี้ต้องใช้ Library (ไลบรารี)

Library ก็เปรียบเสมือน “พริกแกงสำเร็จรูป”
ลองจินตนาการว่าเราอยากทำ “แกงเขียวหวาน” (โปรเจกต์แสดงผลบนจอ OLED)
- ถ้าไม่ใช้ Library (ทำเองตั้งแต่ต้น) เราต้องเดินไปเด็ดพริก ปลูกตะไคร้ โขลกน้ำพริกแกงเอง คั้นกะทิเอง ซึ่งใช้เวลานานเป็นวันๆ และอาจจะไม่อร่อย (โค้ด Error)
- ถ้าใช้ Library (ใช้พริกแกงสำเร็จรูป) มีคนเก่งๆระดับเชฟ (นักพัฒนา) โขลกพริกแกงใส่ซองเตรียมไว้ให้เราแล้ว เราแค่ฉีกซอง เทลงหม้อ ใส่เนื้อสัตว์ (ใส่ข้อมูลของเรา) ก็ได้แกงเขียวหวานที่อร่อยทันทีภายใน 5 นาที
อุปกรณ์อย่างจอ OLED เซนเซอร์วัดอุณหภูมิ หรือแม้แต่การต่อ Wi-Fi นั้นมีการทำงานระดับฮาร์ดแวร์ที่ซับซ้อนมาก หากไม่มี Library เราอาจต้องเขียนโค้ดเป็น พันๆ บรรทัด เพื่อจัดการสัญญาณไฟฟ้าให้ถูกต้อง แต่พอใช้ Library เราเขียนโค้ดแค่ไม่กี่บรรทัดก็ใช้งานได้แล้ว
Library มีหน้าที่ซ่อนความยุ่งยากทางเทคนิคเอาไว้เบื้องหลัง และเปิดให้เราใช้งานผ่านคำสั่งสั้นๆที่เป็นภาษามนุษย์เข้าใจง่าย ทำให้เราเอาเวลาไปโฟกัสที่ไอเดียของโปรเจกต์ได้อย่างเต็มที่
การเตรียม Library
ก่อนเขียนโค้ด ให้นักศึกษาไปที่ Library Manager และติดตั้ง 2 ตัวนี้
- DHT sensor library (โดย Adafruit สำหรับ DHT22)
- Adafruit SSD1306 (สำหรับจอ OLED)
โค้ดตัวอย่าง Smart Monitor
#include <Wire.h> // เรียกใช้งาน Library ควบคุมเส้นทางการสื่อสารแบบ I2C
#include <Adafruit_GFX.h> // เรียกใช้งาน Library จัดการกราฟิก เช่น ขนาดอักษร วาดเส้น
#include <Adafruit_SSD1306.h> // เรียกใช้งาน Library สำหรับสั่งการหน้าจอ OLED โดยเฉพาะ
#include <DHT.h> // เรียกใช้งาน Library สำหรับคุยกับเซนเซอร์อุณหภูมิและความชื้น
// ตั้งค่าจอ OLED
#define SCREEN_WIDTH 128 // กำหนดความกว้างของหน้าจอ OLED เป็น 128 พิกเซล
#define SCREEN_HEIGHT 64 // กำหนดความสูงของหน้าจอ OLED เป็น 64 พิกเซล
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // สร้างตัวแปรชื่อ display ควบคุมจอ (ไม่มีขารีเซ็ต = -1)
// ตั้งค่า DHT22
#define DHTPIN 4 // กำหนดให้สายข้อมูลเซนเซอร์ (Data) ต่อกับบอร์ดที่ขา 4
#define DHTTYPE DHT22 // ระบุว่าเราใช้เซนเซอร์รุ่น DHT22
DHT dht(DHTPIN, DHTTYPE); // สร้างตัวแปรชื่อ dht เตรียมไว้สำหรับดึงค่าเซนเซอร์
void setup() { // ฟังก์ชัน setup() ทำงานแค่ "ครั้งเดียว" ตอนเปิดบอร์ด
Serial.begin(115200); // เปิดการเชื่อมต่อส่งข้อมูลเข้าคอมพิวเตอร์ที่ความเร็ว 115200
dht.begin(); // สั่งให้ตัวเซนเซอร์ DHT เริ่มทำงาน
// เริ่มต้นหน้าจอ OLED
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // ตรวจสอบว่าบอร์ดมองเห็นจอ OLED ที่ Address 0x3C หรือไม่
Serial.println(F("SSD1306 allocation failed")); // ถ้าไม่เจอจอ ให้พิมพ์แจ้ง Error บนคอมพิวเตอร์
for(;;); // สั่งให้บอร์ดหยุดทำงานค้างไว้ตรงนี้ ไม่ต้องทำอย่างอื่นต่อ
}
display.clearDisplay(); // สั่งล้างหน้าจอให้ดำสนิท เผื่อมีจุดสีค้างจากรอบก่อน
display.setTextColor(WHITE); // ตั้งค่าให้แสดงตัวอักษรเป็นสีสว่าง
}
void loop() { // ฟังก์ชัน loop() ทำงานวนซ้ำไปเรื่อยๆตลอดเวลาที่เปิดเครื่อง
float h = dht.readHumidity(); // อ่านค่าความชื้นมาเก็บในตัวแปร h (ใช้ float เพราะมีทศนิยม)
float t = dht.readTemperature(); // อ่านค่าอุณหภูมิมาเก็บในตัวแปร t (ใช้ float เพราะมีทศนิยม)
if (isnan(h) || isnan(t)) { // ตรวจสอบว่าค่า h หรือ t ออกมาสำเร็จไหม
Serial.println("Failed to read from DHT sensor!"); // ถ้าไม่สำเร็จ ให้พิมพ์แจ้งเตือนบนคอมพิวเตอร์
return; // สั่งให้จบการทำงานรอบนี้ทันที เพื่อกลับไปเริ่มบรรทัดบนสุดของ loop ใหม่
}
// ส่วนของการจัดรูปแบบแสดงผลบนหน้าจอ OLED
display.clearDisplay(); // ล้างกระดานหน้าจอให้ว่างเปล่าก่อนเริ่มเขียนรอบใหม่
display.setCursor(0, 0); // เอาเคอเซอร์ไปจ่อที่พิกัด X:0, Y:0 (มุมซ้ายบนสุดของจอ)
display.setTextSize(1); // กำหนดขนาดตัวอักษรเป็นไซส์ 1 (ขนาดเล็ก)
display.println("SMART FARM MONITOR"); // แสดงข้อความ SMART FARM MONITOR
display.setTextSize(2); // เปลี่ยนขนาดตัวอักษรเป็นไซส์ 2 (ใหญ่ขึ้นมาหน่อย)
display.setCursor(0, 20); // ย้ายเคอเซอร์ลงมาที่พิกัด X:0, Y:20
display.print("T "); display.print(t); display.println(" C"); // แสดงตัว T ตามด้วยค่าอุณหภูมิ และตัว C
display.setCursor(0, 45); // ย้ายเคอเซอร์ลงมาอีกที่พิกัด X:0, Y:45
display.print("H "); display.print(h); display.println(" %"); // แสดงตัว H ตามด้วยค่าความชื้น และ %
// Challenge ถ้าอุณหภูมิเกิน 35C ให้แจ้งเตือน
if(t > 35.0) { // ตรวจสอบเงื่อนไข ถ้าอุณหภูมิ (t) มีค่ามากกว่า 35.0 องศา
display.setTextSize(1); // ปรับขนาดอักษรกลับมาไซส์ 1
display.setCursor(85, 10); // ย้ายเคอเซอร์ไปพิกัด X:85, Y:10 แถวมุมขวาบน
display.print("HOT!"); // แสดงคำเตือนว่า HOT!
}
display.display(); // สำคัญมาก นำสิ่งที่เราจัดเตรียมไว้ทั้งหมดข้างต้น ส่งไปแสดงบนจอภาพจริงๆ
delay(2000); // สั่งให้บอร์ดหยุดรอ 2 วินาที เพื่อให้พอดีกับที่เซนเซอร์ DHT22 อัปเดตค่ารอบใหม่
}ภารกิจที่ 1 ปรับแต่งหน้าจอตามใจฉัน
เป้าหมาย ให้นักศึกษาเข้าใจการทำงานของคำสั่งจัดการข้อความและพิกัด (X, Y) บนหน้าจอ OLED
- โจทย์ 1.1 เปลี่ยนข้อความหัวกระดานจาก
"SMART FARM MONITOR"เป็นชื่อโปรเจกต์ของตัวเอง เช่น"SPTC GREENHOUSE" - โจทย์ 1.2 ปัจจุบันตัวอักษร T (อุณหภูมิ) และ H (ความชื้น) อยู่ชิดขอบซ้ายเกินไป ให้นักศึกษาขยับข้อความทั้ง 2 บรรทัด ให้เข้ามาตรงกลางจอมากขึ้น
💡 คำใบ้สำหรับนักศึกษา ลองหาคำสั่ง
display.setCursor(X, Y);แล้วปรับแก้ตัวเลขแกน X แนวนอน (หน้าจอเรากว้าง 128 พิกเซล)
ภารกิจที่ 2 เพิ่มระบบแจ้งเตือนความชื้น
เป้าหมาย ฝึกการเขียนเงื่อนไข if และการจัดวาง Layout บนหน้าจอไม่ให้ตัวหนังสือทับกัน
- โจทย์ ปัจจุบันระบบมีการแจ้งเตือนคำว่า
"HOT!"เมื่ออุณหภูมิเกิน 35 องศาแล้ว ให้นักศึกษาเพิ่มระบบแจ้งเตือนความชื้นด้วย โดย “ถ้าความชื้น (h) ต่ำกว่า 40% ให้แสดงคำว่า “DRY!” (ดินแห้ง) ที่มุมขวาล่างของหน้าจอ”
💡 คำใบ้สำหรับนักศึกษา คัดลอกโครงสร้างของบล็อก
if(t > 35.0) { ... }มาเป็นต้นแบบได้เลย แล้วเปลี่ยนตัวแปรเป็นhพร้อมกับปรับพิกัดsetCursorให้ไปอยู่มุมขวาล่างของหน้าจอ เพื่อไม่ให้ทับกับคำว่า HOT!
การสร้างภาพเคลื่อนไหว (Animation) บนจอ OLED
หลักการ “สมุดมุมกระดาษ” (Flipbook)
ให้นักศึกษาลองนึกถึงตอนเด็กๆที่เราวาดรูปการ์ตูนไว้ที่มุมสมุดหลายๆหน้า โดยแต่ละหน้าขยับแขนขาตัวการ์ตูนทีละนิด แล้วใช้นิ้วกรีดหน้ากระดาษอย่างรวดเร็ว ตาของเราจะมองเห็นตัวการ์ตูนนั้นขยับได้
บอร์ด ESP32 และหน้าจอ OLED ก็ใช้หลักการเดียวกันเป๊ะเลยครับ เรียกว่า การสร้างแอนิเมชันแบบ “เฟรมต่อเฟรม” (Frame by Frame) โดยมีหัวใจสำคัญอยู่ 4 ขั้นตอนที่ต้องทำวนลูปซ้ำๆ
- ลบกระดาน (Clear) ลบภาพเก่าทิ้งให้หมด
- วาดรูปใหม่ (Draw) วาดภาพเดิม แต่เปลี่ยนตำแหน่ง (พิกัด X หรือ Y) ไปนิดหน่อย
- โชว์ภาพ (Display) สั่งให้หน้าจอแสดงภาพที่เพิ่งวาดเสร็จ
- พักสายตา (Delay) หน่วงเวลาแป๊บเดียว เพื่อให้สมองคนเราจับภาพได้ทัน ก่อนจะกลับไปข้อ 1 ใหม่
สร้างหน้าจอ Loading Bar เท่ๆ
ให้นักศึกษานำโค้ดชุดนี้ ไปวางไว้ในฟังก์ชัน setup() แนะนำให้วางไว้ใต้ส่วน “เริ่มต้นหน้าจอ OLED”
display.clearDisplay(); // ล้างหน้าจอให้สะอาดก่อน
// 1. พิมพ์ข้อความชื่อโปรเจกต์
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(15, 20); // กะระยะให้อยู่กึ่งกลางจอ
display.print("SPTC GREENHOUSE");
// 2. วาด "กรอบเปล่า" ของหลอดโหลดข้อมูล
// รูปแบบ drawRect(แกน X, แกน Y, ความกว้าง, ความสูง, สี)
display.drawRect(14, 40, 100, 10, WHITE);
display.display(); // สั่งแสดงผลกรอบเปล่าขึ้นจอก่อน
// 3. วาด "แถบสีทึบ" ให้ค่อยๆ วิ่งจนเต็มกรอบ
// ใช้ลูป for ให้นับเลข 0 ถึง 100 เก็บไว้ในตัวแปร i
for (int i = 0; i <= 100; i++) {
// ให้ความกว้างของสี่เหลี่ยมทึบ เพิ่มขึ้นตามค่า i
display.fillRect(14, 40, i, 10, WHITE);
display.display(); // อัปเดตหน้าจอทุกครั้งที่ขยับ 1 พิกเซล
delay(20); // หน่วงเวลา 20 มิลลิวินาที (ยิ่งค่าน้อย หลอดยิ่งวิ่งเร็ว)
}
// 4. โหลดเสร็จแล้ว ค้างหน้าจอไว้ 1 วินาทีให้คนดูทัน แล้วเคลียร์ทิ้ง
delay(1000);
display.clearDisplay();
// ---------------------------------------------------การนำไปประยุกต์ใช้กับ Smart Farm
นักศึกษาสามารถนำเทคนิคการทำแอนิเมชันนี้ ไปทำให้หน้าจอระบบสมาร์ทฟาร์มของเราดูมีความเป็นมืออาชีพ (Professional) มากขึ้นได้ เช่น
- ตอนที่ปั๊มน้ำทำงาน ทำแอนิเมชันรูปหยดน้ำร่วงลงมาบนพื้นดิน
- ตอนที่พัดลมทำงาน ใช้วิธีสลับรูปวาดใบพัดลม 2 รูปสลับกันไปมาอย่างรวดเร็ว (รูปกากบาท
Xสลับกับรูปเครื่องหมายบวก+) จะดูเหมือนพัดลมกำลังหมุนอยู่จริงๆ - ตอนที่ระบบมีปัญหา ทำแอนิเมชันกรอบสี่เหลี่ยมเตือนภัยกะพริบขยายใหญ่แล้วหดลง
สอนโดย อาจารย์นุ/ครูนุ (ภานุพงศ์ สะและหมัด)
ติดต่อ Line ID : salae44476
