3、AP模式基础:SoftAP配置、热点参数设置、客户端管理
好,咱们今天聊聊ESP32的AP模式。说白了,就是让ESP32自己当个小路由器。
很多初学者一上来就只玩Station模式,觉得连上家里的Wi-Fi才叫联网。但实际项目中,AP模式用得可不少。我最早做智能插座时,就靠AP模式让手机直连设备完成配网。那会儿踩了不少坑,今天一并讲清楚。
核心要点:ESP32的SoftAP模式,本质是让芯片模拟一个简易的Wi-Fi热点。它不依赖外部路由器,设备之间可以直接通信。
3.1 SoftAP初始化流程
先看最基础的代码骨架。我个人习惯把初始化拆成三步:
- 创建并配置热点参数——设置SSID、密码、信道等
- 启动SoftAP——让热点真正生效
- 启动DHCP服务器——给连接的客户端自动分配IP
嗯,这里要注意:很多人忘了第三步,结果手机连上热点却拿不到IP,死活上不了网。
#include <WiFi.h>
void setup() {
Serial.begin(115200);
// 第一步:配置热点参数
const char *ssid = "ESP32_AP_Demo";
const char *password = "12345678";
// 第二步:启动SoftAP
WiFi.softAP(ssid, password);
// 第三步:启动DHCP服务器(默认自动启动,但建议显式调用)
WiFi.softAPConfig(
IPAddress(192, 168, 4, 1), // 网关IP
IPAddress(192, 168, 4, 1), // 网关IP(通常与本地IP一致)
IPAddress(255, 255, 255, 0) // 子网掩码
);
Serial.println("SoftAP started");
Serial.print("IP address: ");
Serial.println(WiFi.softAPIP());
}
void loop() {
// 主循环
}
这段代码跑起来,你用手机搜Wi-Fi,就能看到一个叫"ESP32_AP_Demo"的热点。密码是12345678。
小技巧:如果你不调用softAPConfig(),ESP32默认使用192.168.4.1作为网关。这个地址在业内几乎成了SoftAP的"标准IP",很多配网App都硬编码了这个地址。我建议你保持默认,除非有特殊需求。
3.2 热点参数详解
WiFi.softAP()这个函数,其实有四个参数。很多人只用前两个,后面两个藏着好东西。
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| ssid | const char* | 热点名称,最长32字节 | 无 |
| password | const char* | 密码,至少8位;传空字符串表示开放热点 | 空(开放) |
| channel | uint8_t | Wi-Fi信道,范围1~13 | 1 |
| ssid_hidden | uint8_t | 0=广播SSID,1=隐藏SSID | 0 |
| max_connection | uint8_t | 最大连接客户端数,范围1~10 | 4 |
举个例子,你想做一个隐藏SSID、只允许2个设备连接的热点:
WiFi.softAP("MyHiddenAP", "secret123", 6, 1, 2);
信道这块我多说两句。ESP32默认用信道1,但如果你周围Wi-Fi环境很拥挤,信道1可能干扰很大。我曾在办公楼里调试,手机连上热点后ping值动不动就上千毫秒。后来把信道改成11,瞬间稳定了。你想想看,信道就像高速公路的车道,选个不堵的很重要。
注意:ESP32的SoftAP模式不支持WPA3,只支持WPA2-PSK。如果你设置密码,长度必须≥8位。另外,开放热点(不设密码)在某些国家可能违反法规,商用项目要留意。
3.3 客户端管理
热点开起来了,怎么知道谁连上来了?ESP32提供了几个API,我常用的就三个:
WiFi.softAPgetStationNum()——获取当前连接的客户端数量WiFi.softAPIP()——获取AP本身的IP地址WiFi.softAPBroadcastIP()——获取广播地址
但说实话,光知道数量不够。有时候你需要知道每个客户端的MAC地址,甚至踢掉某个设备。这时候就得用底层API了。
#include <WiFi.h>
#include <esp_wifi.h>
void printConnectedClients() {
wifi_sta_list_t wifi_sta_list;
tcpip_adapter_sta_list_t adapter_sta_list;
// 获取连接的客户端列表
esp_wifi_ap_get_sta_list(&wifi_sta_list);
tcpip_adapter_get_sta_list(&wifi_sta_list, &adapter_sta_list);
Serial.printf("Connected clients: %d\n", adapter_sta_list.num);
for (int i = 0; i < adapter_sta_list.num; i++) {
tcpip_adapter_sta_info_t station = adapter_sta_list.sta[i];
Serial.printf("Client %d: MAC=%02x:%02x:%02x:%02x:%02x:%02x, IP=%s\n",
i,
station.mac[0], station.mac[1], station.mac[2],
station.mac[3], station.mac[4], station.mac[5],
ip4addr_ntoa(&(station.ip)));
}
}
这段代码能打印出每个客户端的MAC地址和IP。我在做智能家居网关时,就用这个功能来识别哪些设备是自家的,哪些是蹭网的。
实战经验:我曾经遇到一个坑——客户端断开后,softAPgetStationNum()不会立即更新。原因是Wi-Fi驱动层有超时机制,默认300秒后才清理已断开的客户端记录。如果你需要实时检测,建议在loop()里每隔几秒轮询一次,或者注册Wi-Fi事件回调。
3.4 事件回调:优雅地处理连接与断开
轮询太low了,咱们用事件驱动。ESP32的Wi-Fi库支持注册事件回调,连接和断开都能自动通知你。
void WiFiEvent(WiFiEvent_t event) {
switch (event) {
case SYSTEM_EVENT_AP_STACONNECTED:
Serial.println("A client connected");
break;
case SYSTEM_EVENT_AP_STADISCONNECTED:
Serial.println("A client disconnected");
break;
case SYSTEM_EVENT_AP_STAIPASSIGNED:
Serial.println("IP assigned to a client");
break;
default:
break;
}
}
void setup() {
WiFi.onEvent(WiFiEvent);
// ... 其他初始化代码
}
这三个事件够用了。特别是SYSTEM_EVENT_AP_STAIPASSIGNED,它告诉你DHCP已经给客户端分配了IP,这时候才能和客户端正常通信。
3.5 知识结构图
下面这张图总结了SoftAP的核心模块和流程,你一看就明白:
3.6 常见问题与避坑
最后,我把自己踩过的坑整理一下,你遇到了直接对照排查:
| 问题现象 | 可能原因 | 解决办法 |
|---|---|---|
| 手机搜不到热点 | 信道超出手机支持范围(如信道13) | 改用信道1~11 |
| 连接后拿不到IP | DHCP服务器未启动或IP池耗尽 | 显式调用softAPConfig(),或减少max_connection |
| 客户端频繁断开 | 电源供电不足,或信道干扰严重 | 换高质量电源,手动选择空闲信道 |
| 热点名称显示乱码 | SSID包含非ASCII字符 | 只使用英文字母和数字 |
| 连接数超过设定值 | 底层驱动限制,实际可能多连1~2个 | 设置max_connection时留余量 |
曾经踩过的坑:有一次我在产品中同时开启SoftAP和Station模式(即Wi-Fi双模式),结果发现SoftAP的客户端连接数莫名其妙减少。查了两天才发现——ESP32的Wi-Fi硬件资源是共享的,Station模式占用了部分内存和信道资源,导致SoftAP的max_connection实际最大值从10降到了4。所以,如果你要同时用两种模式,记得把max_connection设小一点。
好了,AP模式的基础就这些。你先把代码跑通,然后试着改改参数,看看客户端列表的变化。动手试一遍,比看十遍文档都管用。