เนื้อหาในบทความ
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 ดูสิ!