ESP32 前面的 GPIO、ADC、PWM、I²C、SPI、UART 等功能,主要都在處理「ESP32 與周邊硬體之間的連接」。從本章開始,我們正式進入 ESP32 最重要、也最有價值的特色之一:Wi-Fi 無線網路與 IoT 網路應用。
ESP32 本身整合 Wi-Fi 功能,因此不像 Arduino UNO R3 通常需要另外加裝 Wi-Fi Shield、ESP8266 或其他網路模組。只要透過 Arduino IDE 內建於 ESP32 Core 的 WiFi.h,就能讓 ESP32 連接家中路由器、手機熱點或公司的無線網路。
連上 Wi-Fi 之後,ESP32 就可以進一步實作:
- 網頁伺服器 Web Server
- HTTP / HTTPS API
- MQTT
- IoT 感測器
- 手機遠端控制
- 雲端資料上傳
- 網路時間 NTP
- OTA 無線更新
- Home Assistant
- LINE / Telegram 通知
- 即時環境監控
因此,學會 ESP32 WiFi 是從一般微控制器專題跨入真正 IoT 系統的重要分水嶺。
本章將完整介紹:
WiFi.h、Station Mode、STA、SSID、Password、DHCP、IP Address、RSSI、MAC Address、Wi-Fi Scan 與 Wi-Fi 自動重連,最後完成一個:
ESP32 Wi-Fi 掃描器 + 網路狀態顯示器
讓 ESP32 可以掃描附近基地台、連接指定 Wi-Fi,並持續顯示 IP、MAC、SSID、RSSI 與目前連線狀態。
一、什麼是 ESP32 Wi-Fi?
ESP32 內建 Wi-Fi 無線網路功能,可以直接和無線基地台 Access Point、Wi-Fi Router 或手機熱點通訊。
Arduino ESP32 官方 Wi-Fi API 支援 Station、Access Point 以及 Wi-Fi 網路掃描等功能。目前官方 Arduino-ESP32 文件也持續以 WiFi.h 作為 Arduino 環境下操作 ESP32 Wi-Fi 的主要介面。
ESP32 常見的 Wi-Fi 運作模式主要有三種:
| 模式 | 說明 | 常見用途 |
|---|---|---|
| STA | Station Mode | ESP32 連接家中 Router |
| AP | Access Point Mode | 手機直接連 ESP32 |
| AP + STA | 同時使用 AP 與 STA | 設定介面、IoT Gateway |
本章首先學習最重要也最常使用的:
STA Station Mode
二、什麼是 Station Mode?
Station Mode 簡稱:
STA
在 STA 模式中,ESP32 的角色就和:
- Notebook
- iPhone
- Android 手機
- 平板電腦
- Smart TV
類似。
也就是:
ESP32
│
│ Wi-Fi
▼
Wireless Router
│
├── LAN
│
└── Internet
ESP32 主動加入現有 Wi-Fi 網路,而不是自己建立一個 Wi-Fi 基地台。
Arduino ESP32 官方文件將 STA 定義為 ESP32 連接到 Access Point 的模式;如果 ESP32 專案需要透過既有網路連上 Internet,STA 就是最主要的使用方式。
程式中通常使用:
WiFi.mode(WIFI_STA);
設定 ESP32 為 Station Mode。
三、ESP32 WiFi.h 函式庫
Arduino IDE 開發 ESP32 Wi-Fi 最重要的函式庫就是:
#include <WiFi.h>
只要安裝好:
ESP32 Arduino Core
通常不需要另外安裝第三方 Wi-Fi Library。
最基本的 ESP32 WiFi 程式只有幾行:
#include <WiFi.h>
const char* ssid = "你的WiFi名稱";
const char* password = "你的WiFi密碼";
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi Connected!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
}
void loop() {
}
官方 Arduino ESP32 文件也是以:
WiFi.begin(ssid, password);
開始 STA 連線,並使用:
WiFi.status() == WL_CONNECTED
判斷是否完成連線,再使用:
WiFi.localIP()
取得 IP Address。
四、什麼是 SSID?
SSID 全名是:
Service Set Identifier
簡單來說,就是:
Wi-Fi 網路名稱。
例如手機看到:
WCST_2.4G
ASUS_WIFI
Jason_Home
TP-Link_A520
iPhone
這些就是 SSID。
ESP32 程式通常寫成:
const char* ssid = "WCST_WIFI";
連線時:
WiFi.begin(ssid, password);
五、Password Wi-Fi 密碼
如果 Wi-Fi 有 WPA / WPA2 / WPA3 等密碼保護,就需要提供 Password。
例如:
const char* password = "12345678";
再使用:
WiFi.begin(ssid, password);
完整形式:
const char* ssid = "WCST_WIFI";
const char* password = "your_password";
WiFi.begin(ssid, password);
正式產品中不建議直接將真正 Wi-Fi 密碼公開在 GitHub 或公開下載的 .ino 程式裡。
比較好的做法是另外建立:
secrets.h
例如:
#define WIFI_SSID "WCST_WIFI"
#define WIFI_PASSWORD "your_password"
然後:
#include "secrets.h"
這對未來 ESP32 IoT 專案會非常重要。
六、WiFi.status():判斷 ESP32 網路狀態
ESP32 可以利用:
WiFi.status()
取得目前 Wi-Fi 狀態。
最常使用的是:
if (WiFi.status() == WL_CONNECTED)
代表 ESP32 已經成功連接 Wi-Fi。
例如:
if (WiFi.status() == WL_CONNECTED) {
Serial.println("WiFi Connected");
}
else {
Serial.println("WiFi Disconnected");
}
常見 Wi-Fi 狀態
常見狀態包括:
| 狀態 | 意義 |
|---|---|
| WL_CONNECTED | 已成功連線 |
| WL_NO_SSID_AVAIL | 找不到指定 SSID |
| WL_CONNECT_FAILED | Wi-Fi 連線失敗 |
| WL_CONNECTION_LOST | 連線中斷 |
| WL_DISCONNECTED | 尚未連線或已斷線 |
| WL_IDLE_STATUS | Wi-Fi 正在處理 |
因此不要只在 ESP32 開機時檢查 Wi-Fi。
真正穩定的 IoT 程式還必須持續監控:
WiFi.status()
七、什麼是 DHCP?
ESP32 連接 Wi-Fi 之後還需要一個 IP Address 才能進行 TCP/IP 網路通訊。
一般情況不需要自己指定。
家庭 Router 通常會執行:
DHCP Server
自動分配:
- IP Address
- Gateway
- Subnet Mask
- DNS Server
給 ESP32。
例如:
ESP32
│
▼
Wi-Fi Router
│
├── IP:192.168.1.105
├── Gateway:192.168.1.1
├── Mask:255.255.255.0
└── DNS:192.168.1.1
這就是:
DHCP 自動取得 IP。
所以最基本的程式:
WiFi.begin(ssid, password);
連線成功之後,一般就會由網路中的 DHCP Server 分配 IP。
若未來有需要,也可以使用 WiFi.config() 設定 Static IP;Arduino ESP32 官方 API 提供 local IP、Gateway、Subnet 與 DNS 的自訂設定能力。
八、取得 ESP32 IP Address
Wi-Fi 連線完成之後,可以使用:
WiFi.localIP()
讀取 ESP32 的 IP Address。
例如:
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
Serial Monitor 可能顯示:
IP Address: 192.168.1.105
這個 IP 非常重要。
下一章開始建立:
ESP32 Web Server
時,瀏覽器就是利用這個 IP 找到 ESP32。
例如:
http://192.168.1.105/
九、ESP32 MAC Address 是什麼?
除了 IP Address 之外,每個網路介面還具有 MAC Address。
MAC 是:
Media Access Control Address
一般格式例如:
24:6F:28:12:34:56
ESP32 可以使用:
WiFi.macAddress()
讀取 Station Wi-Fi MAC Address:
Serial.print("MAC Address: ");
Serial.println(WiFi.macAddress());
輸出可能是:
MAC Address: 24:6F:28:12:34:56
IP 與 MAC 有什麼差別?
可以簡單理解為:
MAC Address → 網路卡身分
IP Address → 目前所在網路上的通訊地址
例如:
| 項目 | 範例 |
|---|---|
| MAC | 24:6F:28:12:34:56 |
| IP | 192.168.1.105 |
DHCP 分配的 IP 可能會改變,但 MAC 通常用來識別同一個網路裝置。
因此 Router 的:
DHCP Reservation
功能通常也是根據 MAC Address 幫 ESP32 固定 IP。
十、RSSI:判斷 ESP32 Wi-Fi 訊號強度
ESP32 可以讀取目前 Wi-Fi 訊號強度:
WiFi.RSSI()
RSSI:
Received Signal Strength Indicator
單位通常為:
dBm
例如:
Serial.print("RSSI: ");
Serial.print(WiFi.RSSI());
Serial.println(" dBm");
可能輸出:
RSSI: -48 dBm
RSSI 數字為什麼是負數?
Wi-Fi RSSI 越接近:
0
代表訊號越強。
所以:
-40 dBm
比:
-80 dBm
強很多。
可大致用下表判斷:
| RSSI | 訊號品質 |
|---|---|
| -30 ~ -50 dBm | 非常強 |
| -50 ~ -60 dBm | 很好 |
| -60 ~ -67 dBm | 良好 |
| -67 ~ -70 dBm | 普通 |
| -70 ~ -80 dBm | 偏弱 |
| 小於 -80 dBm | 很弱 |
這只是實務上的概略判斷值,實際連線品質還會受到:
- AP 品質
- 天線
- ESP32 模組
- 牆壁
- 金屬遮蔽
- Wi-Fi Channel
- 同頻干擾
影響。
十一、ESP32 WiFi Scan 是什麼?
ESP32 不只可以連接 Wi-Fi,也可以像手機一樣:
搜尋附近所有 Wi-Fi 基地台。
最重要的函式為:
WiFi.scanNetworks();
例如:
int n = WiFi.scanNetworks();
n 就代表掃描到多少個 Wi-Fi Network。
官方 Wi-Fi API 的 scanNetworks() 同時支援同步、非同步、隱藏網路與指定 Channel 等進階參數;掃描完成後也可以利用 scanDelete() 清除上一輪掃描資料、釋放相關記憶體。
十二、第一個 ESP32 Wi-Fi Scan 程式
先做一個最基本的掃描程式。
#include <WiFi.h>
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(1000);
Serial.println("Scanning WiFi...");
int n = WiFi.scanNetworks();
if (n == 0) {
Serial.println("No WiFi networks found.");
}
else {
Serial.print(n);
Serial.println(" networks found:");
for (int i = 0; i < n; i++) {
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i));
Serial.print(" RSSI=");
Serial.print(WiFi.RSSI(i));
Serial.print(" dBm CH=");
Serial.println(WiFi.channel(i));
}
}
WiFi.scanDelete();
}
void loop() {
}
Serial Monitor 可能看到:
Scanning WiFi...
6 networks found:
1: WCST_WIFI RSSI=-41 dBm CH=6
2: ASUS_HOME RSSI=-54 dBm CH=11
3: TP-Link_1234 RSSI=-63 dBm CH=1
4: iPhone RSSI=-70 dBm CH=6
5: Office_WIFI RSSI=-78 dBm CH=11
6: Guest RSSI=-85 dBm CH=1
此時 ESP32 已經變成簡單的:
Wi-Fi Scanner。
十三、Wi-Fi Channel 是什麼?
掃描結果中還可以取得:
WiFi.channel(i)
例如:
CH 1
CH 6
CH 11
代表 Wi-Fi 使用的無線頻道。
如果附近有很多基地台都集中在相同頻道,就可能造成:
Wi-Fi Interference
因此 ESP32 WiFi Scan 不只是找 SSID,也可以作為簡單的:
2.4 GHz Wi-Fi 環境分析工具。
十四、ESP32 連接指定 Wi-Fi
現在加入真正的 Wi-Fi Connection。
#include <WiFi.h>
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi Connected!");
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
Serial.print("MAC Address: ");
Serial.println(WiFi.macAddress());
Serial.print("RSSI: ");
Serial.print(WiFi.RSSI());
Serial.println(" dBm");
}
void loop() {
}
十五、為什麼不建議永遠卡在 while 等 Wi-Fi?
很多初學範例會寫:
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
教學沒有問題,但正式系統要小心。
假設:
- Router 關機
- SSID 寫錯
- Password 寫錯
- AP 故障
ESP32 就可能永遠卡在:
while()
後面的:
- 感測器
- 按鍵
- LCD
- Relay
- Safety Control
全部不會執行。
比較好的方式是加入:
Connection Timeout。
例如:
unsigned long startTime = millis();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED &&
millis() - startTime < 15000) {
delay(500);
Serial.print(".");
}
最多等:
15 秒
如果仍連不上,ESP32 可以繼續做其他事情。
這才比較符合 IoT 裝置的實際設計。
十六、ESP32 Wi-Fi 自動重連
IoT 裝置通常 24 小時開機。
如果 Router:
- 重新開機
- 短暫斷電
- Wi-Fi Restart
- 訊號短暫消失
ESP32 不應該需要人工 Reset。
Arduino ESP32 提供:
WiFi.setAutoReconnect(true);
啟用自動重新連線。
例如:
WiFi.mode(WIFI_STA);
WiFi.setAutoReconnect(true);
WiFi.begin(ssid, password);
另外還可以手動執行:
WiFi.reconnect();
目前 Arduino ESP32 官方文件仍提供 reconnect() 與 setAutoReconnect();相較之下,舊的 setAutoConnect() 已被標示為 deprecated,因此新程式不建議再依賴 setAutoConnect()。
十七、推薦的 Wi-Fi 重連機制
正式程式最好同時保留:
Auto Reconnect
+
定期 Status Check
+
Manual Reconnect Fallback
例如:
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi disconnected!");
WiFi.reconnect();
}
但也不建議每一次 loop() 都執行 reconnect。
因為 loop() 可能一秒執行幾千甚至幾萬次。
應該加入時間控制。
例如每 10 秒檢查一次:
unsigned long lastReconnectAttempt = 0;
void loop() {
if (WiFi.status() != WL_CONNECTED) {
if (millis() - lastReconnectAttempt >= 10000) {
lastReconnectAttempt = millis();
Serial.println("Trying WiFi reconnect...");
WiFi.reconnect();
}
}
}
這就是非常典型的 IoT 網路恢復設計。
十八、實作:ESP32 Wi-Fi 掃描器 + 網路狀態顯示
接下來把本章所有功能整合在一起。
功能包括:
- ESP32 設定為 STA Mode
- 掃描附近 Wi-Fi
- 顯示 SSID
- 顯示 RSSI
- 顯示 Wi-Fi Channel
- 連接指定 SSID
- 取得 DHCP IP
- 顯示 MAC Address
- 顯示目前 Wi-Fi RSSI
- 每 5 秒顯示一次 Network Status
- Wi-Fi 中斷後自動重連
- 避免程式因 Wi-Fi 故障永久卡死
完整程式
/*
* 第 11 章
* ESP32 Wi-Fi 掃描器 + 網路狀態顯示
*
* 功能:
* 1. 掃描附近 Wi-Fi
* 2. 顯示 SSID / RSSI / Channel
* 3. 連接指定 Wi-Fi
* 4. 顯示 IP / MAC / RSSI
* 5. 持續監控 Wi-Fi 狀態
* 6. Wi-Fi 中斷自動重連
*/
#include <WiFi.h>
// =====================================================
// Wi-Fi 設定
// =====================================================
const char* WIFI_SSID = "YOUR_SSID";
const char* WIFI_PASSWORD = "YOUR_PASSWORD";
// =====================================================
// 時間設定
// =====================================================
unsigned long lastStatusTime = 0;
unsigned long lastReconnectTime = 0;
const unsigned long STATUS_INTERVAL = 5000;
const unsigned long RECONNECT_INTERVAL = 10000;
// =====================================================
// Wi-Fi 狀態文字
// =====================================================
String getWiFiStatusText() {
switch (WiFi.status()) {
case WL_CONNECTED:
return "CONNECTED";
case WL_NO_SSID_AVAIL:
return "SSID NOT FOUND";
case WL_CONNECT_FAILED:
return "CONNECT FAILED";
case WL_CONNECTION_LOST:
return "CONNECTION LOST";
case WL_DISCONNECTED:
return "DISCONNECTED";
case WL_IDLE_STATUS:
return "IDLE";
default:
return "UNKNOWN";
}
}
// =====================================================
// RSSI 品質判斷
// =====================================================
String getRSSIQuality(int32_t rssi) {
if (rssi >= -50)
return "Excellent";
else if (rssi >= -60)
return "Very Good";
else if (rssi >= -67)
return "Good";
else if (rssi >= -70)
return "Fair";
else if (rssi >= -80)
return "Weak";
else
return "Very Weak";
}
// =====================================================
// 掃描附近 Wi-Fi
// =====================================================
void scanWiFi() {
Serial.println();
Serial.println("========================================");
Serial.println(" ESP32 Wi-Fi Scanner");
Serial.println("========================================");
Serial.println("Scanning Wi-Fi networks...");
int networkCount = WiFi.scanNetworks();
if (networkCount <= 0) {
Serial.println("No Wi-Fi networks found.");
}
else {
Serial.print("Networks found: ");
Serial.println(networkCount);
Serial.println();
Serial.println("No | SSID | RSSI | Channel");
Serial.println("----------------------------------------");
for (int i = 0; i < networkCount; i++) {
Serial.print(i + 1);
Serial.print(" | ");
Serial.print(WiFi.SSID(i));
Serial.print(" | ");
Serial.print(WiFi.RSSI(i));
Serial.print(" dBm | CH ");
Serial.println(WiFi.channel(i));
delay(10);
}
}
WiFi.scanDelete();
Serial.println("========================================");
}
// =====================================================
// 連接 Wi-Fi
// =====================================================
void connectWiFi() {
Serial.println();
Serial.println("Connecting to Wi-Fi...");
Serial.print("SSID: ");
Serial.println(WIFI_SSID);
WiFi.mode(WIFI_STA);
WiFi.setAutoReconnect(true);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
unsigned long startTime = millis();
while (WiFi.status() != WL_CONNECTED &&
millis() - startTime < 15000) {
delay(500);
Serial.print(".");
}
Serial.println();
if (WiFi.status() == WL_CONNECTED) {
Serial.println();
Serial.println("*** Wi-Fi Connected ***");
printNetworkInfo();
}
else {
Serial.println();
Serial.println("*** Wi-Fi Connection Failed ***");
Serial.println("Program will continue and retry later.");
}
}
// =====================================================
// 顯示網路資料
// =====================================================
void printNetworkInfo() {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("Wi-Fi is not connected.");
return;
}
Serial.println();
Serial.println("========================================");
Serial.println(" Network Information");
Serial.println("========================================");
Serial.print("SSID : ");
Serial.println(WiFi.SSID());
Serial.print("IP Address : ");
Serial.println(WiFi.localIP());
Serial.print("MAC Address: ");
Serial.println(WiFi.macAddress());
int32_t rssi = WiFi.RSSI();
Serial.print("RSSI : ");
Serial.print(rssi);
Serial.println(" dBm");
Serial.print("Signal : ");
Serial.println(getRSSIQuality(rssi));
Serial.print("Status : ");
Serial.println(getWiFiStatusText());
Serial.println("========================================");
}
// =====================================================
// Setup
// =====================================================
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println();
Serial.println("ESP32 Wi-Fi Scanner + Network Monitor");
Serial.println();
// 設為 STA
WiFi.mode(WIFI_STA);
// 先掃描附近 Wi-Fi
scanWiFi();
// 再連接指定 Wi-Fi
connectWiFi();
}
// =====================================================
// Loop
// =====================================================
void loop() {
// -------------------------------------------------
// Wi-Fi 已連線
// -------------------------------------------------
if (WiFi.status() == WL_CONNECTED) {
if (millis() - lastStatusTime >= STATUS_INTERVAL) {
lastStatusTime = millis();
printNetworkInfo();
}
}
// -------------------------------------------------
// Wi-Fi 已斷線
// -------------------------------------------------
else {
if (millis() - lastReconnectTime >= RECONNECT_INTERVAL) {
lastReconnectTime = millis();
Serial.println();
Serial.print("Wi-Fi Status: ");
Serial.println(getWiFiStatusText());
Serial.println("Trying to reconnect...");
WiFi.reconnect();
}
}
}
十九、修改自己的 SSID 與 Password
上傳程式之前請修改:
const char* WIFI_SSID = "YOUR_SSID";
改成自己的 Wi-Fi,例如:
const char* WIFI_SSID = "WCST_WIFI";
Password:
const char* WIFI_PASSWORD = "YOUR_PASSWORD";
例如:
const char* WIFI_PASSWORD = "12345678";
二十、Arduino IDE 設定
以一般 ESP32-WROOM-32 / ESP32 Dev Module 為例:
Tools
→ Board
→ ESP32 Arduino
→ ESP32 Dev Module
再選擇正確:
COM Port
Serial Monitor Baud Rate 設定:
115200
因為程式使用:
Serial.begin(115200);
二十一、程式執行結果
正常啟動後可能看到:
ESP32 Wi-Fi Scanner + Network Monitor
========================================
ESP32 Wi-Fi Scanner
========================================
Scanning Wi-Fi networks...
Networks found: 5
No | SSID | RSSI | Channel
----------------------------------------
1 | WCST_WIFI | -42 dBm | CH 6
2 | ASUS_HOME | -55 dBm | CH 11
3 | TP-Link | -64 dBm | CH 1
4 | Guest | -72 dBm | CH 6
5 | iPhone | -83 dBm | CH 11
========================================
Connecting to Wi-Fi...
SSID: WCST_WIFI
......
*** Wi-Fi Connected ***
========================================
Network Information
========================================
SSID : WCST_WIFI
IP Address : 192.168.1.105
MAC Address: 24:6F:28:12:34:56
RSSI : -43 dBm
Signal : Excellent
Status : CONNECTED
========================================
之後每:
5 秒
更新一次 Wi-Fi 狀態。
二十二、測試 Wi-Fi 自動重連
這是一個很值得實際操作的實驗。
- ESP32 正常連接 Router。;應看到:;Status : CONNECTED
- 將 Router Wi-Fi 暫時關閉。;ESP32 將變成:;Wi-Fi Status: CONNECTION LOST Trying to reconnect...;或:;Wi-Fi Status: DISCONNECTED
- 重新開啟 Wi-Fi Router。;ESP32 不需要 Reset。;Auto Reconnect 與程式中的重試機制會嘗試重新恢復連線。;這正是實際 IoT 裝置非常重要的:;Fault Recovery / Connection Recovery;能力。
二十三、Wi-Fi Scan、RSSI 與 IoT 有什麼實際用途?
很多人第一次看到:
WiFi.scanNetworks();
會認為只是示範程式。
其實 WiFi Scan 在正式產品上非常實用。
應用一:Wi-Fi 設定介面
ESP32 第一次開機時:
掃描附近 AP
↓
列出 SSID
↓
使用者選 Wi-Fi
↓
輸入 Password
↓
ESP32 儲存設定
↓
自動連線
很多 IoT 裝置第一次設定網路就是使用類似方式。
應用二:Wi-Fi 訊號品質監測
例如:
int rssi = WiFi.RSSI();
若:
RSSI < -75 dBm
可以顯示:
Wi-Fi Signal Weak
甚至透過 LCD / OLED 顯示訊號。
應用三:IoT 設備安裝測試
ESP32 放在:
- 工廠
- 倉庫
- 溫室
- 機房
- 屋頂
- 戶外控制箱
時,可以先測:
RSSI
確認 Wi-Fi 訊號是否足夠。
應用四:選擇較好的 Access Point
大型環境可能有:
AP-1
AP-2
AP-3
利用 Scan 搭配 RSSI,就能判斷哪個 Access Point 訊號最好。
未來還可以進一步使用:
WiFiMulti
管理多組 AP。
Arduino ESP32 官方 Wi-Fi API 也提供 WiFiMulti,可以預先加入多組 Access Point,讓 ESP32 在 Station 模式下管理多個候選 Wi-Fi。
二十四、ESP32 WiFi 常見問題
Q1:ESP32 一直顯示 Connecting WiFi 怎麼辦?
先檢查:
SSID
Password
是否正確。
另外確認 ESP32 與 Router 的頻段相容。
Q2:Wi-Fi 找得到但連不上?
可能包括:
- Password 錯誤
- AP Security 設定
- Router 黑名單
- MAC Filter
- DHCP 問題
- Wi-Fi 訊號太弱
- Router 同時連線數過多
可以先執行:
WiFi.scanNetworks();
確認 ESP32 是否能看到該 SSID。
Q3:ESP32 IP 每次都不一樣?
因為一般使用:
DHCP
所以 Router 可能每次分配不同 IP。
解決方式可以使用:
方法一
Router:
DHCP Reservation
利用 ESP32 MAC Address 固定 IP。
方法二
ESP32 使用:
WiFi.config()
設定 Static IP。
一般家庭或企業 IoT 專案,我比較建議:
由 Router 做 DHCP Reservation。
管理會比每一台 ESP32 都寫死 Static IP 更方便。
二十五、ESP32 WiFi 常用指令整理
| 功能 | 指令 |
|---|---|
| 引入 Wi-Fi | #include <WiFi.h> |
| STA Mode | WiFi.mode(WIFI_STA) |
| 連接 Wi-Fi | WiFi.begin(ssid,password) |
| Wi-Fi 狀態 | WiFi.status() |
| 是否連線 | WL_CONNECTED |
| IP Address | WiFi.localIP() |
| SSID | WiFi.SSID() |
| RSSI | WiFi.RSSI() |
| MAC Address | WiFi.macAddress() |
| Scan | WiFi.scanNetworks() |
| Scan SSID | WiFi.SSID(i) |
| Scan RSSI | WiFi.RSSI(i) |
| Channel | WiFi.channel(i) |
| 清除掃描資料 | WiFi.scanDelete() |
| 自動重連 | WiFi.setAutoReconnect(true) |
| 手動重連 | WiFi.reconnect() |
| 斷開連線 | WiFi.disconnect() |
二十六、ESP32 與 Arduino UNO 的網路能力差異
這也是 ESP32 相對 Arduino UNO R3 最大的優勢之一。
| 功能 | Arduino UNO R3 | ESP32 |
|---|---|---|
| GPIO | ✓ | ✓ |
| ADC | ✓ | ✓ |
| PWM | ✓ | ✓ |
| UART | ✓ | ✓ |
| SPI | ✓ | ✓ |
| I²C | ✓ | ✓ |
| Wi-Fi | × | ✓ |
| Bluetooth | × | ✓ |
| Web Server | 需網路模組 | ✓ |
| IoT | 需額外硬體 | ✓ |
Arduino UNO 若要上網,通常需要:
UNO
+
ESP8266
或:
UNO
+
Ethernet Shield
ESP32 則直接具備無線網路能力。
因此 ESP32 特別適合:
Sensor
↓
ESP32
↓ Wi-Fi
Router
↓
Internet
↓
Cloud / Server / App
二十七、ESP32 WiFi 的完整學習路線
本章可以視為 ESP32 IoT 教材的真正起點。
目前我們已經完成:
ESP32
│
├── GPIO
├── Digital Input
├── ADC
├── PWM
├── Touch
├── I²C
├── SPI
├── UART
│
└── Wi-Fi ← 本章
接下來就可以開始:
Wi-Fi
↓
TCP/IP
↓
HTTP
↓
Web Server
↓
REST API
↓
MQTT
↓
Cloud
↓
完整 IoT 系統
從這裡開始,ESP32 已經不再只是一塊「控制 LED 與感測器的開發板」。
它開始成為真正的:
Networked Embedded System
也就是:
具備網路能力的嵌入式系統。
二十八、本章實作架構
本章完成的:
ESP32 Wi-Fi 掃描器 + 網路狀態顯示
整體流程如下:
ESP32 開機
│
▼
WiFi.mode(WIFI_STA)
│
▼
掃描附近 Wi-Fi
│
├── SSID
├── RSSI
└── Channel
│
▼
WiFi.begin()
│
▼
連接 Router
│
▼
DHCP
│
▼
取得 IP Address
│
├── SSID
├── IP
├── MAC
└── RSSI
│
▼
每 5 秒檢查 Wi-Fi
│
├── Connected ──→ 顯示網路狀態
│
└── Disconnected
│
▼
WiFi.reconnect()
│
▼
恢復連線
這個程式架構後面可以直接沿用在:
- ESP32 Web Server
- ESP32 MQTT
- ESP32 HTTP Client
- ESP32 Firebase
- ESP32 ThingSpeak
- ESP32 Home Assistant
- ESP32 IoT Sensor
- ESP32 遠端控制
等專案中。
二十九、本章重點整理
完成本章後,應該掌握以下觀念:
1. ESP32 WiFi 函式庫
#include <WiFi.h>
2. Station Mode
WiFi.mode(WIFI_STA);
ESP32 連接現有 Router。
3. SSID 與 Password
WiFi.begin(ssid, password);
4. 判斷連線
WiFi.status() == WL_CONNECTED
5. DHCP
一般情況由 Router 自動分配 IP。
6. IP Address
WiFi.localIP();
7. MAC Address
WiFi.macAddress();
8. RSSI
WiFi.RSSI();
數字越接近 0,通常代表訊號越強。
9. WiFi Scan
WiFi.scanNetworks();
搜尋附近 Access Point。
10. Wi-Fi 自動重連
WiFi.setAutoReconnect(true);
並搭配:
WiFi.reconnect();
提高 IoT 系統長時間運行的可靠性。
三十、結語
ESP32 最重要的價值,不只是 GPIO 比 Arduino UNO 多、CPU 比 Arduino UNO 快,而是它把:
微控制器
+
Wi-Fi
+
TCP/IP
+
Bluetooth
整合在同一顆 MCU 中。
因此當我們學會:
ESP32 WiFi、ESP32 WiFi Scan、SSID、DHCP、IP Address、RSSI、MAC Address 與 Wi-Fi 自動重連
之後,就已經完成進入 IoT 世界最重要的基礎建設。
本章的 ESP32 Wi-Fi 掃描器 + 網路狀態顯示器 不只是練習程式。
它實際建立了後面所有網路專案都會使用的共同架構:
搜尋網路
→ 連接網路
→ 取得 IP
→ 判斷網路品質
→ 持續監控
→ 斷線恢復
下一階段就可以在這套 Wi-Fi 基礎之上建立:
ESP32 Web Server
讓手機或電腦直接透過瀏覽器存取 ESP32,正式進入 ESP32 網頁控制與 IoT 應用。