📡 ESP32 به وایفای وصل نمیشود؟ عیبیابی قدم به قدم با یک کد تشخیص
نقطهها پشت سر هم در سریال مانیتور چاپ میشوند و هیچوقت «Connected» نمیآید. اگر ESP32 به وایفای وصل نمیشود، تنها نیستی؛ این رایجترین مشکل پروژههای اینترنت اشیاست. خبر خوب این است که تقریباً همیشه دلیلش یکی از چند مورد مشخص است و خود ESP32 میتواند بگوید کدام. در این آموزش یک کد تشخیص مینویسیم که شبکههای اطراف را اسکن میکند، وضعیت اتصال را با اسم چاپ میکند و دلیل قطع شدن را میگوید، و بعد سراغ فهرست علتها و راهحلها میرویم.
قدم اول: کد تشخیص
این کد را روی برد بریز و اسم و رمز شبکهات را جایگزین کن. هر جا گیر کردی، همین خروجی سریال مانیتور به تو میگوید مشکل کجاست. فقط به یک برد ESP32 نیاز داری.
// ESP32 Wi-Fi doctor: scans, connects with a timeout and explains failures.
#include <WiFi.h>
const char* ssid = "YOUR_WIFI"; // in the simulator: "Wokwi-GUEST"
const char* password = "YOUR_PASSWORD"; // in the simulator: ""
const char* statusName(wl_status_t s) {
switch (s) {
case WL_IDLE_STATUS: return "IDLE (trying)";
case WL_NO_SSID_AVAIL: return "NO_SSID_AVAIL (network not found)";
case WL_SCAN_COMPLETED: return "SCAN_COMPLETED";
case WL_CONNECTED: return "CONNECTED";
case WL_CONNECT_FAILED: return "CONNECT_FAILED (password or security)";
case WL_CONNECTION_LOST: return "CONNECTION_LOST";
case WL_DISCONNECTED: return "DISCONNECTED";
default: return "UNKNOWN";
}
}
void onWiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) {
if (event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED) {
Serial.print(" disconnect reason: ");
Serial.println(info.wifi_sta_disconnected.reason);
}
}
void scanNetworks() {
Serial.println("Scanning...");
int n = WiFi.scanNetworks();
bool found = false;
for (int i = 0; i < n; i++) {
Serial.print(" ");
Serial.print(WiFi.SSID(i));
Serial.print(" RSSI ");
Serial.print(WiFi.RSSI(i));
Serial.print(" ch ");
Serial.println(WiFi.channel(i));
if (WiFi.SSID(i) == ssid) found = true;
}
if (n <= 0) Serial.println(" No networks at all: antenna or power problem?");
Serial.println(found ? "Your network is visible." : "Your network is NOT visible (5 GHz only? hidden? too far?)");
WiFi.scanDelete();
}
bool connectWiFi(unsigned long timeoutMs) {
WiFi.begin(ssid, password);
unsigned long start = millis();
wl_status_t last = WL_NO_SHIELD;
while (millis() - start < timeoutMs) {
wl_status_t s = WiFi.status();
if (s != last) {
Serial.print("status ");
Serial.print((int) s);
Serial.print(" = ");
Serial.println(statusName(s));
last = s;
}
if (s == WL_CONNECTED) return true;
delay(250);
}
return false;
}
void setup() {
Serial.begin(115200);
delay(500);
WiFi.mode(WIFI_STA);
WiFi.persistent(false); // do not store old settings in flash
WiFi.disconnect();
WiFi.onEvent(onWiFiEvent);
scanNetworks();
if (connectWiFi(20000)) {
Serial.print("Connected. IP ");
Serial.print(WiFi.localIP());
Serial.print(" RSSI ");
Serial.print(WiFi.RSSI());
Serial.print(" dBm channel ");
Serial.println(WiFi.channel());
} else {
Serial.println("Gave up after 20 s. Read the status and reason lines above.");
}
}
void loop() {
static unsigned long last = 0;
if (millis() - last > 10000) { // check every 10 s
last = millis();
if (WiFi.status() != WL_CONNECTED) {
Serial.println("Wi-Fi lost, reconnecting...");
WiFi.disconnect();
connectWiFi(15000);
}
}
}
معنی کدهای WiFi.status
| عدد | نام | معمولاً یعنی |
|---|---|---|
| 0 | WL_IDLE_STATUS | در حال تلاش است؛ کمی صبر کن |
| 1 | WL_NO_SSID_AVAIL | شبکهای با این اسم پیدا نشد |
| 3 | WL_CONNECTED | وصل است و IP دارد |
| 4 | WL_CONNECT_FAILED | رمز یا نوع امنیت مشکل دارد |
| 5 | WL_CONNECTION_LOST | وصل بود و قطع شد |
| 6 | WL_DISCONNECTED | هنوز وصل نشده؛ اگر طول کشید اغلب رمز اشتباه است |
| 255 | WL_NO_SHIELD | وایفای روشن نشده است |
روی ESP32 رمز اشتباه همیشه به عدد ۴ نمیرسد و خیلی وقتها برد روی ۶ میماند. برای همین کد بالا دلیل قطع (reason) را هم چاپ میکند که دقیقتر است:
| reason | معنی |
|---|---|
| 201 | شبکه پیدا نشد (اسم اشتباه، ۵ گیگاهرتز، دور بودن) |
| 15 یا 204 | دستدادن رمزنگاری تمام نشد؛ تقریباً همیشه رمز اشتباه |
| 202 | احراز هویت رد شد (رمز یا نوع امنیت) |
| 203 | مودم اتصال را نپذیرفت (فیلتر MAC، پر بودن ظرفیت) |
| 2 | احراز هویت منقضی شد؛ معمولاً سیگنال ضعیف |
| 8 | خودمان قطع کردیم (WiFi.disconnect)؛ نگران نباش |
در هستهی ۳ آردوینوی ESP32 کدهای ۲۱۰ تا ۲۱۲ هم ممکن است ببینی؛ یعنی شبکه پیدا شد ولی نوع امنیت یا قدرت سیگنالش با تنظیمات برد جور نیست.
علتها و راهحلها
۱. شبکه فقط ۵ گیگاهرتز است
ESP32 فقط وایفای ۲٫۴ گیگاهرتز را میبیند. اگر در اسکن اسم شبکهات نیست ولی گوشیات آن را میبیند، احتمالاً همین است. در تنظیمات مودم باند ۲٫۴ را روشن کن. اگر مودم هر دو باند را با یک اسم پخش میکند و برد گاهی وصل نمیشود، برای باند ۲٫۴ اسم جدا بگذار.
۲. اسم یا رمز اشتباه
اسم و رمز به حروف بزرگ و کوچک حساساند و یک فاصلهی اضافه در آخر رمز کافی است تا هیچوقت وصل نشوی. اسم شبکهای که حروف فارسی یا شکلک دارد هم گاهی مشکلساز است؛ برای امتحان یک اسم سادهی انگلیسی بگذار.
۳. نوع امنیت
حالت WPA2-PSK (با AES) یا حالت ترکیبی WPA2/WPA3 بهترین انتخاب است. شبکههای فقط WPA3، WEP قدیمی، و شبکههای سازمانی دانشگاه و اداره (WPA2-Enterprise با نام کاربری) با کد سادهی بالا وصل نمیشوند. شبکههای هتل و خوابگاه که بعد از اتصال صفحهی ورود باز میکنند هم مناسب نیستند؛ برد وصل میشود ولی به اینترنت نمیرسد.
۴. کانال ۱۲ و ۱۳
بعضی مودمها خودکار روی کانال ۱۲ یا ۱۳ میروند. اگر برد با بقیهی شبکهها مشکلی ندارد ولی با این یکی وصل نمیشود، کانال مودم را دستی روی ۱، ۶ یا ۱۱ بگذار.
۵. سیگنال ضعیف و آنتن
RSSI در اسکن بین ۳۰- و ۶۰- عالی است و پایینتر از ۸۰- مشکلساز. آنتن چاپی روی برد را با دست، فلز یا بردبورد بزرگ نپوشان و برد را نزدیکتر ببر. بردهایی که سوکت آنتن بیرونی دارند، بدون آنتن تقریباً هیچ شبکهای نمیبینند.
۶. تغذیهی ضعیف
ESP32 لحظهی روشن کردن رادیو جریان زیادی میکشد. با کابل USB نازک، پورت جلوی کیس یا هاب، ولتاژ افت میکند و پیام Brownout detector was triggered میبینی و برد مدام ریاستارت میشود. کابل کوتاه و خوب، پورت پشت کیس یا یک منبع ۵ ولت جدا امتحان کن؛ یک خازن ۱۰۰ تا ۴۷۰ میکروفاراد بین 3V3 و GND هم کمک میکند.
۷. اشکالهای کد
- صدا زدن
WiFi.beginدر هر دورloopهر بار تلاش قبلی را از نو شروع میکند و هیچوقت به نتیجه نمیرسد. - حلقهی
whileبدون تایماوت برنامه را برای همیشه قفل میکند؛ مثل کد بالا محدودیت زمان بگذار. - اگر قبلاً برد در حالت Access Point بوده، حالت را صریحاً با
WiFi.mode(WIFI_STA)تعیین کن.
۸. محدودیتهای مودم
فیلتر آدرس MAC، پر بودن ظرفیت DHCP یا محدودیت تعداد کاربر باعث میشود اتصال رد شود (reason ۲۰۳). آدرس MAC برد را با WiFi.macAddress() چاپ کن و در مودم مجاز کن. هاتاسپات گوشی هم آزمایش خوبی است؛ در آیفون گزینهی Maximize Compatibility را روشن کن تا روی ۲٫۴ گیگاهرتز پخش شود.
در شبیهساز چه چیزی را تمرین کنیم؟
علتهای رادیویی، یعنی ۵ گیگاهرتز، کانال، آنتن و تغذیه، فقط روی برد واقعی پیدا میشوند. ولی منطق اتصال کاملاً در شبیهساز تمرینشدنی است: حلقهی وصل شدن با تایماوت، چاپ وضعیت و وصل شدن دوباره. در شبیهساز، مثل ووکوی (Wokwi)، اسم شبکه Wokwi-GUEST و رمز خالی است. یک بار هم عمداً اسم را اشتباه بنویس و ببین کد تو بعد از تایماوت چه رفتاری میکند. نمونهی آمادهی وصل شدن ESP32 به وایفای، پروژهی بامزهی وایفای و چراغ نفسکش و درس «وصل شدن به وایفای» در تینکرکد فارسی هستند. خواندنشان رایگان است و اجرای برد ESP32 اشتراک Plus میخواهد.
فهرست سریع
- اسکن را ببین: اسم شبکه هست؟ اگر نیست، ۵ گیگاهرتز، دوری یا آنتن.
- اگر هست ولی reason ۱۵ یا ۲۰۴ میگیری، رمز را دوباره و حرف به حرف بنویس.
- اگر برد ریاستارت میشود، کابل و تغذیه را عوض کن.
- اگر فقط با یک مودم مشکل داری، امنیت را WPA2 و کانال را ۱، ۶ یا ۱۱ کن.
- با هاتاسپات گوشی امتحان کن تا بفهمی مشکل از برد است یا از مودم.
آموزش پایهای اتصال را در وصل شدن ESP32 به وایفای ببین. اگر مشکل تو پیش از این مرحله است و اصلاً برنامه روی برد نمیرود، خطای آپلود ESP32 را بخوان. همهی پروژههای شبکه هم در وایفای و اینترنت اشیا جمع شدهاند.
حلقهی اتصال وایفای را در شبیهساز امتحان کن 📶سؤالهای رایج
چرا ESP32 شبکهی وایفای خانه را پیدا نمیکند؟
رایجترین دلیل این است که مودم فقط روی ۵ گیگاهرتز پخش میکند. ESP32 فقط وایفای ۲٫۴ گیگاهرتز را میبیند. باند ۲٫۴ را روشن کن یا با هاتاسپات گوشی روی ۲٫۴ گیگاهرتز امتحان کن.
WiFi.status عدد ۶ برمیگرداند؛ یعنی چه؟
عدد ۶ یعنی WL_DISCONNECTED. روی ESP32 این حالت معمولاً یعنی هنوز وصل نشده است و اگر طولانی شد، اغلب رمز اشتباه است. دلیل دقیق را از رویداد قطع اتصال و کد reason آن بخوان؛ مثلاً ۲۰۱ یعنی شبکه پیدا نشد.
در شبیهساز چه اسم و رمزی بگذارم؟
در شبیهساز اسم شبکه Wokwi-GUEST با همین حروف بزرگ و خط تیره است و رمز خالی است. این شبکه به اینترنت واقعی نمیرسد، ولی برای تمرین وصل شدن، تایماوت و وصل شدن دوباره کافی است.