สอนการใช้งาน ESP32 Web Server ควบคุมความสว่างหลอดLED (PWM)
สอนการใช้งาน ESP32 Web Server ควบคุมความสว่างหลอดLED ในบทเรียนนี้คุณจะได้เรียนรู้การสร้างแถบเลื่อนบนหน้าเว็บ ESP Server ของคุณและยังเป็นค่าอินพุตที่ปรับเปลี่ยนได้ 0 – 255 ค่า esp เซอเวอร์จะรับค่านี้และบันทึกลงตัวแปรเพื่อนำไปใช้ในการสร้างสัญญาณ PWM เพื่อควบคุมความสว่างของหลอด LED หรือ นำสัญญาณ PWM ไปควบคุมอุปกรณ์อื่นๆ เช่น มอเตอร์ไดร์, inverter, Heater

< สร้างหน้าเว็บเพจ แถบเลื่อนควบคุมความสว่างหลอด LED ด้วย ESPAsyncWebServer >
หากยังไม่รู้จักความสามารถและโครงสร้างของบอร์ด ESP32 แนะนำให้อ่าน ESP32 คืออะไร ก่อน เพื่อเข้าใจภาพรวม
เลือกพินให้ถูก โปรเจกต์ไม่มีพัง! ดูตารางและรายละเอียด ESP32 Pinout ครบทั้ง GPIO, ADC, PWM, I2C, UART ได้ที่ คู่มือ ESP32 Pinout DEVKIT V1
เตรียมความพร้อม
- เราจะโปรแกรมบอร์ด ESP32 โดยใช้ Arduino IDE ดังนั้นคุณต้องติดตั้งโปรแกรมเสริมของ ESP32 ให้เรียบร้อยก่อน
- ในการสร้างเว็บเซิร์ฟเวอร์แบบอะซิงโครนัส จำเป็นต้องติดตั้งไลบรารีต่อไปนี้
บอร์ด ESP32 ต้องติดตั้งไลบรารี ESPAsyncWebServer และ AsyncTCP
ติดตั้งไลบรารีใน Arduino IDE ไปที่ Sketch > Include Library > Add .zip Library และ เลือกไลบรารีที่จะติดตั้ง
แผนผังวงจรฮาร์ดแวร์
ใช้งานขา GPIO D4 ของบอร์ด ESP32 เป็นขาสัญญาณ PWM ควบคุมความสว่างหลอดไฟ LED

ไฟล์โครงงาน
ในการสร้างเว็บเซิร์ฟเวอร์ในตัวบทเรียนนี้ จะมีไฟล์ 3 ไฟล์ คือ ไฟล์ Arduino sketch และไฟล์ index.h และ style.h

หากเพิ่งเริ่มต้นกับ Arduino esp32 และไม่รู้ว่าจะเริ่มตรงไหน แนะนำให้เปิด Arduino IDE Guide เพื่อความเข้าใจพื้นฐานจากศูนย์
ไฟล์ HTML
สร้างไฟล์ index.h โดยมีข้อมูลดังนี้
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Deva DIY ควบคุมความสว่างหลอด LED</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="slider-container">
<h2>ESP Web Server ควบคุมความสว่างหลอด LED</h2> <br>
<p>Value: <span id="sliderValue">%VALUE_INPUT1%</span></p> <br>
<input type="range" min="0" max="255" value="%VALUE_INPUT1%" class="slider" id="myslider" onchange="updateSlider(this)"> <br>
</div>
<script>
function updateSlider(){
var slider = document.getElementById("myslider");
var output = document.getElementById("sliderValue");
output.innerHTML = slider.value;
var sliderValue = slider.value;
slider.oninput = function() {
output.innerHTML = this.value;
}
var xhr = new XMLHttpRequest();
xhr.open("GET", "/slider?value="+sliderValue, true);
xhr.send();
}
</script>
</body>
</html>
)rawliteral";
<div class="slider-container"> <h2>ESP Web Server ควบคุมความสว่างหลอด LED</h2> <br> <p>Value: <span id="sliderValue">%VALUE_INPUT1%</span></p> <br> <input type="range" min="0" max="255" value="%VALUE_INPUT1%" class="slider" id="myslider" onchange="updateSlider(this)"> <br> </div>ในแท็ก <p>….</p> จะแสดงข้อมูล value ในปัจจุบัน
<p>Value: <span id="sliderValue">%VALUE_INPUT1%</span></p>ในแท็ก input จะแสดงแถบเลื่อนในปรับเปลี่ยนค่า value และกำหนดค่าให้อยู่ในช่วง 0-255
<input type="range" min="0" max="255" value="%VALUE_INPUT1%" class="slider" id="myslider" onchange="updateSlider(this)">ในแท็ก <script>….</script> function updateSlider() จะอัพเดทค่าใน id=sliderValue เมื่อได้เลื่อนแถบสไลด์ และส่ง request HTTP GET ตามด้วย URLและค่าพารามิเตอร์ตามนี้ “/slider?value= “ไปที่ Server ESP32 เพื่อควบคุมสัญญาณ PWM
var xhr = new XMLHttpRequest();
xhr.open("GET", "/slider?value="+sliderValue, true);
xhr.send();
ตัวอย่าง เมื่อแถบเลื่อนอยู่ที่ 0 จะส่งคำขอ HTTP GET ตาม URL ต่อไปนี้:http://Your-ESP-IP-ADDRESS/slider?value=0ตัวอย่าง เมื่อแถบเลื่อนอยู่ที่ 255 จะส่งคำขอ HTTP GET ตาม URL ต่อไปนี้:
http://Your-ESP-IP-ADDRESS/slider?value=255
ไฟล์ style.css
สร้างไฟล์ style.h โดยมีข้อมูลดังนี้
const char style_css[] PROGMEM = R"rawliteral(
body {
margin: 0px;
padding: 10px;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: #f0f0f0;
font-family: Arial, sans-serif;
}
.slider-container {
width: 80%;
max-width: 500px;
}
.slider {
-webkit-appearance: none;
width: 100%;
height: 15px;
border-radius: 5px;
background: linear-gradient(90deg, rgba(0,45,84,1) 0%, rgba(43,152,190,1) 50%, rgba(5,210,251,1) 100%);
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
border-radius: 15px;
}
.slider:hover {
opacity: 1;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
border-radius: 50%;
background: #002d54;
cursor: pointer;
border-radius: 50%;
box-shadow: 0 0 5px rgba(0,0,0,0.2);
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
border-radius: 50%;
background: #002d54;
cursor: pointer;
border-radius: 50%;
box-shadow: 0 0 5px rgba(0,0,0,0.2);
}
)rawliteral";
ไฟล์ Arduino sketch
นี้คือโค๊ดตัวอย่างการทำงาน Web Server เพื่อรับค่า Duty Cycle PWM ควบคุมความสว่างหลอดไฟและอธิบายการทำงานของโค๊ดตัวอย่างนี้ส่วนถัดไป:
/*
Deva Diy
ESP Web Server ควบคุมความสว่างหลอด LED
ด้วยสัญญาณ PWM
*/
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "index.h"
#include "style.h"
// สร้าง AsyncWebServer object พอร์ต 80
AsyncWebServer server(80);
//ตัวแปรบันทึกค่า ssid รหัสผ่าน
const char* ssid = "your ssid";
const char* password = "your password";
String valueSlider = "0";
const int Pin = 4;
// setting PWM properties
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
void WiFi_init() {
unsigned long pastTime = 0;
unsigned long nowTime = 0;
unsigned long timeOut = 10000;
// ตั้งค่า esp32 WiFi Mode : Station
WiFi.mode(WIFI_STA);
// เชื่อมต่อเครื่อข่าย WiFi ด้วย ssid, password
WiFi.begin(ssid, password);
// ตรวจสอบการเชื่อมต่อ WiFi ถ้าใช้เวลาเชื่อมต่อเกิน timeOut ให้หยุดการเชื่อมต่อ
pastTime = millis();
while ((WiFi.status() != WL_CONNECTED) && (nowTime <= timeOut )) {
Serial.print("Connecting to "); Serial.println(ssid);
delay(500);
nowTime = millis() - pastTime;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.print("Local ESP32 IP: ");
Serial.println(WiFi.localIP());
Serial.print("RSSI: ");
Serial.println(WiFi.RSSI());
}
else {
Serial.print("Unable connect to Wi-Fi " + String(ssid));
WiFi.disconnect();
}
}
// Replaces placeholder with values of slider
String processor(const String& var) {
if (var == "VALUE_INPUT1") {
return valueSlider;
}
return String();
}
void setup() {
Serial.begin(115200);
WiFi_init();
// configure LED PWM functionalitites
ledcSetup(ledChannel, freq, resolution);
ledcAttachPin(Pin, ledChannel);
ledcWrite(ledChannel, valueSlider.toInt());
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send_P(200, "text/html", index_html, processor);
});
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send_P(200, "text/css", style_css);
});
// Send a GET request to <ESP_IP>/slider?value=
server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputGET;
// GET input1 value on <ESP_IP>/slider?value=<inputMessage>
if (request->hasParam("value")) {
inputGET = request->getParam("value")->value();
valueSlider = inputGET;
ledcWrite(ledChannel, valueSlider.toInt());
}
else {
inputGET = "No Parameter!";
}
request->send(200, "text/plain", "Set up successfully");
delay(1000);
Serial.println(inputGET);
});
// Start server
server.begin();
}
void loop() {
}
อธิบายการทำงาน ESPAsyncWebServer ควบคุมความสว่างหลอดLED
รวมไลบรารีที่จำเป็น และ ไฟล์ index.h ไฟล์ style.h ดั่งต่อไปนี้:#include #include #include #include "index.h" #include "style.h"สร้าง AsyncWebServer object บนพอร์ท 80:
AsyncWebServer server(80);"สร้างตัวแปรบันทึกค่า ssid และรหัสผ่าน ในการเชื่อมต่อ WiFi:
const char* ssid = "your ssid"; const char* password = "your password";สร้างตัวแปรในการเก็บค่า Duty Cycle PWM
String valueSlider = "0";กำหนดพินที่ 4 ของบอร์ด ESP32 เป็นขา Output สัญญาณ PWM
const int Pin = 4;สร้างตัวแปรในการตั้งค่าสัญญาณ PWM freq กำหนดความถี่ ledChannel ตั้งค่าช่องสัญญาณ PWM (0-15) resolution กำหนดขนาด bit สามารถปรับความละเอียดได้ 1-16 bit
const int freq = 5000; const int ledChannel = 0; const int resolution = 8;ฟังก์ชัน WiFi_init() ฟังก์ชั่น WiFi_init() นี้จะทำการเชื่อมต่อ WiFi ของคุณ ในกรณีใช้เวลาเชื่อมต่อเกิน 10 วินาทีจะทำการหยุดการเชือมต่อ
void WiFi_init() {
unsigned long pastTime = 0;
unsigned long nowTime = 0;
unsigned long timeOut = 10000;
// ตั้งค่า esp32 WiFi Mode : Station
WiFi.mode(WIFI_STA);
// เชื่อมต่อเครื่อข่าย WiFi ด้วย ssid, password
WiFi.begin(ssid, password);
// ตรวจสอบการเชื่อมต่อ WiFi ถ้าใช้เวลาเชื่อมต่อเกิน timeOut ให้หยุดการเชื่อมต่อ
pastTime = millis();
while ((WiFi.status() != WL_CONNECTED) && (nowTime <= timeOut )) {
Serial.print("Connecting to "); Serial.println(ssid);
delay(500);
nowTime = millis() - pastTime;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.print("Local ESP32 IP: ");
Serial.println(WiFi.localIP());
Serial.print("RSSI: ");
Serial.println(WiFi.RSSI());
}
else {
Serial.print("Unable connect to Wi-Fi " + String(ssid));
WiFi.disconnect();
}
}
processor(const String& var)
ฟังก์ชั่น processor() ที่จะแทนที่ตำแหน่งข้อความที่ได้ยึดไว้ในตัวแปรในข้อความ HTML ของเราด้วยค่า Value ในแถบเลื่อน ซึ่งตำแหน่งข้อความที่เราได้ยึดไว้กับตัวแปรในฟังก์ชั่นนี้คือ VALUE_INPUT1
String processor(const String& var) {
if (var == "VALUE_INPUT1") {
return valueSlider;
}
return String();
}
ในส่วน setup()
กำหนดค่าฟังก์ชันการทำงานของ PWMledcSetup(ledChannel, freq, resolution); ledcAttachPin(Pin, ledChannel);สร้างสัญญาณ PWM Output ด้วยคำสั่ง ledcWrite() ซึ่งอาร์กิวเมนต์ที่รับเข้ามาคือ Channel และ ค่า duty cycle ที่ขึ้นกับความละเอียดที่กำหนดในฟังก์ชัน ledcSetup
ledcWrite(ledChannel, valueSlider.toInt());
การจัดการ Requests
code การจัดการเว็บเซิร์ฟเวอร์
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send_P(200, "text/html", index_html, processor);
});
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send_P(200, "text/css", style_css);
});
// Send a GET request to /slider?value=
server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputGET;
// GET input1 value on /slider?value=
if (request->hasParam("value")) {
inputGET = request->getParam("value")->value();
valueSlider = inputGET;
ledcWrite(ledChannel, valueSlider.toInt());
}
else {
inputGET = "No Parameter!";
}
request->send(200, "text/plain", "Set up successfully");
delay(1000);
Serial.println(inputGET);
});
// Start server
server.begin();
เมื่อได้รับการร้องขอ root URL (/) เราจะส่งข้อความ HTML ที่บันทึกไว้ในไฟล์ index.h ภายใต้ชื่อ index_html นอกจากนี้เรายังต้องผ่านฟังก์ชัน processor() ซึ่งจะแทนที่ข้อความที่ได้ยึดตำแหน่งไว้ด้วยค่าที่อ่านได้จากตัวแปร valueSlider :
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send_P(200, "text/html", index_html, processor);
});
จัดการกับการร้องขอ /slider ซึ่งจะส่ง Parameter พร้อมกับ Slider Value มาด้วยเพื่อนำมาใช้ควบคุมควบสัญญาณ PWM ในการเปลี่ยนแปลงความสว่างของหลอด LED
server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputGET;
// GET input1 value on /slider?value=
if (request->hasParam("value")) {
inputGET = request->getParam("value")->value();
valueSlider = inputGET;
ledcWrite(ledChannel, valueSlider.toInt());
}
else {
inputGET = "No Parameter!";
}
request->send(200, "text/plain", "Set up successfully");
delay(1000);
Serial.println(inputGET);
});
ในบรรทัดนี้ เราจะรับค่าในพารามิเตอร์ชื่อ value ซึ่งเป็นค่าของแถบเลื่อน เพื่อนำค่านี้ไปอัพเดท PWM Duty Cycle ในคำสั่ง ledcWrite() จากนั้นก็ส่งออกสัญญาณ PWM ออกไปเพื่อควบคุมความสว่าง LED
if (request->hasParam("value")) {
inputGET = request->getParam("value")->value();
valueSlider = inputGET;
ledcWrite(ledChannel, valueSlider.toInt());
}
เริ่มเซิร์ฟเวอร์server.begin();
Download Code ดาวน์โหลดไฟล์ทั้งหมดได้ที่นี้
กรุณา เข้าสู่ระบบ เพื่อดาวน์โหลด
เปิดไฟล์ ESP32_Web_Server_ControlLED ด้วยโปรแกรม Arduino IDE จากนั้นอัปโหลดโค้ดไปยังบอร์ดของคุณ และอย่าลืมแก้ไข ssid และ password ในการติดต่อกับ WiFi ของคุณ
เมื่ออัพโหลดโค๊ดเรียบร้อย เปิด Serial Monitor ตั้งค่า baud rate ที่ 115200 ถัดไปกดปุ่ม EN|RST ที่บอร์ด ESP เมื่อบอร์ดเชื่อมต่อ WiFi สำเร็จ จะแสดงเลข IP Address ที่หน้าจอด Serial Monitor

สรุปบทเรียน ESPAsyncWebServer ควบคุมความสว่างหลอดLED (PWM)
ในบทเรียนนี้ช่วยให้คุณได้เรียนรู้วิธีการสร้างปุ่มแถบเลื่อนบนหน้าเว็บ แล้วส่งค่าจากแถบเลื่อนนี้กลับมาที่ ESP Web Server เพื่อใช้ในการควบคุมสัญญาณ Duty Cycle PWM และ output นี้ได้นำไปควบคุมความสว่างของหลอด LED ผลที่ได้คือ ความสว่างจะมาก-น้อย ขึ้นอยู่กับ ค่า duty cylcle ยิ่งค่ามากความสว่างก็มากขึ้นตามไปด้วย ความรู้จากบทเรียนนี้สามารถนำไปปรับใช้กับการควบคุมอุปกรณ์อื่นๆได้อีกมากทาย และหวังว่าบทเรียนนี้จะมีประโยชน์สำหรับโครงงานของคุณ




