ควบคุม LED ด้วย PWM ผ่าน ESP32 Web Server

สอนการใช้งาน ESP32 Web Server ควบคุมความสว่างหลอดLED (PWM)

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

รูปภาพประกอบบทเรียน ESP32 Web Server ควบคุมความสว่างหลอดLED - Deva DIY

< สร้างหน้าเว็บเพจ แถบเลื่อนควบคุมความสว่างหลอด LED ด้วย ESPAsyncWebServer >

หากยังไม่รู้จักความสามารถและโครงสร้างของบอร์ด ESP32 แนะนำให้อ่าน ESP32 คืออะไร ก่อน เพื่อเข้าใจภาพรวม

🔌 เลือกพินให้ถูก โปรเจกต์ไม่มีพัง! ดูตารางและรายละเอียด ESP32 Pinout ครบทั้ง GPIO, ADC, PWM, I2C, UART ได้ที่ คู่มือ ESP32 Pinout DEVKIT V1

เตรียมความพร้อม

  1. เราจะโปรแกรมบอร์ด ESP32 โดยใช้ Arduino IDE ดังนั้นคุณต้องติดตั้งโปรแกรมเสริมของ ESP32  ให้เรียบร้อยก่อน
  2. ในการสร้างเว็บเซิร์ฟเวอร์แบบอะซิงโครนัส จำเป็นต้องติดตั้งไลบรารีต่อไปนี้
    บอร์ด ESP32 ต้องติดตั้งไลบรารี ESPAsyncWebServer และ AsyncTCP
    ติดตั้งไลบรารีใน Arduino IDE ไปที่ Sketch > Include Library > Add .zip Library และ เลือกไลบรารีที่จะติดตั้ง

แผนผังวงจรฮาร์ดแวร์

ใช้งานขา GPIO D4 ของบอร์ด ESP32 เป็นขาสัญญาณ PWM ควบคุมความสว่างหลอดไฟ LED

รูปภาพประกอบบทเรียน ESP32 Web Server ควบคุมความสว่างหลอดLED - Deva DIY วงจรการต่อสายสัญญาณ

ไฟล์โครงงาน

ในการสร้างเว็บเซิร์ฟเวอร์ในตัวบทเรียนนี้ จะมีไฟล์ 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>….</div> จะแสดงข้อมูล value และ แถบเลื่อนสำหรับปรับเปลี่ยนค่า value
<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, &#91;&#93;(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) &amp;&amp; (nowTime &lt;= 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&amp; var) {
if (var == "VALUE_INPUT1") {
return valueSlider;
}
return String();
}

ในส่วน setup()

กำหนดค่าฟังก์ชันการทำงานของ PWM
ledcSetup(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-&gt;send_P(200, "text/html", index_html, processor);
});
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest * request) {
request-&gt;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-&gt;hasParam("value")) {
inputGET = request-&gt;getParam("value")-&gt;value();
valueSlider = inputGET;
ledcWrite(ledChannel, valueSlider.toInt());
}
else {
inputGET = "No Parameter!";
}
request-&gt;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-&gt;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-&gt;hasParam("value")) {
inputGET = request-&gt;getParam("value")-&gt;value();
valueSlider = inputGET;
ledcWrite(ledChannel, valueSlider.toInt());
}
else {
inputGET = "No Parameter!";
}
request-&gt;send(200, "text/plain", "Set up successfully");
delay(1000);
Serial.println(inputGET);
});
ในบรรทัดนี้ เราจะรับค่าในพารามิเตอร์ชื่อ value ซึ่งเป็นค่าของแถบเลื่อน เพื่อนำค่านี้ไปอัพเดท PWM Duty Cycle ในคำสั่ง ledcWrite() จากนั้นก็ส่งออกสัญญาณ PWM ออกไปเพื่อควบคุมความสว่าง LED
if (request-&gt;hasParam("value")) {
inputGET = request-&gt;getParam("value")-&gt;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

รูปภาพประกอบบทเรียน ESP32 Web Server ควบคุมความสว่างหลอดLED - Deva DIY หน้า Serial monitor แสดงข้อความเลข ESP IP Address

สรุปบทเรียน ESPAsyncWebServer ควบคุมความสว่างหลอดLED (PWM)

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

 


 

เรื่องที่น่าสนใจบนเว็บ DevaDIY :

Shopping Cart
Scroll to Top