WiFi State Machine — หัวใจของระบบ IoT ที่ไม่มีวันล่ม
ในโลกของ IoT สิ่งที่น่ากลัวที่สุดไม่ใช่อุปกรณ์พัง แต่คือ อุปกรณ์ที่ค้างเงียบโดยไม่มีใครรู้ — เซ็นเซอร์วัดอุณหภูมิโรงงานที่หยุดส่งข้อมูลตั้งแต่เที่ยงคืน ระบบรดน้ำอัตโนมัติที่ WiFi หลุดแล้วไม่กลับมา หรือบอร์ด ESP32 ในกล่องควบคุมที่ค้างอยู่กับ WiFi.begin() ไปตลอดกาล
โปรแกรมข้างต้นแก้ปัญหานี้ด้วยแนวคิดที่เรียกว่า State Machine ซึ่งเป็นหนึ่งในทักษะพื้นฐานที่ช่างและนักพัฒนา IoT ทุกคนต้องเข้าใจครับ

State Machine คืออะไร?
ลองนึกภาพไฟจราจรครับ — มันไม่ได้ "คิด" ซับซ้อน แค่วนระหว่าง 3 สถานะ คือ แดง เหลือง เขียว และในแต่ละสถานะก็ทำหน้าที่ของตัวเองชัดเจน ไม่ก้าวก่ายกัน
WiFi State Machine ในโค้ดนี้ทำงานเหมือนกันเลยครับ มี 3 สถานะ:
WIFI_IDLE — บอร์ดกำลังรอเวลาก่อนลองเชื่อมต่อใหม่ ไม่ได้ค้างหรือหยุดทำงาน แค่นับเวลาอยู่เงียบๆ พอครบกำหนดก็สั่ง WiFi.begin() แล้วเปลี่ยนสถานะทันที
WIFI_CONNECTING — กำลังรอผลการเชื่อมต่อ ถ้าสำเร็จก็เดินหน้าต่อ แต่ถ้าเกิน timeout ที่กำหนดก็ไม่รอต่อ ตัดทิ้งแล้วกลับไป IDLE เพื่อลองใหม่ในรอบถัดไป
WIFI_CONNECTED — เชื่อมต่อสำเร็จและกำลังทำงานปกติ แต่ยังคอย "เฝ้า" อยู่ตลอด ถ้าสัญญาณหลุดขึ้นมาเมื่อไหร่ก็จะรู้ทันทีและกลับเข้าสู่กระบวนการ retry อัตโนมัติ

ทำไมถึงสำคัญ?
นักพัฒนา IoT มือใหม่มักเขียนโค้ดแบบนี้ครับ:
cppWiFi.begin(SSID, PASS);
while (!WiFi.isConnected()) {
delay(500);
}
ดูเผินๆ ก็ใช้ได้ แต่ปัญหาคือ บอร์ดจะค้างอยู่ใน while นั้นตลอดไป ถ้า WiFi ไม่ยอมต่อ ไม่มีการ timeout ไม่มีการ retry อัจฉริยะ และที่สำคัญคือ งานอื่นทุกอย่างหยุดหมด ไม่ว่าจะเป็นการอ่านเซ็นเซอร์ การกะพริบ LED หรือการตอบสนองต่อปุ่มกด
State Machine แก้ปัญหานี้ได้หมดครับ เพราะฟังก์ชัน handleWiFi() ถูกเรียกใน loop() ทุกรอบโดยไม่มี delay ไม่มีการค้าง บอร์ดจึงทำงานหลายอย่างพร้อมกันได้อย่างราบรื่น

ภาพรวมของระบบ IoT ที่สมบูรณ์
WiFi State Machine เป็นแค่ชิ้นส่วนเดียวในระบบ IoT ที่ดีครับ ยังมีอีกหลายเรื่องที่ต้องเข้าใจ เช่น:

MQTT State Machine — จัดการการเชื่อมต่อกับ broker และการ subscribe/publish
Sensor Manager — อ่านค่าเซ็นเซอร์อย่างถูกจังหวะโดยไม่ block การทำงานอื่น
LED Indicator — สื่อสารสถานะระบบให้ผู้ใช้เห็นได้ด้วยตา
Watchdog Timer — รีสตาร์ทบอร์ดอัตโนมัติถ้าระบบค้างนานเกินกำหนด
OTA Update — อัปเดตโปรแกรมผ่าน WiFi โดยไม่ต้องถอดสาย

ทุกชิ้นส่วนเหล่านี้ทำงานร่วมกันใน loop() เดียวกัน โดยไม่มีใครขัดขวางใคร นั่นคือปรัชญาของการเขียน firmware IoT ที่ดีครับ

ตัวอย่างโปรแกรม
// ════════════════════════════════════════════════════
// HANDLE WIFI — State Machine
// ════════════════════════════════════════════════════
void handleWiFi() {
switch (wifiState) {

case WIFI_IDLE:
if (millis() - lastWifiRetryMs >= WIFI_RECONNECT_MS) {
Serial.printf("🔄 WiFi retry: %s ...\n", WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASS);
wifiState = WIFI_CONNECTING;
wifiConnectStart = millis();
}
break;

case WIFI_CONNECTING:
if (WiFi.isConnected()) {
wifiState = WIFI_CONNECTED;
Serial.printf("✅ WiFi OK — IP: %s\n",
WiFi.localIP().toString().c_str());
} else if (millis() - wifiConnectStart >= WIFI_CHECK_TIMEOUT_MS) {
Serial.println("⚠️ WiFi timeout — จะลองใหม่...");
WiFi.disconnect();
wifiState = WIFI_IDLE;
lastWifiRetryMs = millis();
}
break;

case WIFI_CONNECTED:
if (!WiFi.isConnected()) {
Serial.println("⚠️ WiFi หลุด — รอ retry...");
wifiState = WIFI_IDLE;
lastWifiRetryMs = millis();
setLedMode(LED_BLINK);
}
break;
}
}
สรุป
ถ้าคุณอยากสร้างอุปกรณ์ IoT ที่ เปิดทิ้งไว้ได้หลายเดือนโดยไม่ต้องรีสตาร์ทมือ การเข้าใจ State Machine คือจุดเริ่มต้นที่ขาดไม่ได้ครับ โค้ดไม่กี่สิบบรรทัดนี้คือความแตกต่างระหว่างระบบที่ "ใช้งานได้" กับระบบที่ "เชื่อถือได้" ในโลกจริง