บทความ: สร้างระบบสื่อสารแบบเรียลไทม์ด้วย ESP32 WebSocket

เรียนรู้วิธีการใช้ WebSocket กับ ESP32 เพื่อสร้างระบบสื่อสารแบบเรียลไทม์สำหรับโปรเจกต์ IoT พร้อมตัวอย่างโค้ดและคำอธิบายภาษาไทย

📅 11 มีนาคม 2026⏱️ 15 นาที🎯 ระดับกลาง

WebSocket คืออะไร?

WebSocket เป็นโปรโตคอลการสื่อสารแบบ Full-Duplex ที่ช่วยให้ Client และ Server สามารถส่งข้อมูลไปมาได้ตลอดเวลาผ่านการเชื่อมต่อเดียว ต่างจาก HTTP ที่ต้องทำการ Request และ Response ทุกครั้ง

🔑 ข้อดีของ WebSocket

  • เรียลไทม์: ส่งข้อมูลได้ทันทีโดยไม่ต้องรอ
  • ประหยัด Bandwidth: ไม่ต้องส่ง Header ซ้ำๆ
  • Low Latency: การตอบสนองที่รวดเร็ว
  • Bidirectional: ส่งข้อมูลไปมาได้พร้อมกัน

สำหรับโปรเจกต์ IoT ที่ต้องการอัปเดตข้อมูลแบบเรียลไทม์ เช่น ระบบควบคุมอุณหภูมิ, การตรวจสอบค่า Sensor, หรือ Dashboard ควบคุมอุปกรณ์ WebSocket จึงเป็นตัวเลือกที่เหมาะสมที่สุด

ทำไมต้องใช้ WebSocket กับ ESP32?

การเลือกโปรโตคอลสื่อสารที่เหมาะสมเป็นสิ่งสำคัญสำหรับโปรเจกต์ IoT นี่คือการเปรียบเทียบระหว่าง WebSocket และวิธีอื่นๆ

❌ HTTP Polling (แบบเดิม)

  • • Client ต้อง Request ข้อมูลทุกๆ วินาที
  • • สิ้นเปลือง Bandwidth และทรัพยากร
  • • มี Latency สูง (ต้องรอ Cycle ถัดไป)
  • • Server ต้องรองรับ Request จำนวนมาก

✅ WebSocket (แนะนำ)

  • • เชื่อมต่อครั้งเดียว สื่อสารได้ตลอด
  • • Server สามารถ Push ข้อมูลได้ทันที
  • • Low Latency และ Real-time
  • • ประหยัดทรัพยากร ESP32

📦 อุปกรณ์ที่ต้องการ

🔧

Hardware

  • • ESP32 Board (DevKit, NodeMCU, หรือ compatible)
  • • USB Cable สำหรับ Programming
  • • Sensors ตามต้องการ (DHT11, DHT22, BME280, etc.)
  • • Jumper Wires และ Breadboard (ถ้าต่อ Sensor)
💻

Software

  • • Arduino IDE 2.x หรือ PlatformIO
  • • Web Browser (Chrome, Firefox, Edge)
  • • Library: WebSockets โดย Markus Sattler
  • • Library: WiFi (built-in)
🌐

Network

  • • WiFi 2.4GHz (ESP32 ไม่รองรับ 5GHz)
  • • ความเร็ว Internet: ขั้นต่ำ 1 Mbps (เพียงพอสำหรับ IoT)
  • • Router ที่รองรับ multiple connections

🔧 การติดตั้ง Library

ก่อนเริ่มเขียนโค้ด เราต้องติดตั้ง Library ที่จำเป็นก่อน

1. เปิด Arduino IDE

ไปที่ Sketch → Include Library → Manage Libraries

2. ค้นหา Library

พิมพ์ WebSockets ในช่องค้นหา

3. ติดตั้ง

เลือก WebSockets โดย Markus Sattler แล้วกด Install

🚀 สร้าง WebSocket Server บน ESP32

ต่อไปนี้คือโค้ดสำหรับสร้าง WebSocket Server ที่จะรับข้อมูลจาก Sensor และส่งไปยัง Client แบบเรียลไทม์

#include <WiFi.h>
#include <WebSocketsServer.h>

// ตั้งค่า WiFi
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";

// สร้าง WebSocket Server ที่ port 81
WebSocketsServer webSocket = WebSocketsServer(81);

// ฟังก์ชันจัดการเมื่อมี WebSocket Event
void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) {
  switch(type) {
    case WStype_DISCONNECTED:
      Serial.printf("[%u] Disconnected!\n", num);
      break;
    case WStype_CONNECTED:
      {
        IPAddress ip = webSocket.remoteIP(num);
        Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num,
          ip[0], ip[1], ip[2], ip[3], payload);
        // ส่งข้อความต้อนรับไปยัง Client
        webSocket.sendTXT(num, "Connected");
      }
      break;
    case WStype_TEXT:
      Serial.printf("[%u] get Text: %s\n", num, payload);
      // ส่งข้อมูลกลับไปยัง Client (Echo)
      webSocket.sendTXT(num, payload);
      break;
  }
}

void setup() {
  Serial.begin(115200);

  // เชื่อมต่อ WiFi
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // เริ่มต้น WebSocket Server
  webSocket.begin();
  webSocket.onEvent(webSocketEvent);
  Serial.println("WebSocket Server started");
}

void loop() {
  webSocket.loop();

  // ทุกๆ 2 วินาที ส่งข้อมูลจำลอง Sensor
  static unsigned long lastSend = 0;
  if (millis() - lastSend > 2000) {
    lastSend = millis();

    // จำลองค่า Sensor (อุณหภูมิและความชื้น)
    float temperature = random(2000, 3500) / 100.0;
    float humidity = random(4000, 8000) / 100.0;

    // สร้าง JSON String
    String json = "{\"temp\": " + String(temperature) +
                   ", \"humidity\": " + String(humidity) + "}";

    // ส่งข้อมูลไปยัง Client ทุกตัวที่เชื่อมต่อ
    webSocket.broadcastTXT(json);

    Serial.println("Sent: " + json);
  }
}

💡 คำอธิบาย: โค้ดนี้สร้าง WebSocket Server ที่ port 81 เมื่อ Client เชื่อมต่อ จะส่งข้อมูลจำลอง Sensor (อุณหภูมิและความชื้น) ไปยัง Client ทุกๆ 2 วินาที ในรูปแบบ JSON

📊 สร้าง Dashboard เพื่อรับข้อมูล

ต่อไปเราจะสร้าง HTML/JavaScript Dashboard ง่ายๆ เพื่อแสดงข้อมูลจาก ESP32

<!DOCTYPE html>
<html>
<head>
  <title>ESP32 WebSocket Dashboard</title>
  <style>
    body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
    .card { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
              color: white; padding: 20px; border-radius: 10px; margin: 10px 0; }
    .value { font-size: 48px; font-weight: bold; }
    .label { font-size: 18px; opacity: 0.9; }
    #status { padding: 10px; border-radius: 5px; margin-bottom: 20px; }
    .connected { background: #10b981; color: white; }
    .disconnected { background: #ef4444; color: white; }
  </style>
</head>
<body>
  <h1>ESP32 WebSocket Dashboard</h1>
  <div id="status" class="disconnected">⚫ Disconnected</div>

  <div class="card">
    <div class="label">🌡️ อุณหภูมิ</div>
    <div class="value"><span id="temp">--</span>°C</div>
  </div>

  <div class="card">
    <div class="label">💧 ความชื้น</div>
    <div class="value"><span id="humidity">--</span>%</div>
  </div>

  <script>
    // เชื่อมต่อ WebSocket (แก้ IP เป็น IP ของ ESP32 คุณ)
    const ws = new WebSocket('ws://192.168.1.100:81');

    ws.onopen = function() {
      console.log('Connected');
      document.getElementById('status').className = 'connected';
      document.getElementById('status').innerHTML = '🟢 Connected';
    };

    ws.onclose = function() {
      console.log('Disconnected');
      document.getElementById('status').className = 'disconnected';
      document.getElementById('status').innerHTML = '⚫ Disconnected';
      // พยายามเชื่อมต่อใหม่ทุกๆ 3 วินาที
      setTimeout(function() { location.reload(); }, 3000);
    };

    ws.onmessage = function(event) {
      console.log('Received: ' + event.data);

      // แปลง JSON String เป็น Object
      const data = JSON.parse(event.data);

      // อัปเดตค่าใน Dashboard
      document.getElementById('temp').innerHTML = data.temp.toFixed(1);
      document.getElementById('humidity').innerHTML = data.humidity.toFixed(1);
    };
  </script>
</body>
</html>

⚠️ ข้อควรระวัง: อย่าลืมเปลี่ยน 192.168.1.100 เป็น IP Address ของ ESP32 คุณเอง (ดูได้จาก Serial Monitor)

🎯 เทคนิคขั้นสูง

1. การส่งข้อมูลจริงจาก Sensor

#include <DHT.h>

#define DHTPIN 4
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  dht.begin();
  // ... rest of setup
}

void loop() {
  // ... webSocket.loop()

  if (millis() - lastSend > 2000) {
    float temp = dht.readTemperature();
    float humi = dht.readHumidity();

    String json = "{\"temp\": " + String(temp) +
                   ", \"humidity\": " + String(humi) + "}";

    webSocket.broadcastTXT(json);
  }
}

2. การรับคำสั่งจาก Dashboard

case WStype_TEXT:
  Serial.printf("[%u] Received: %s\n", num, payload);

  // แปลง String เป็น Integer (เช่น "LED_ON" หรือ "LED_OFF")
  String message = reinterpret_cast<char*>(payload);

  if (message == "LED_ON") {
    digitalWrite(LED_PIN, HIGH);
    webSocket.sendTXT(num, "LED turned ON");
  } else if (message == "LED_OFF") {
    digitalWrite(LED_PIN, LOW);
    webSocket.sendTXT(num, "LED turned OFF");
  }
  break;

3. การจัดการ Multiple Clients

WebSocket Library รองรับหลาย Client พร้อมกันโดยอัตโนมัติ ใช้ broadcastTXT() เพื่อส่งข้อมูลไปทุก Client พร้อมกัน:

// ส่งข้อมูลไปยัง Client ทุกตัว
webSocket.broadcastTXT("Hello everyone!");

// ส่งข้อมูลไปยัง Client ที่ระบุ (num = client ID)
webSocket.sendTXT(num, "Private message");

// ส่งข้อมูลไปยัง Client ทุกตัว ยกเว้น sender
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
  if(i != num && webSocket.connectedClients() > 0) {
    webSocket.sendTXT(i, "Message from another user");
  }
}

🔧 การแก้ปัญหาที่พบบ่อย

❌ ปัญหา: เชื่อมต่อ WebSocket ไม่ได้

อาการ: Dashboard ขึ้น "Disconnected" ตลอด

สาเหตุ: IP Address ผิด, Firewall บล็อก, หรือ Port ผิด

วิธีแก้:

  • • ตรวจสอบ IP Address ของ ESP32 จาก Serial Monitor
  • • ตรวจสอบว่า ESP32 และ Computer อยู่ในเครือข่ายเดียวกัน
  • • ลอง Ping IP ของ ESP32 เพื่อยืนยันการเชื่อมต่อ
  • • ปิด Firewall ชั่วคราวเพื่อทดสอบ

⚠️ ปัญหา: ข้อมูลไม่อัปเดต

อาการ: ค่าใน Dashboard ไม่เปลี่ยนแปลง

สาเหตุ: JSON format ผิด, Sensor ไม่ทำงาน

วิธีแก้:

  • • ตรวจสอบ JSON format ด้วย JSON Validator
  • • ดู Serial Monitor ว่ามีการส่งข้อมูลหรือไม่
  • • ทดสอบ Sensor แยกจากระบบ WebSocket

🐌 ปัญหา: อัปเดตช้าเกินไป

อาการ: ข้อมูลอัปเดตไม่ทันที

สาเหตุ: Sampling interval นานเกินไป

วิธีแก้:

  • • ลดเวลา interval (เช่นจาก 2000ms เป็น 500ms)
  • • แต่ระวัง: ถ้าเร็วเกินไปอาจทำให้ระบบไม่เสถียร
  • • ใช้ AsyncWebServer แทน WebServer ปกติ (ขั้นสูง)

📝 สรุป

ในบทความนี้ เราได้เรียนรู้:

  • ✅ หลักการทำงานของ WebSocket
  • ✅ วิธีสร้าง WebSocket Server บน ESP32
  • ✅ การสร้าง Dashboard เพื่อรับข้อมูลแบบเรียลไทม์
  • ✅ เทคนิคขั้นสูง: Sensor integration, การควบคุม, Multiple clients
  • ✅ การแก้ปัญหาที่พบบ่อย

ตอนนี้คุณสามารถนำความรู้นี้ไปประยุกต์ใช้กับโปรเจกต์ IoT ของคุณได้แล้ว! ลองสร้างระบบควบคุมอุณหภูมิ, ระบบรดน้ำอัตโนมัติ, หรือ Dashboard ควบคุม Smart Home ดูสิ!

🚀 บทความที่เกี่ยวข้อง