📑 เนื้อหาในบทความ
🌐 ภาพรวม ESP32 Web Server
ESP32 มีความสามารถในการสร้าง Web Server ที่ทรงพลังด้วย WiFi ในตัว ซึ่งช่วยให้คุณสามารถ:
- ควบคุม GPIO (LED, Relay, Motor) ผ่านเว็บเบราว์เซอร์
- แสดงข้อมูลจาก Sensor (อุณหภูมิ, ความชื้น, แรงดัน)
- สร้าง Dashboard สำหรับ Smart Home
- รับค่าจากผู้ใช้ผ่าน Form
- อัปเดต OTA (Over-The-Air) ผ่านเว็บ
💡 เคล็ดลับ: Web Server บน ESP32 ทำงานได้ดีที่สุดเมื่อใช้ในเครือข่าย WiFi เดียวกับอุปกรณ์ที่เชื่อมต่อ เพื่อความเสถียรและล่าช้าน้อยที่สุด
📋 ข้อกำหนดเบื้องต้น
Hardware ที่ต้องใช้:
- ESP32 Board (ESP32 DevKit, NodeMCU-32, หรือตระกูล ESP32 อื่นๆ)
- USB Cable สำหรับเชื่อมต่อกับคอมพิวเตอร์
- LED (ตัวอย่างนี้ใช้ LED ในตัวบอร์ด)
- Sensor (DHT11/DHT22 ถ้าต้องการแสดงข้อมูล - ถือว่าเป็นตัวเลือก)
Software ที่ต้องใช้:
- Arduino IDE (พร้อม ESP32 Board Support)
- Web Browser (Chrome, Firefox, Safari)
- Serial Monitor (ตรวจสอบ IP Address)
ระดับความยาก:
🚀 สร้าง Web Server พื้นฐาน
เริ่มต้นด้วยการสร้าง Web Server แบบง่ายที่แสดงข้อความ "Hello World" บนหน้าเว็บ
#include <WiFi.h>
#include <WebServer.h>
// แทนที่ด้วยข้อมูล WiFi ของคุณ
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// สร้าง Web Server object ที่พอร์ต 80
WebServer server(80);
// ฟังก์ชันจัดการเมื่อมีคนเข้าหน้าแรก
void handleRoot() {
server.send(200, "text/html", "<h1>Hello World from ESP32!</h1><p>นี่คือ Web Server แรกของคุณ</p>");
}
void setup() {
Serial.begin(115200);
// เชื่อมต่อ WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("WiFi Connected. IP Address: ");
Serial.println(WiFi.localIP()); // แสดง IP ที่ Serial Monitor
// ตั้งค่าเส้นทาง (routes)
server.on("/", handleRoot); // หน้าแรก
// เริ่มต้น Web Server
server.begin();
Serial.println("HTTP server started");
}
void loop() {
server.handleClient(); // รองรับการเชื่อมต่อจาก client
}📝 คำอธิบาย: โค้ดนี้สร้าง Web Server ที่แสดง "Hello World" เมื่อคุณเข้าผ่าน IP Address ของ ESP32
วิธีใช้งาน:
- อัปโหลดโค้ดไปยัง ESP32
- เปิด Serial Monitor (115200 baud)
- รอจนกว่าจะเชื่อมต่อ WiFi และแสดง IP Address
- เปิด Web Browser แล้วพิมพ์ IP Address ที่ได้
- คุณจะเห็นหน้าเว็บ "Hello World from ESP32!"
💡 ควบคุม GPIO ผ่าน Web
ตอนนี้เราจะสร้าง Web Interface ที่สามารถเปิด/ปิด LED ได้ โดยใช้ปุ่มกดบนหน้าเว็บ
#include <WiFi.h>
#include <WebServer.h>
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
WebServer server(80);
// ขา LED ในตัวบอร์ด ESP32 ส่วนใหญ่คือ GPIO 2
const int ledPin = 2;
bool ledState = false;
// หน้าเว็บ HTML ที่มีปุ่มเปิด/ปิด LED
void handleRoot() {
String html = "<!DOCTYPE html><html>";
html += "<head><meta charset='UTF-8'>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
html += "<title>ESP32 LED Control</title>";
html += "<style>";
html += "body { font-family: Arial, sans-serif; text-align: center; margin-top: 50px; }";
html += "button { padding: 15px 30px; font-size: 18px; margin: 10px; cursor: pointer; }";
html += ".on { background-color: #4CAF50; color: white; }";
html += ".off { background-color: #f44336; color: white; }";
html += "</style>";
html += "</head><body>";
html += "<h1>ESP32 LED Control</h1>";
html += "<p>สถานะ LED: <strong>" + String(ledState ? "เปิด" : "ปิด") + "</strong></p>";
html += "<a href='/led/on'><button class='on'>เปิด LED</button></a>";
html += "<a href='/led/off'><button class='off'>ปิด LED</button></a>";
html += "</body></html>";
server.send(200, "text/html", html);
}
// เปิด LED
void handleLedOn() {
digitalWrite(ledPin, HIGH);
ledState = true;
Serial.println("LED turned ON");
handleRoot(); // กลับไปหน้าแรก
}
// ปิด LED
void handleLedOff() {
digitalWrite(ledPin, LOW);
ledState = false;
Serial.println("LED turned OFF");
handleRoot(); // กลับไปหน้าแรก
}
// หน้า 404
void handleNotFound() {
server.send(404, "text/plain", "404: Not found");
}
void setup() {
Serial.begin(115200);
pinMode(ledPin, OUTPUT);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
// ตั้งค่า routes
server.on("/", handleRoot);
server.on("/led/on", handleLedOn);
server.on("/led/off", handleLedOff);
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
}
void loop() {
server.handleClient();
}✅ ผลลัพธ์: เมื่อคุณกดปุ่ม "เปิด LED" หรือ "ปิด LED" บนหน้าเว็บ LED บนบอร์ด ESP32 จะเปิด/ปิดตามที่คุณสั่ง
🌡️ แสดงข้อมูล Sensor แบบ Real-time
ในตัวอย่างนี้ เราจะจำลองข้อมูล Sensor (อุณหภูมิและความชื้น) และแสดงแบบ Auto-refresh ทุก 5 วินาที
#include <WiFi.h>
#include <WebServer.h>
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
WebServer server(80);
// ตัวแปรจำลองข้อมูล sensor
float temperature = 25.0;
float humidity = 60.0;
// สร้างข้อมูล sensor แบบสุ่ม (จำลอง)
void updateSensorData() {
temperature = random(200, 350) / 10.0; // 20.0 - 35.0 °C
humidity = random(400, 800) / 10.0; // 40.0 - 80.0 %
}
// หน้าเว็บแสดงข้อมูล sensor พร้อม auto-refresh
void handleRoot() {
updateSensorData(); // อัปเดตข้อมูลก่อนแสดง
String html = "<!DOCTYPE html><html>";
html += "<head><meta charset='UTF-8'>";
html += "<meta http-equiv='refresh' content='5'>"; // Auto-refresh ทุก 5 วินาที
html += "<title>ESP32 Sensor Dashboard</title>";
html += "<style>";
html += "body { font-family: Arial, sans-serif; text-align: center; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); margin: 0; padding: 20px; min-height: 100vh; }";
html += ".container { background: white; border-radius: 20px; padding: 40px; max-width: 600px; margin: 50px auto; box-shadow: 0 10px 30px rgba(0,0,0,0.3); }";
html += "h1 { color: #333; margin-bottom: 30px; }";
html += ".sensor-box { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); color: white; padding: 20px; margin: 10px 0; border-radius: 15px; }";
html += ".sensor-value { font-size: 48px; font-weight: bold; margin: 10px 0; }";
html += ".sensor-label { font-size: 18px; opacity: 0.9; }";
html += ".update-info { color: #666; font-size: 14px; margin-top: 20px; }";
html += "</style>";
html += "</head><body>";
html += "<div class='container'>";
html += "<h1>🌡️ อุณหภูมิและความชื้น</h1>";
html += "<div class='sensor-box'>";
html += "<div class='sensor-label'>อุณหภูมิ</div>";
html += "<div class='sensor-value'>" + String(temperature, 1) + "°C</div>";
html += "</div>";
html += "<div class='sensor-box' style='background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);'>";
html += "<div class='sensor-label'>ความชื้น</div>";
html += "<div class='sensor-value'>" + String(humidity, 1) + "%</div>";
html += "</div>";
html += "<p class='update-info'>อัปเดตอัตโนมัติทุก 5 วินาที - เวลา: " + String(millis() / 1000) + " วินาที</p>";
html += "</div>";
html += "</body></html>";
server.send(200, "text/html", html);
}
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
server.on("/", handleRoot);
server.begin();
Serial.println("HTTP server started");
}
void loop() {
server.handleClient();
}🎨 คำแนะนำ: หน้าเว็บนี้ใช้ CSS Gradient ที่สวยงาม และ Auto-refresh ทุก 5 วินาทีเพื่อแสดงข้อมูลล่าสุด คุณสามารถปรับเปลี่ยนสไตล์ได้ตามต้องการ
🎨 ตกแต่งหน้าเว็บให้สวยงาม
คุณสามารถปรับปรุงหน้าตา Web Interface ด้วยเทคนิคต่างๆ เหล่านี้:
1. ใช้ CSS Framework (Bootstrap, Tailwind)
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> 2. ใช้ JavaScript สำหรับ Interaction
<script>function toggleLED() { fetch('/toggle'); }</script> 3. เพิ่ม Icon ด้วย Font Awesome
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css"> 4. ใช้ Chart แสดงข้อมูล (Chart.js)
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> 🚀 เทคนิคขั้นสูง
1. WebSocket สำหรับ Real-time Update
ใช้ WebSocket แทน HTTP Polling สำหรับการอัปเดตข้อมูลแบบทันทีทันใด ลดภาระจากการ refresh หน้าเว็บซ้ำๆ
2. Authentication ป้องกันการเข้าถึง
เพิ่มระบบ Login ด้วย Username/Password หรือ Token เพื่อป้องกันการเข้าถึงโดยไม่ได้รับอนุญาต
3. Serve Static Files (SPIFFS/LittleFS)
เก็บ HTML, CSS, JavaScript ไว้ใน File System ของ ESP32 เพื่อลดการใช้ Memory และจัดการไฟล์ได้ง่ายขึ้น
4. RESTful API Design
ออกแบบ API แบบ RESTful (GET, POST, PUT, DELETE) เพื่อให้สอดคล้องกับมาตรฐานและง่ายต่อการใช้งาน
5. OTA (Over-The-Air) Updates
อัปเดต Firmware ผ่าน Web Interface โดยไม่ต้องเสียบสาย USB
🔧 แก้ปัญหาที่พบบ่อย
ปัญหา: เข้าเว็บไม่ได้ / Connection Refused
สาเหตุ: อุปกรณ์ไม่ได้อยู่ในเครือข่ายเดียวกัน หรือ IP Address ผิด
วิธีแก้: ตรวจสอบ Serial Monitor ว่า IP Address ถูกต้อง และมือถือ/คอมพิวเตอร์อยู่ใน WiFi เดียวกับ ESP32
ปัญหา: หน้าเว็บโหลดช้ามาก
สาเหตุ: HTML Code ยาวเกินไป หรือมีรูปภาพขนาดใหญ่
วิธีแก้: ใช้ LittleFS/SPIFFS สำหรับไฟล์ขนาดใหญ่ หรือบีบอัดรูปภาพให้เล็กลง
ปัญหา: ESP32 รีเซ็ตเองบ่อยๆ
สาเหตุ: Memory ไม่พอ หรือไฟกระแสไม่เสถียร
วิธีแก้: ใช้ PSRAM ถ้ามี, ลดขนาด HTML, ตรวจสอบแหล่งจ่ายไฟ
ปัญหา: ข้อมูล Sensor ไม่อัปเดต
สาเหตุ: โค้ดอ่านค่า sensor ไม่ถูกเรียกใน loop()
วิธีแก้: เพิ่มฟังก์ชันอ่าน sensor ใน loop() หรือใช้ Timer
🎉 สรุป
ในบทความนี้ คุณได้เรียนรู้วิธีสร้าง Web Server บน ESP32 ตั้งแต่พื้นฐานไปจนถึงการควบคุม GPIO และแสดงข้อมูล Sensor คุณสามารถนำความรู้นี้ไปประยุกต์ใช้กับโปรเจกต์ IoT ต่างๆ ได้ทันที
หากคุณต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ IoT, ESP32 หรือการเชื่อมต่อกับ CynoIoT Platform, ลองดูบทความอื่นๆ ของเรา!