ESPAsyncWebServer – สร้างหน้าเพจ Wi-Fi Manager

สร้างหน้าเพจ Wi-Fi Manager ร่วมกับ ESPAsyncWebServer


เว็บเพจ Wi-Fi Manager จัดการข้อมูลบันทึก SSID และ PASSWORD ในการเชื่มต่อเครือข่าย Wi-Fi การใช้ Wi-Fi Manager ช่วยให้การเชื่อมต่อเครือข่าย Wi-Fi อื่นๆที่แตกต่างต่างกันได้โดยที่ไม่ต้องเข้าไปแก้ไขตัวโค๊ดโปรแกรมแล้วอัพโหลดใหม่ไปที่ตัวบอร์ดESP โดยเมื่อใส่ข้อมูล SSID และ PASSWORD ในหน้าเว็บ Wi-Fi Manager บอร์ดESP จะบันทึกข้อมูลนี้ไว้และทุกครั้งที่เชื่อมต่อเครื่อข่ายWiFi จะนำข้อมูลนี้มาใช้งานอัตโนมัติ


<สร้างหน้าเว็บเพจ wifi manager ด้วย ESPAsyncWebServer>

การติดตั้งไลบรารี (Arduino IDE)

ติดตั้งไลบรารีต่อไปนี้ใน Arduino IDE ไปที่ Sketch Include Library > Add .zip Library และ เลือกไลบรารีที่จะติดตั้ง

รายละเอียดพื้นฐานของ ESP32 คืออะไร พร้อมจุดเด่นและวิธีเริ่มต้นใช้งาน

ติดตั้งไฟล์ wifimanager html

ไฟล์ HTML เพื่อสร้างหน้าตัวจัดการ Wi-Fi (wifimanager.html)
ตัวอย่างหน้าเว็บ Wi-Fi Manager
ESPAsyncWebServer สร้างหน้า wifi manager

<รูปตัวอย่างหน้าเว็บ Wi-Fi Manager>

คัดลอกข้อมูลไฟล์ wifimanager_html ด้านล่างนี้ไปยัง Arduino IDE ตั้งชื่อไฟล์ wifimanager.h
const char wifimanager_html[] PROGMEM = R"rawliteral(
<div class="headtopic">
<h1>จัดการ Wi-Fi</h1>
</div>
<div class="box">
<div class="block_input"><form action="/wifi" method="POST"><label for="ssid">SSID</label>
<input id="ssid" name="ssid" type="text" />
<label for="pass">Password</label>
<input id="pass" name="password" type="text" />
<input type="submit" value="บันทึก" /></form></div>
</div>
)rawliteral";

คอร์สออนไลน์: การใช้งาน WiFi Manager บน ESP32

“หากยังไม่รู้จัก ESPAsyncWebServer มาก่อน แนะนำให้อ่านคู่มือฉบับเต็มก่อนใช้งานจริง”
🔗 ESPAsyncWebServer Guide

ถ้าคุณอยากเริ่มต้นใช้งาน Arduino IDE อย่างมั่นใจ ลองอ่าน Arduino IDE Guide — คู่มือแนะนำตั้งแต่การติดตั้งจนถึงการใช้งานจริง

ไฟล์ HTML นี้ เราจะสร้างแบบฟอร์ม คำขอ HTTP POST พร้อมข้อมูล ssid และ password ไปยังเซิร์ฟเวอร์
<form action="/wifi" method="POST">
        <p>
          <label for="ssid">SSID</label>
          <input type="text" id ="ssid" name="ssid"><br>
          <label for="pass">Password</label>
          <input type="text" id ="pass" name="password"><br>
          <input type ="submit" value ="บันทึก">
        </p>
</form>
แบบฟอร์มจะมีช่องใส่ข้อมูล 2 ช่อง นี้คือ ช่องใส่ข้อมูล ssid
<label for="ssid">SSID</label>
<input type="text" id ="ssid" name="ssid">
ช่องใส่ข้อมูล password
<label for="pass">Password</label>
<input type="text" id ="pass" name="password">
คัดลอกข้อมูลไฟล์ wifimanager_css ด้านล่างนี้ไปยัง Arduino IDE ตั้งชื่อไฟล์ style_wifimanager.h
const char wifimanager_css[] PROGMEM = R"rawliteral(
html {
font-family: Arial, Helvetica, sans-serif;
display: inline-block;
}
h1 {
font-size: 1.75em;
color: white;
text-align: center;
}
p {
font-size: 1.125em;
}
.headtopic {
overflow: hidden;
background-color: #1a3300;
}
body {
margin: 0;
}
.block_input{
max-width: 600px;
margin: auto;
padding: 1px 100px;
text-align: center;
background-color: white;
box-shadow: 1px 1px 15px 1px grey;
}
.box {
margin: 20px;
}
input[type=submit] {
border: none;
color: #FEFCFB;
background-color: #034078;
padding: 15px 15px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
width: 100px;
margin-right: 10px;
border-radius: 4px;
transition-duration: 1s;
}
input[type=submit]:hover {
background-color: #1282A2;
}
input[type=text], input[type=number], select {
max-width: 85%;
padding: 12px 20px;
margin: 18px;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
label {
font-size: 1em;
}
span {
font-size: 0.6em;
}
)rawliteral";

การตั้งค่าเว็บเซิร์ฟเวอร์

คัดลอกข้อมูลไฟล์ ด้านล่างนี้ไปยัง Arduino IDE
/*
  Deva DIY
  www.devadiy.com
  ตัวอย่างการสร้างเว็บ WiFi Manager
*/

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <EEPROM.h>
#include "wifimanager.h"
#include "style_wifimanager.h"

// สร้าง AsyncWebServer object พอร์ต 80
AsyncWebServer server(80);

//ตัวแปรบันทึกค่า ssid รหัสผ่านจากแบบฟอร์ม WiFi manager
const char* ssid = "";
const char* password = "";

// ตัวแปรบันทึกค่า ssid รหัสผ่าน ลงใน เมมโมรี่
struct EepromObj_wifimanager {
  char parm_ssid[64] = "";
  char parm_pass[24] = "";
};
EepromObj_wifimanager saveparm;

// ตั้งค่าพิน GPIO led onboard
const int led = 2;

// ตรวจสอบแต่ละตัวอักษร
bool isAlphaNumericString(const String &str) {
  for (size_t i = 0; i < str.length(); i++) {
    if (!isAlphaNumeric(str.charAt(i))) {
      return false;
    }
  }
  return true;
}

// อ่านข้อมูลจากเมมโมรี
void readParm() {
  EEPROM.get(2, saveparm);
  ssid = saveparm.parm_ssid;
  password = saveparm.parm_pass;
  delay(500);

  Serial.print("SSID : ");
  Serial.println(ssid);
  Serial.print("PASSWORD : ");
  Serial.println(password);
}

// เขียนข้อมูลลงในเมมโมรี
void writeParm() {
  EEPROM.put(2, saveparm);
  EEPROM.commit();
  delay(500);
  Serial.println("Saved Parm to Memory");
}

// เริ่มต้นใช้งานการเชื่อมต่อ WiFi
bool WiFi_init() {
  unsigned long pastTime = 0;
  unsigned long nowTime = 0;
  unsigned long timeOut = 10000;

  // ตรวจสอบ ssid มีข้อมูลบันทึกอยู่หรือไม่
  if (String(ssid) == "") {
    Serial.println("Unable connect to Wi-Fi");
    return false;
  }

  // ตั้งค่า 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(1000);
    nowTime = millis() - pastTime;
  }
  if (WiFi.status() == WL_CONNECTED) {
    Serial.print("Local ESP32 IP: ");
    Serial.println(WiFi.localIP());
    Serial.print("RSSI: ");
    Serial.println(WiFi.RSSI());
    return true;
  } else {
    Serial.println("Unable connect to Wi-Fi " + String(ssid));
    WiFi.disconnect();
    return false;
  }
}

void setup() {
  // Serial port for debugging
  Serial.begin(115200);

  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);

  //เริ่มต้นใช้งาน EEPROM
  EEPROM.begin(512);
  delay(500);

  readParm();

  if (!WiFi_init()) {
    Serial.println("Setting AP (Access Point)");
    // ตั้งค่า Access Point
    WiFi.softAP("ESP-WIFI-MANAGER", "Deva_DIY");

    IPAddress IP = WiFi.softAPIP();
    Serial.println("AP IP address: ");
    Serial.println(IP);

    // Web Server Root URL
    server.on("/", HTTP_GET, &#91;&#93;(AsyncWebServerRequest* request) {
      request->send_P(200, "text/html", wifimanager_html);
    });
    // Web Server style.css
    server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest* request) {
      request->send_P(200, "text/css", wifimanager_css);
    });

    // Get the parameters submited on the form
    server.on("/wifi", HTTP_POST, [](AsyncWebServerRequest* request) {

      // HTTP POST ssid value
      if (request->hasParam("ssid", true)) {
        // ดึงค่า parameter
        String ssid = request->getParam("ssid", true)->value();
        Serial.print("[Parameter Value] SSID : ");
        Serial.println(ssid);
        strcpy(saveparm.parm_ssid, ssid.c_str());
      }

      // HTTP POST pass value
       if (request->hasParam("ssid", true)) {
        String password = request->getParam("password", true)->value();
        Serial.print("[Parameter Value] Password : ");
        Serial.println("********");
        strcpy(saveparm.parm_pass, password.c_str());
       }       
      
      //บันทึกค่า ssid, password ในเมมโมรี
      writeParm();
      delay(500);
      request->send(200, "text/plain", " saved done. ESP32 will restart connect to your router");
      delay(2000);
      ESP.restart();
    });
    server.begin();
  }
}

void loop() {
  // led แสดงผลการเชื่อมต่อ WiFi
  if (WiFi.status() == WL_CONNECTED) {
    digitalWrite(led, HIGH);
  } else {
    digitalWrite(led, LOW);
  }
}

โค๊ดทำงานอย่างไร

  • เมื่อ esp32 ทำงานครั้งแรก จะเริ่มอ่านข้อมูลที่บันทึกในเมมโมรี ssid, password
  • ถ้าข้อมูลใน ssid ว่างเปล่า บอร์ด ESP จะถูกตั้งค่าในโหมด access point
  • สามารถใช้อุปกรณ์เชื่อมต่อ WiFi กับบอร์ด ESP32 ชื่อเริ่มต้น ESP-WIFI-MANAGER
  • เมื่ออุปกรณ์เชื่อมต่อกับ ESP-WIFI-MANAGER ได้แล้ว เปิดเว็บเบราเซอร์ ใส่ค่าเริ่มต้น IP address 192.168.4.1 เพื่อเปิดหน้าเว็บตั้งค่า SSID และ PASSWORD ของคุณ
  • SSID และ PASSWOR ในแบบฟอร์มจะถูกบันทึกไว้ในหน่วยความจำของบอร์ด ESP32 แล้วหลังจากนั้นจะรีสตาร์ทเครื่องใหม่
  • หลังจากรีสตาร์ท ค่า ssid จะไม่ว่าง  ESP32 จะเชื่อมต่อกับเครือข่ายWiFiในโหมด Station โดยใช้การตั้งค่าที่คุณได้กรอกลงไปในแบบฟอร์ม
  • หากเชื่อมต่อเครื่อข่ายWiFiได้สำเร็จ เป็นอันเสร็จสมบูรณ์ แต่หากเชื่อมต่อ WiFi ไม่สำเร็จ บอร์ด ESP จะกลับไปตั้งค่าในโหมด access point อีกครั้ง
ตัวแปรต่อไปนี้ใช้เพื่อบันทึก SSID, รหัสผ่านในคำขอ HTTP POST เมื่อกดปุ่มส่งแบบฟอร์ม และ บันทึกค่า SSID, รหัสผ่าน จากแฟลชเมมโมรีESP เมื่อเปิดเครื่องทุกครั้ง
 
//ตัวแปรบันทึกค่า ssid รหัสผ่านจากแบบฟอร์ม WiFi manager
const char* ssid = "";
const char* password = "";
ตัวแปรแบบ struct นี้ใช้สำหรับส่งผ่านค่าจากตัวแปรด้านบน เพื่อบันทึกค่าลงในหน่วยความจำแฟลชเมมโมรี
 // ตัวแปรบันทึกค่า ssid รหัสผ่าน ลงใน เมมโมรี่ 
struct EepromObj_wifimanager { 
  char parm_ssid[64]; 
  char parm_pass[24]; 
}; 
EepromObj_wifimanager saveparm; 
ฟังก์ชั่น readParm() ใช้อ่านข้อมูลที่บันทึกอยู่ในแฟลชเมมโมรี
// อ่านข้อมูลจากเมมโมรี
void readParm() {
  EEPROM.get(2, saveparm);
  ssid = saveparm.parm_ssid;
  password = saveparm.parm_pass;
  delay(500);
  Serial.print("SSID : " );
  Serial.println(ssid);
  Serial.print("PASSWORD : " );
  Serial.println(password);
}

โค้ดฟังก์ชั่น

ฟังก์ชั่น writeParm() ใช้อ่านข้อมูลที่บันทึกอยู่ในแฟลชเมมโมรี
// เขียนข้อมูลลงในเมมโมรี
void writeParm() {
EEPROM.put(2, saveparm);
EEPROM.commit();
delay(500);
Serial.println("Saved Parm to Memory");
}
ฟังก์ชั่น WiFi_init() ฟังก์ชั่นส่งคืนค่าบูลีน (true, false) เพื่อตรวจสอบว่า ESP32 เชื่อมต่อกับเครือข่าย WiFi ได้สำเร็จหรือไม่ เรียนรู้การใช้งานการเชื่อมต่อ WiFi ได้ที่  ESP32 WiFi Library Functions
// เริ่มต้นใช้งานการเชื่อมต่อ WiFi
bool WiFi_init() {
unsigned long pastTime = 0;
unsigned long nowTime = 0;
unsigned long timeOut = 10000;
// ตรวจสอบ ssid มีข้อมูลบันทึกอยู่หรือไม่
if(String(ssid)==""){
Serial.println("Unable connect to Wi-Fi");
return false;
}
// ตั้งค่า 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());
return true;
}
else {
Serial.print("Unable connect to Wi-Fi " + String(ssid));
WiFi.disconnect();
return false;
}
}

ภายใน void setup()

เริ่มต้นเรียกใช้งาน แฟลชเมมโมรีของบอร์ด ESP32 ด้วย EEPROM.begin()
//เริ่มต้นใช้งาน EEPROM
EEPROM.begin(512);
เรียกใช้ฟังก์ชั่น readParm() เพื่ออ่านข้อมูลในแฟลชเมมโมรีเพื่อรับ SSID, รหัสผ่าน ที่บันทึกไว้ก่อนหน้านี้
readParm();
ในกรณี ESP เชื่อมต่อ WiFi สำเร็จในโหมด Station ฟังก์ชั่น WiFi_init() จะส่งคืนค่า true แต่หากเชื่อมต่อไม่สำเร็จจะส่งคืนค่า false และเปลี่ยนเป็นโหมด Access Point
if (!WiFi_init()) {
Serial.println("Setting AP (Access Point)");
// ตั้งค่า Access Point
WiFi.softAP("ESP-WIFI-MANAGER", "Deva_DIY");
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
softAP() ส่งอาร์กิวเมนต์ชื่อสำหรับจุดเชื่อมต่อและรหัสผ่าน ในตัวอย่างตั้งชื่อจุดใช้งาน “ESP-WIFI-MANAGER” และ รหัสผ่าน “Deva_DIY” หากต้องการเข้าใช้งานโดยไม่ต้องใช้รหัสผ่านให้เปลี่ยน “Deva_DIY” เป็น NULL หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับการตั้งค่า Access Point โปรดอ่านบทช่วยสอนต่อไปนี้: วิธีการใช้งาน WiFi library
WiFi.softAP("ESP-WIFI-MANAGER", NULL);
เมื่อเชื่อมต่อกับบอร์ดESP ผ่าน Access Point ได้แล้ว จะแสดงหน้าเว็บ WiFi Manager เพื่อป้อนข้อมูลในแบบฟอร์ม ดังนั้น ESP จะต้องส่งข้อมูล wifimanager_html เมื่อได้รับคำขอบนรูท / URL
// Web Server Root URL
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
request-&gt;send_P(200, "text/html", wifimanager_html);
});
เมื่อมีการส่งคำขอ /wifi ผ่าน HTTP POST  โค๊ดในส่วนนี้จะจะบันทึกค่าพารามิเตอร์ที่ส่งในผ่านในชื่อ name=”ssid” ลงในตัวแปร ssid และ name=”password” ลงในตัวแปร  password
// Get the parameters submited on the form
server.on("/wifi", HTTP_POST, [](AsyncWebServerRequest * request) {
int params = request-&gt;params();
for (int i = 0; i &lt; params; i++) { AsyncWebParameter* p = request-&gt;getParam(i);
if (p-&gt;isPost())
{
// HTTP POST ssid value
if (p-&gt;name() == "ssid") {
ssid = p-&gt;value().c_str();
Serial.print("[Parameter Value] SSID : ");
Serial.println(ssid);
strcpy(saveparm.parm_ssid, ssid);
}
// HTTP POST pass value
if (p-&gt;name() == "password") {
password = p-&gt;value().c_str();
Serial.print("[Parameter Value] Password : ");
Serial.println("********");
strcpy(saveparm.parm_pass, password);
}
}
}
เมื่อบันทึกค่าในตัวแปร ssid, password แล้ว ถัดไปจะบันทึกค่าเหล่านี้ในตัวแปร struct บันทึกค่าจาก ssid ไปเก็บที่ saveparm.parm_ssid
strcpy(saveparm.parm_ssid, ssid);
บันทึกค่าจาก password ไปเก็บที่ saveparm.parm_pass
strcpy(saveparm.parm_pass, password);
ในบรรทัดนี้จะนำค่าที่อยู่ในตัวแปร struct บันทึกลงในแฟลชเมมโมรี่ ด้วยฟังก์ชั่น writeParm()
writeParm();
ถัดไปจะส่งข้อความตอบกลับไป เพื่อให้ทราบว่า ESP Server ได้รับข้อมูลในฟอร์มเรียบร้อยแล้ว
request-&gt;send(200, "text/plain", " saved done. ESP32 will restart connect to your router");
หลังจากผ่านไป 2 วินาที จะรีสตาร์ทบอร์ด ESP ด้วยคำสั่ง ESP.restart()
delay(2000);
ESP.restart();

Download Code ดาวน์โหลดไฟล์ทั้งหมดได้ที่นี้

กรุณา เข้าสู่ระบบ เพื่อดาวน์โหลด

สรุป

บทความนี้สอนการสร้างหน้า wifi manager ด้วยโปรแกรม ARDUNIO IDE บนบอร์ด ESP32 ช่วยให้การเชื่อมต่อกับเครื่อข่ายอื่นๆทำได้ง่าย โดยที่ไม่ต้องไปแก้ไขโค๊ดโปรแกรมและอัพโหลดใหม่ Deva DIY หวังว่าบทความนี้จะเป็นประโยชน์กับโครงงาน ioT ของคุณ เรียนรู้เพิ่มเติมเกี่ยวกับ ESP32 :
Shopping Cart
Scroll to Top