3. AP模式配网原理:ESP8266/ESP32创建热点、手机连接热点、建立TCP/UDP通信、传输WiFi凭证

AP模式,说白了就是让设备自己先当个小路由器。

你想想看,一个新买的ESP8266,它不知道家里的WiFi密码,怎么联网?

那就让它先开个热点,你手机连上去,把密码告诉它。这就是AP模式配网的核心思路。

我个人习惯把这个过程拆成四步:建热点 → 等连接 → 开通信 → 传凭证。下面我们一步步拆开看。

核心逻辑一句话:设备先做AP(接入点),手机做STA(站点),通过临时建立的TCP/UDP通道,把目标路由器的SSID和密码交给设备。

AP模式配网核心流程 AP模式配网核心流程 ESP8266/ESP32 创建WiFi热点 (AP) 手机 扫描并连接该热点 建立通信通道 TCP 或 UDP ① 热点广播 ② 连接成功 手机发送凭证 SSID + Password 设备接收凭证 切换STA模式连目标路由 ③ 通道就绪 ④ 数据传输 💡 关键点: 整个过程中,设备先做AP,手机做STA。凭证传完后,设备关闭AP,切换为STA模式去连接目标路由器。

3.1 设备创建热点

ESP8266和ESP32的WiFi库都提供了现成的API。你只需要设置SSID和密码,调用一个函数就行。

嗯,这里要注意:热点名最好带个设备标识,比如 SmartConfig_XXXX,方便用户在手机WiFi列表里找到它。

// ESP8266 / ESP32 创建AP模式热点
#include <WiFi.h>

const char *ap_ssid = "ESP_Config_001";
const char *ap_password = "12345678";

void setup() {
  Serial.begin(115200);
  
  // 设置为AP模式
  WiFi.mode(WIFI_AP);
  
  // 启动热点
  WiFi.softAP(ap_ssid, ap_password);
  
  Serial.print("AP IP地址: ");
  Serial.println(WiFi.softAPIP());  // 默认 192.168.4.1
}

void loop() {
  // 等待手机连接...
}

我的经验:热点密码不要设得太复杂,8位纯数字就行。我曾经见过有人设了个32位随机密码,结果自己手机连的时候输错了三次……配网失败。

3.2 手机连接热点

设备热点启动后,手机打开WiFi列表,找到你设的那个SSID,点一下,输入密码,连接。

这一步看起来简单,但有个坑:手机连接热点后,会失去原有的移动网络或家庭WiFi连接。所以配网App必须提前把数据准备好,连上后立刻开始通信。

对比项 手机连接前 手机连接热点后
网络状态 4G/5G 或 家庭WiFi 仅连接设备热点
可访问目标 互联网 仅设备IP (192.168.4.1)
配网App状态 可后台运行 必须前台运行并主动通信

⚠️ 避坑:Android和iOS在连接热点后,可能会弹出「是否保持连接?」的提示,或者自动检测到该热点无互联网而断开。我曾经在iOS项目里遇到过,手机连上热点3秒后自动切回4G,配网直接中断。解决方案是在App里做网络状态监听,强制绑定热点连接。

3.3 建立TCP/UDP通信

手机连上热点后,设备和手机就在同一个局域网了。设备默认IP是 192.168.4.1,手机被分配一个IP,比如 192.168.4.2。

接下来要建立通信通道。两种选择:TCP 或 UDP。

  • TCP:面向连接,可靠,适合传WiFi凭证这种关键数据。我一般用TCP,省心。
  • UDP:无连接,速度快,但可能丢包。适合广播场景,比如设备发心跳包。

我个人习惯用TCP。为什么?因为WiFi凭证一旦传错一个字符,设备就连不上目标路由器,你还得重新配网。TCP有重传机制,靠谱。

// ESP8266/ESP32 创建TCP服务器,等待手机连接
#include <WiFi.h>

WiFiServer server(8888);  // 监听端口8888

void setup() {
  // ... 省略AP启动代码 ...
  
  server.begin();  // 启动TCP服务器
  Serial.println("TCP服务器已启动,等待手机连接...");
}

void loop() {
  WiFiClient client = server.available();  // 检查是否有手机连接
  if (client) {
    Serial.println("手机已连接");
    while (client.connected()) {
      if (client.available()) {
        String data = client.readStringUntil('\n');
        Serial.print("收到数据: ");
        Serial.println(data);
        // 处理WiFi凭证...
      }
    }
    client.stop();
  }
}

端口选择建议:避免使用知名端口(如80、443),选一个不常用的端口,比如8888、9999。我曾经见过有人用80端口,结果手机浏览器自动发HTTP请求,把配网数据搞乱了。

3.4 传输WiFi凭证

通信通道建立后,手机把目标路由器的SSID和密码发过来。数据格式怎么定?

我推荐用 JSON 或者简单的 自定义协议。JSON可读性好,调试方便;自定义协议更省内存。

举个例子,用JSON格式:

// 手机发送的数据格式(JSON)
{
  "ssid": "MyHomeWiFi",
  "password": "MyPassword123"
}

// ESP8266/ESP32 解析代码片段
String parseWiFiCredentials(String jsonData) {
  // 简单解析,实际项目建议用ArduinoJson库
  int ssidStart = jsonData.indexOf("\"ssid\":\"") + 8;
  int ssidEnd = jsonData.indexOf("\"", ssidStart);
  String ssid = jsonData.substring(ssidStart, ssidEnd);
  
  int pwdStart = jsonData.indexOf("\"password\":\"") + 12;
  int pwdEnd = jsonData.indexOf("\"", pwdStart);
  String password = jsonData.substring(pwdStart, pwdEnd);
  
  // 保存凭证并尝试连接目标路由器
  WiFi.begin(ssid.c_str(), password.c_str());
  return ssid + " / " + password;
}

我的经验:设备收到凭证后,先不要急着关热点。我习惯的做法是:先尝试连接目标路由器,如果连上了,再关闭AP模式;如果连不上,保持热点开启,让手机重发一次。这样用户体验好很多。

3.5 完整配网流程总结

把上面几步串起来,AP模式配网的完整流程就是:

  1. 设备上电 → 检测到未保存WiFi凭证 → 自动进入AP模式
  2. 创建热点 → 设置SSID和密码 → 启动TCP服务器
  3. 手机连接热点 → 打开配网App → 连接到设备热点
  4. 建立TCP连接 → 手机向设备IP:端口发起连接
  5. 传输凭证 → 手机发送SSID+密码 → 设备解析并保存
  6. 设备切换模式 → 关闭AP → 以STA模式连接目标路由器
  7. 反馈结果 → 连接成功则配网完成;失败则重新开启AP等待

⚠️ 重要提醒:设备切换模式时,WiFi库会重新初始化,这个过程大约需要1-3秒。期间不要断电,否则凭证可能没保存成功。我建议在写入EEPROM或Flash后加一个LED指示,让用户知道「正在保存,请勿断电」。

AP模式配网,说白了就是「设备先当主人,再当客人」。它把配网的主动权交给了用户,兼容性最好——几乎所有的手机都支持连接WiFi热点。缺点就是操作步骤多了一步,但胜在稳定可靠。

我个人做项目时,如果产品面向普通消费者,我首选AP模式。虽然开发起来多写几行代码,但用户配网成功率确实高。