Smart Farm MJU คือแพลตฟอร์มเกษตรอัตโนมัติที่ออกแบบให้ทำงาน "กลางไร่" บนคอมพิวเตอร์บอร์ดเดี่ยว (NVIDIA Jetson Nano / Raspberry Pi 3B) — รับข้อมูลเซนเซอร์จากโหนด ESP32 ในแปลง รดน้ำตามตารางอัตโนมัติ ดูภาพสดจากกล้อง และวิเคราะห์พืชด้วย AI ครบในเครื่องเดียว โดยไม่พึ่งระบบ cloud แม้แต่น้อย
โครงการนี้คืออะไร
จุดตั้งต้นของโครงการคือแปลงเกษตรในพื้นที่ที่อินเทอร์เน็ตไม่เสถียร บางช่วงออฟไลน์สนิท ระบบแบบ "ส่งข้อมูลขึ้น cloud แล้วควบคุมกลับมา" จึงใช้ไม่ได้จริง — ไม่ใช่แค่ไม่สะดวก แต่พังทั้งระบบทันทีที่เน็ตหาย และแม้เน็ตจะดี การส่งข้อมูลของแปลงออกนอกเครือข่ายก็ยังเป็นประเด็นความเป็นส่วนตัวของเจ้าของแปลง
ทางออกคือย้าย "สมอง" ทั้งหมดมาไว้ในไร่ บนบอร์ดราคาไม่กี่พันบาท ทำหน้าที่เป็น hub กลาง: รับ telemetry จากโหนดเซนเซอร์ สั่งปั๊มน้ำตามตาราง (โดยเช็คความชื้นดินก่อนเสมอ) กระจายวิดีโอจากกล้อง และเรียกบริการ AI วิเคราะห์ภาพ — ผู้ใช้เปิดเบราว์เซอร์ใน WiFi ของไร่ก็ใช้งานได้ทันที
- อุปกรณ์ภาคสนามต้อง "โง่" — firmware ทำแค่อ่านเซนเซอร์/สั่งรีเลย์ ไม่มี logic ตัดสินใจ จึงเล็ก ทดสอบง่าย และพังยาก
- ทุกการตัดสินใจอยู่ที่ hub — แก้กฎการรดน้ำไม่ต้องแตะ firmware แม้แต่ตัวเดียว
- หนึ่ง path ควบคุมต่อ actuator — hub เป็นผู้สั่งปั๊มรายเดียว ไม่มีคำสั่งขัดแย้งกันจากหลายทาง
- พังแบบไหนต้อง "ปลอดภัยขึ้น" — อ่านเซนเซอร์ไม่ได้ กล้องตาย หรือ AI ล่ม ระบบยังต้องทำหน้าที่หลักได้ และต้องเอนไปทาง "น้ำท่วมไม่ได้ / เครื่องร้อนไม่ได้" เสมอ
โครงการพัฒนาต่อเนื่องตั้งแต่ มิถุนายน 2026 จนถึงปัจจุบัน ประกอบด้วย 6 subsystems ที่เขียนด้วย 3 ภาษาหลัก (TypeScript/JavaScript, Python, C++) และ firmware สำหรับบอร์ด embedded 3 แบบ ใช้งานจริงทั้งบน Jetson Nano และ Raspberry Pi 3B
สถาปัตยกรรมระบบ 3 ชั้น
ชั้นภาคสนาม คือโหนด embedded ราคาถูก: sensor-zone (ESP32 อ่าน DHT22 และเซนเซอร์ความชื้นดินแล้ว POST ทุก 2 วินาที), pump-zone (ESP-01 คุมรีเลย์ปั๊มน้ำ) และ esp32cam (กล้อง push ภาพ JPEG เข้า hub ตาม interval ที่ตั้งได้จากไกล)
ชั้น hub คือหัวใจ มี 3 บริการ: dashboard (Node.js/Express — API กลาง, ตัวจัดตารางรดน้ำ, ตัวกระจายวิดีโอ และเว็บ UI ภาษาไทย/อังกฤษ), smartfarm-ai (บริการ AI แยกต่างหาก) และ edge-ctrl (daemon C++ ดูแลอุณหภูมิของตัว hub เอง)
ชั้นผู้ใช้ คือเบราว์เซอร์ในเครือข่ายภายในของไร่ — จบ ไม่มีข้อมูลสักไบต์ออกนอกไร่
จุดเชื่อมทุกจุดใช้ HTTP + JSON ด้วย schema กลางเดียวกันคือ {device_id, metrics} ตัวอย่าง telemetry จากโหนดเซนเซอร์:
{
"device_id": "zone-a",
"metrics": { "temperature": 25.4, "humidity": 60.2, "soil_moisture": 42.0 }
}แปลว่าเปลี่ยนฮาร์ดแวร์ภาคสนามเป็นตัวใหม่ (หรือเพิ่มโหนดใหม่) hub ไม่ต้องแก้โค้ดแม้แต่บรรทัดเดียว
องค์ประกอบและเทคโนโลยี
| องค์ประกอบ | เทคโนโลยี | หน้าที่หลัก |
|---|---|---|
dashboard | Node.js, Express, React (Redux Toolkit) | API ศูนย์กลาง รับ telemetry ตารางรดน้ำอัตโนมัติ กระจายวิดีโอ MJPEG เว็บ UI |
smartfarm-ai | Python (PyTorch / TFLite / PIL + numpy) | วิเคราะห์ water stress, ปริมาณทรงพุ่ม และโรคพืชจากภาพกล้อง |
edge-ctrl | C++17, libgpiod, systemd | daemon คุมพัดลมระบายความร้อนตู้ hub แบบ hysteresis, อ่าน DHT22, sync นาฬิกา RTC |
sensor-zone | ESP-IDF (C, ESP32) | โหนดเซนเซอร์: DHT22 + ความชื้นดิน ส่ง telemetry ทุก 2 วินาที |
pump-zone | Arduino (ESP-01) | รีเลย์ปั๊มน้ำ + dead-man cutoff + watchdog + OTA |
esp32cam | Arduino (ESP32-CAM) | กล้องถ่ายภาพตาม interval, push เข้า hub, รับ config จากไกล |
รายละเอียดที่น่าสนใจของแต่ละตัวอยู่ใน README ของแต่ละโฟลเดอร์ใน repository — ส่วนสองหัวข้อถัดไปคือเรื่องที่ผมอยากเล่ามากที่สุด
ความปลอดภัยคือหัวใจของดีไซน์
ปั๊มน้ำคือ actuator ตัวเดียวในระบบที่สร้างความเสียหายจริงได้ (น้ำท่วมแปลง) จึงได้การออกแบบมากที่สุด แบบ defense-in-depth 4 ชั้น:
- Hub auto-off — ทุกคำสั่ง "เปิด" ต้องมีอายุ 1–60 นาทีเสมอ หมดเวลาแล้ว hub สั่งปิดเองและจดลง log
- Firmware dead-man cutoff — ตัว ESP-01 เองปฏิเสธการทำงานเกิน 5 นาที ตัดรีเลย์ที่ตัวปั๊มโดยไม่สนว่า hub จะสั่งอะไร — hub ตายก็ปั๊มก็ดับเอง
- Watchdog + network recovery — watchdog 8 วินาทีกัน firmware ค้าง และถ้า WiFi ขาดต่อเนื่อง 120 วินาที อุปกรณ์จะปิดปั๊มแล้วรีสตาร์ทเอง
- UI กันมนุษย์พลาด — สั่งเปิดปั๊มมือขณะโหมด AUTO จะถูกปฏิเสธ (HTTP 409) แต่สั่ง "ปิด" ได้เสมอเพื่อ emergency stop
ชั้นวิเคราะห์ข้อมูลก็ออกแบบด้วยหลักเดียวกัน: Moisture Guard เช็คความชื้นดินเฉลี่ยก่อนทุกรอบ (ชุ่มพอ = ข้าม) โดยใช้เฉพาะข้อมูลสดอายุไม่เกิน 5 นาที ค่าความชื้นติดลบถือเป็นเซนเซอร์เสีย (โพรบหลุดจากดิน) ไม่นับเข้าค่าเฉลี่ย และถ้าไม่มีข้อมูลสดเลย ระบบเลือก fail-open — รดตามตาราง เพราะ "ไม่รดน้ำเลย" อันตรายต่อพืชมากกว่า
หลัก "พังต้องปลอดภัยขึ้น" นี้ใช้ทั่วระบบ ไม่ใช่แค่ปั๊ม — daemon edge-ctrl ที่คุมพัดลมตู้ hub อ่านอุณหภูมิไม่ได้ก็สั่งเปิดพัดลมทันที (fail-to-cooling) และ override จากแดชบอร์ดมีได้แค่คำสั่งเดียวคือ "เปิดเพิ่ม" ห้ามปิด พร้อมวันหมดอายุฝังไว้ในคำสั่งเสมอ
AI ที่ขอบสนาม (Edge AI)
งาน AI ทั้งสามอย่างถูกเลือกระดับ "ความฉลาด" ให้เหมาะกับงานจริง ไม่ใช่ใช้ deep learning กับทุกอย่าง:
- Water stress — rule engine ล้วน: ความชื้นดินเป็นตัวตั้งระดับความเสี่ยง แล้วปรับด้วยอุณหภูมิ/ความชื้นอากาศ ออกมาเป็น 3 ระดับ พร้อมเหตุผลย้อนกลับ (factors) — โปร่งใส ตรวจสอบได้ รันได้ทุกเครื่อง เป็นข้อมูลประกอบการตัดสินใจ ไม่สั่งปั๊มโดยตรง
- Canopy coverage — computer vision คลาสสิก: แปลงภาพกล้องเป็น HSV แล้ววัดสัดส่วนพิกเซลสีเขียวเป็น % ทรงพุ่ม ใช้แค่ PIL + numpy รันสบายบน Raspberry Pi RAM 1 GB
- โรคพืช — งานเดียวที่คู่ควร CNN จริง: MobileNetV2 จากชุดข้อมูล PlantVillage 38 คลาส รัน PyTorch บน Jetson และ TFLite บน Raspberry Pi (PyTorch ไม่มี wheel สำหรับ ARM 32-bit จึงเขียน converter แปลงผ่าน ONNX พร้อมตรวจสอบว่าผลลัพธ์เท่าเดิมก่อนใช้)
สถาปัตยกรรมฝั่ง AI แยกเป็น container ของตัวเอง และ dashboard ไม่รู้จัก AI เลย — รู้แค่ว่ามี HTTP endpoint ให้เรียก ผลคือ AI ล่อย ระบบรดน้ำ กล้อง และแดชบอร์ดยังทำงานครบ แค่แสดงข้อมูลเก่าพร้อมป้าย aiOnline: false — ปัญญาประดับที่ถอดออกได้ ไม่ใช่อวัยวะที่พังแล้วทั้งตัวตาย
วิศวกรรมที่น่าสนใจ
ผลลัพธ์และบทเรียน
ระบบใช้งาน production จริงทั้งบน Jetson Nano และ Raspberry Pi 3B แดชบอร์ดมี 5 หน้า (ภาพรวม, กล้อง, รดน้ำ, AI insights, ตั้งค่า) รองรับสองภาษา และหลังจากนี้มีโปรเจ็คถัดไปคือ mushroom-house (โรงเห็ด) ที่แยก codebase ออกไปตามแพลตฟอร์มเดียวกันนี้
บทเรียนที่จดไว้แล้วใช้จริง:
- อย่ามองแต่ model — ดู runtime ปลายทางก่อน: PyTorch ไม่มี wheel สำหรับ ARM 32-bit เลย ทำให้ต้องสร้างเส้นทางแปลงโมเดล (torch → ONNX → TFLite) พร้อมการตรวจสอบความเท่ากันของผลลัพธ์ตั้งแต่แรก ถ้ารอเจอตอน deploy คงช้าไปหลายสัปดาห์
- API ของระบบปฏิบัติการเปลี่ยนได้เสมอ: libgpiod ข้ามเวอร์ชัน v1/v2 ใช้ API ต่างกันเกือบทั้งหมด การเขียน layer รองรับทั้งคู่ตั้งแต่ต้น (พร้อม fallback ไป
gpiosetและ sysfs) ช่วยให้โค้ดชุดเดียวรันได้ทั้ง Jetson ระบบเก่าและ Raspberry Pi ใหม่ - ออกแบบ persistence ตามตัว storage จริง: ไฟล์ settings แบบ rewrite ทั้งไฟล์ทุกครั้งที่มี telemetry สร้าง load เขียนมหาศาลบน SD card เปลี่ยนเป็น JSONL append-only + ring buffer แก้ปัญหาที่ราก
- "อุปกรณ์โง่" คือ decision ที่คุ้มที่สุดของโครงการ: ทุกครั้งที่ logic รดน้ำเปลี่ยน แก้ที่ hub ตัวเดียว ไม่ต้อง reflash อุปกรณ์กลางแปลง และเมื่อ firmware เล็กมาก มันก็แข็งแรงมากด้วย
แผนต่อยอดอยู่ใน roadmap ของระบบ AI เอง — เพิ่มความสามารถวิเคราะห์ภาพต่อเนื่อง เชื่อมประวัติ water stress กับตารางรดน้ำ และขยายไปยังโรงเห็ดที่มีความต้องการควบคุมสิ่งแวดล้อมละเอียดกว่านี้