📡 ESP32 در حالت Access Point: وبسرور بدون مودم با WiFi.softAP
تا اینجا هر وبسروری که روی ESP32 ساختیم، به یک مودم وصل میشد: برد از مودم IP میگرفت و گوشی از طریق همان مودم صفحه را باز میکرد. ولی اگر مودمی نباشد چه؟ وسط حیاط، در کلاس، روی یک ربات یا در غرفهی جشنواره. اینجاست که ESP32 در حالت Access Point به کار میآید: خود برد یک شبکهی وایفای میسازد، گوشی مستقیم به آن وصل میشود و صفحهی کنترل را در آدرس 192.168.4.1 باز میکند. در این آموزش با WiFi.softAP یک چراغ بیسیم میسازیم که هیچ مودمی لازم ندارد، و همهچیز را در شبیهساز ESP32 امتحان میکنیم؛ همان کاری که در ووکوی (Wokwi) انجام میدهی.
سه حالت وایفای ESP32
| حالت | دستور | یعنی چه؟ | کی به کار میآید |
|---|---|---|---|
| Station | WIFI_STA | برد مثل گوشی به یک مودم وصل میشود | وقتی اینترنت یا شبکهی خانه لازم است |
| Access Point | WIFI_AP | برد خودش مودم کوچکی میشود | جایی که مودم نیست؛ صفحهی تنظیمات اولیه |
| هر دو | WIFI_AP_STA | هم به مودم وصل است و هم شبکهی خودش را دارد | دستگاهی که هم گزارش میفرستد و هم مستقیم کنترل میشود |
حالت Station را در وصل شدن ESP32 به وایفای یاد گرفتیم. حالا نوبت حالت دوم است. نکتهی مهم: در حالت AP خالص، برد و گوشی هیچکدام به اینترنت دسترسی ندارند؛ فقط با هم حرف میزنند. برای کنترل یک چراغ یا ربات همین کافی است.
قطعهها و سیمکشی
| قطعه | اتصال |
|---|---|
| ESP32 | — |
| مقاومت ۲۲۰ اهم | بین GPIO4 و پایهی بلند LED |
| LED | پایهی کوتاه به GND |
کد کامل
// ESP32 as its own Wi-Fi network (Access Point) + a page that controls an LED.
#include <WiFi.h>
#include <WebServer.h>
const char* AP_NAME = "ESP32-Lamp";
const char* AP_PASS = "12345678"; // at least 8 characters, or "" for an open network
const int LED = 4;
WebServer server(80);
bool ledOn = false;
String page() {
String html = "<!doctype html><html><head><meta charset='utf-8'>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1'>";
html += "<title>ESP32 Lamp</title></head>";
html += "<body style='font-family:sans-serif;text-align:center;padding-top:30px'>";
html += "<h2>ESP32 Access Point</h2>";
html += "<p>LED is <b>" + String(ledOn ? "ON" : "OFF") + "</b></p>";
html += "<p><a href='/on'><button style='font-size:22px'>ON</button></a> ";
html += "<a href='/off'><button style='font-size:22px'>OFF</button></a></p>";
html += "<p>Uptime: " + String(millis() / 1000) + " s</p>";
html += "</body></html>";
return html;
}
void handleRoot() {
server.send(200, "text/html", page());
}
void setLed(bool on) {
ledOn = on;
digitalWrite(LED, on ? HIGH : LOW);
server.sendHeader("Location", "/"); // go back to the main page
server.send(303, "text/plain", "");
}
void setup() {
Serial.begin(115200);
pinMode(LED, OUTPUT);
WiFi.mode(WIFI_AP);
bool ok = WiFi.softAP(AP_NAME, AP_PASS);
if (!ok) {
Serial.println("softAP failed. Is the password at least 8 characters?");
return;
}
Serial.print("Wi-Fi network: ");
Serial.println(AP_NAME);
Serial.print("Open http://");
Serial.println(WiFi.softAPIP()); // normally 192.168.4.1
server.on("/", handleRoot);
server.on("/on", []() { setLed(true); });
server.on("/off", []() { setLed(false); });
server.onNotFound([]() { server.send(404, "text/plain", "Not found"); });
server.begin();
}
void loop() {
server.handleClient(); // answer the phone's requests
}
توضیح بخشهای مهم
WiFi.mode(WIFI_AP)به برد میگوید این بار مهمان نیست، میزبان است. اگر همزمان بخواهی به مودم خانه هم وصل باشی،WIFI_AP_STAبنویس و بعد همsoftAPو همWiFi.beginرا صدا بزن.WiFi.softAP(AP_NAME, AP_PASS)شبکه را میسازد. اسم شبکه همانی است که در لیست وایفای گوشی میبینی. رمز باید حداقل ۸ حرف باشد؛ اگر کوتاهتر باشد، این دستورfalseبرمیگرداند و برای همین نتیجهاش را چک میکنیم. این دستور پارامترهای اختیاری هم دارد: شمارهی کانال (۱ تا ۱۳)، پنهان بودن اسم شبکه و حداکثر تعداد دستگاهها که پیشفرضش ۴ است.WiFi.softAPIP()آدرس برد در شبکهی خودش است و بهطور پیشفرض192.168.4.1. حواست باشد اینجا ازWiFi.localIP()استفاده نکنی؛ آن آدرس حالت Station است و در حالت AP خالص صفر برمیگرداند.page()صفحهی HTML را بهصورت یک رشته میسازد. خطviewportباعث میشود صفحه روی گوشی درشت و خوانا باشد، نه ریز مثل نسخهی دسکتاپ.- در
setLedبعد از عوض کردن LED، با کد303و سرآیندLocationمرورگر را به صفحهی اصلی برمیگردانیم. این یک عادت خوب است: اگر کاربر صفحه را رفرش کند، دستور «روشن کن» دوباره فرستاده نمیشود و آدرس نوار مرورگر هم تمیز میماند. server.handleClient()درloopواجب است. بدون آن، برد درخواستها را میگیرد ولی هیچوقت جواب نمیدهد و صفحه در گوشی تا ابد در حال بارگذاری میماند.
وصل شدن با گوشی (روی برد واقعی)
- کد را آپلود کن و سریال مانیتور را روی ۱۱۵۲۰۰ باز کن تا پیام
Open http://192.168.4.1را ببینی. - در تنظیمات وایفای گوشی، شبکهی ESP32-Lamp را پیدا کن و با رمز ۱۲۳۴۵۶۷۸ وصل شو.
- گوشی احتمالاً میگوید «این شبکه اینترنت ندارد». گزینهی «متصل بمان» را بزن. اگر صفحه باز نشد، اینترنت سیمکارت را موقتاً خاموش کن؛ بعضی گوشیها وقتی وایفای اینترنت ندارد، درخواستها را از سیمکارت میفرستند.
- در مرورگر آدرس
http://192.168.4.1را بزن (با http، نه https) و با دکمهها LED را کنترل کن.
12345678 فقط برای تمرین است. در پروژهای که جایی نصب میشود، رمز را عوض کن؛ هر کسی که در شعاع چند ده متری باشد شبکهی ESP32 را میبیند.اجرا در شبیهساز
شبیهساز ESP32 تینکرکد فارسی حالت softAP را پشتیبانی میکند: کد بالا را اجرا کن تا پیام آدرس 192.168.4.1 در سریال مانیتور بیاید، بعد تب «مرورگر» ویرایشگر را باز کن. صفحهی برد همانجا باز میشود و با زدن دکمههای ON و OFF، LED روی صحنه روشن و خاموش میشود. البته شبکهی شبیهساز مجازی است: نه گوشی واقعی میتواند به آن وصل شود و نه به اینترنت واقعی میرسد، که برای این پروژه اصلاً لازم نیست. خواندن مثالها رایگان است و اجرای ESP32 به اشتراک Plus نیاز دارد. پروژهی آمادهی LED از مرورگر همین صفحه را در حالت Station دارد؛ کافی است بخش وایفای آن را با softAP عوض کنی. درس «وبسرور: LED از مرورگر» هم ساختن صفحه را قدمبهقدم درس میدهد.
چند قابلیت بیشتر برای برد واقعی
- آدرس دلخواه: قبل از
softAP، باWiFi.softAPConfig(ip, gateway, subnet)میتوانی آدرسی مثل 10.0.0.1 بگذاری. - شمارش دستگاهها:
WiFi.softAPgetStationNum()میگوید الان چند گوشی وصلاند؛ میشود با آن یک LED «کسی وصل است» ساخت. - صفحهی خودکار (Captive Portal): با کتابخانهی
DNSServerهر آدرسی که کاربر بزند به صفحهی برد هدایت میشود و گوشی خودش صفحه را باز میکند؛ همان چیزی که در وایفای هتلها میبینی. بیشتر صفحههای «تنظیم وایفای» دستگاههای هوشمند همینطور ساخته شدهاند.
اشکالهای رایج
- شبکه در گوشی دیده نمیشود: رمز کمتر از ۸ حرف است و
softAPشکست خورده؛ پیام سریال را ببین. - گوشی وصل میشود ولی صفحه باز نمیشود: اینترنت سیمکارت را خاموش کن و آدرس را با
http://بزن. - در سریال آدرس 0.0.0.0 چاپ میشود: بهجای
softAPIPازlocalIPاستفاده کردهای. - صفحه بار نمیشود و برد هم ریست نمیشود:
server.handleClient()درloopنیست، یا یکdelayطولانی جلویش را گرفته. - پنجمین گوشی وصل نمیشود: سقف پیشفرض ۴ دستگاه است؛ آن را با پارامتر آخر
softAPزیاد کن. - analogRead بعد از روشن شدن AP خراب شد: AP هم وایفای است و ADC2 را میگیرد؛ سنسور را به ADC1 ببر (پین اوت ESP32).
این صفحه را میتوانی خیلی زیباتر و زندهتر کنی: با WebSocket وضعیت LED بدون رفرش عوض میشود و با صفحهی وب در SPIFFS HTML را جدا از کد نگه میداری. همهی پروژههای شبکه در وایفای و اینترنت اشیا و صفحهی ESP32 جمع شدهاند.
وبسرور ESP32 را در تینکرکد فارسی باز کن 📡سؤالهای رایج
آدرس وبسرور ESP32 در حالت Access Point چیست؟
بهصورت پیشفرض 192.168.4.1 است. بعد از وصل شدن گوشی به شبکهی ESP32، همین آدرس را با http در مرورگر باز کن. با دستور WiFi.softAPIP میتوانی آن را در سریال مانیتور هم ببینی.
رمز softAP در ESP32 باید چند حرف باشد؟
حداقل ۸ حرف. اگر رمز کوتاهتر بدهی، softAP شکست میخورد و شبکه ساخته نمیشود. برای شبکهی بدون رمز، رشتهی خالی بده یا رمز را اصلاً ننویس.
چند گوشی میتوانند همزمان به Access Point ESP32 وصل شوند؟
بهصورت پیشفرض تا ۴ دستگاه. با پارامتر آخر WiFi.softAP میتوانی این عدد را تا ۱۰ بالا ببری، ولی برای یک وبسرور ساده ۴ کافی است.
ESP32 در حالت Access Point به اینترنت وصل است؟
نه. در این حالت خود ESP32 شبکه است و به هیچ مودمی وصل نیست، پس دستگاههای وصلشده فقط با خود برد حرف میزنند. برای داشتن هر دو، حالت WIFI_AP_STA را استفاده کن.