ESP32 初次开机自动配置 WiFi

📅 发布时间:2026/7/5 17:16:18 👁️ 浏览次数:
ESP32 初次开机自动配置 WiFi
1. 简介很多物联网设备需要连接家庭 WiFi但无法预知用户的网络名称和密码。本教程将教你如何编写一个 ESP32 程序实现首次开机自动进入配网模式创建一个名为ESP32_Config的热点用户通过手机/电脑连接后打开网页输入 WiFi 信息。保存信息将 WiFi 信息保存到 ESP32 的 NVS非易失性存储中断电不丢失。后续开机自动读取保存的 WiFi 信息并连接如果连接失败则重新进入配网模式。通过这种方式用户只需配置一次之后设备就能自动联网。2. 准备材料硬件ESP32 开发板、USB 数据线。软件Arduino IDE浏览器用于配置页面。可选LED 验证连接状态ESP32 板载 LED 通常已集成。3. 代码解析以下是完整的代码稍后解释各部分功能#include WiFi.h #include WebServer.h #include DNSServer.h #include Preferences.h // 配置参数 const char* AP_SSID ESP32_Config; // 配置模式下的热点名称 const char* AP_PASSWORD ; // 热点密码空表示开放 const int DNS_PORT 53; // DNS 服务器端口 const int WEB_PORT 80; // Web 服务器端口 const unsigned long CONNECT_TIMEOUT 30000; // WiFi 连接超时时间毫秒 const unsigned long AP_TIMEOUT 300000; // AP 模式超时时间毫秒5分钟超过无配置则重启 // 全局对象 WebServer server(WEB_PORT); DNSServer dnsServer; Preferences preferences; // 标志位是否处于配网模式 bool configMode false; unsigned long apStartTime 0; // 用户 LED 引脚可根据需要修改 const int ledPin 2; // 大多数 ESP32 开发板板载 LED 在 GPIO2 // 读取保存的 WiFi 凭据 bool loadWiFiCredentials(String ssid, String password) { preferences.begin(wifi, false); // 命名空间 wifi读写模式 ssid preferences.getString(ssid, ); password preferences.getString(password, ); preferences.end(); return (ssid.length() 0); } // 保存 WiFi 凭据 void saveWiFiCredentials(const String ssid, const String password) { preferences.begin(wifi, false); preferences.putString(ssid, ssid); preferences.putString(password, password); preferences.end(); } // 尝试连接 WiFi bool connectToWiFi(const String ssid, const String password) { WiFi.mode(WIFI_STA); WiFi.begin(ssid.c_str(), password.c_str()); Serial.print(Connecting to WiFi: ); Serial.println(ssid); unsigned long startAttempt millis(); while (WiFi.status() ! WL_CONNECTED millis() - startAttempt CONNECT_TIMEOUT) { delay(500); Serial.print(.); } Serial.println(); if (WiFi.status() WL_CONNECTED) { Serial.println(Connected!); Serial.print(IP address: ); Serial.println(WiFi.localIP()); return true; } else { Serial.println(Connection failed.); return false; } } // 启动 AP 模式并开启 DNS Web 服务器 void startConfigMode() { configMode true; apStartTime millis(); WiFi.mode(WIFI_AP); WiFi.softAP(AP_SSID, AP_PASSWORD); IPAddress apIP WiFi.softAPIP(); Serial.println(AP mode started); Serial.print(AP IP address: ); Serial.println(apIP); // 启动 DNS 服务器将所有域名请求指向 AP 的 IP dnsServer.start(DNS_PORT, *, apIP); // 配置 Web 服务器路由 server.on(/, handleRoot); server.on(/configure, HTTP_POST, handleConfigure); server.onNotFound(handleNotFound); server.begin(); Serial.println(HTTP server started); } // 处理根路径显示配置页面 void handleRoot() { String html !DOCTYPE htmlhtml; html headmeta name\viewport\ content\widthdevice-width, initial-scale1\; html titleWiFi Config/title/headbody; html h2ESP32 WiFi Configuration/h2; html form method\POST\ action\/configure\; html SSID:brinput type\text\ name\ssid\ placeholder\WiFi SSID\br; html Password:brinput type\password\ name\password\ placeholder\Password\brbr; html input type\submit\ value\Save and Restart\; html /form/body/html; server.send(200, text/html, html); } // 处理配置表单提交 void handleConfigure() { if (server.hasArg(ssid) server.hasArg(password)) { String ssid server.arg(ssid); String password server.arg(password); if (ssid.length() 0) { saveWiFiCredentials(ssid, password); server.send(200, text/html, h2Configuration saved. Restarting.../h2); delay(1000); ESP.restart(); } else { server.send(400, text/html, h2SSID cannot be empty/h2); } } else { server.send(400, text/html, h2Missing parameters/h2); } } // 处理未找到的路径用于 Android/iPhone 的浏览器探测 void handleNotFound() { server.send(204, text/plain, ); // 204 No Content 让手机不弹出错误 } void setup() { Serial.begin(115200); delay(1000); Serial.println(\nESP32 WiFi Config Example); pinMode(ledPin, OUTPUT); digitalWrite(ledPin, LOW); // 尝试加载已保存的 WiFi 信息 String savedSSID, savedPassword; bool hasCredentials loadWiFiCredentials(savedSSID, savedPassword); if (hasCredentials) { Serial.println(Found saved WiFi credentials.); if (connectToWiFi(savedSSID, savedPassword)) { // 连接成功执行用户主程序此处为 LED 闪烁示例 Serial.println(Starting user program...); // 在主循环中执行用户逻辑见 loop return; // 直接退出 setup进入 loop } else { Serial.println(Saved WiFi connection failed.); } } else { Serial.println(No saved WiFi credentials.); } // 没有凭据或连接失败启动配网模式 startConfigMode(); } void loop() { if (configMode) { // 处理 DNS 和 Web 请求 dnsServer.processNextRequest(); server.handleClient(); // 超时检查若 AP 模式运行超过指定时间且无配置则重启尝试重新连接 if (millis() - apStartTime AP_TIMEOUT) { Serial.println(AP timeout, restarting...); ESP.restart(); } } else { // 正常模式用户程序 // 示例LED 闪烁表示已连接 WiFi digitalWrite(ledPin, !digitalRead(ledPin)); delay(1000); Serial.println(Wifi连接成功进入用户程序.); } }关键代码解释头文件与全局变量WiFi.h提供 WiFi 连接功能。WebServer.h用于建立 HTTP 服务器处理配置页面。DNSServer.h实现 DNS 劫持使所有域名请求指向 ESP32 的 IP。Preferences.h用于在 NVS 中保存 WiFi 信息类似键值对存储。参数配置AP_SSID和AP_PASSWORD配置模式下的热点名称和密码留空表示开放。CONNECT_TIMEOUT连接 WiFi 的超时时间。AP_TIMEOUTAP 模式最长运行时间避免一直占用。Preferences 存储preferences.begin(wifi, false)打开命名空间wifi可自定义第二个参数false表示读写。putString/getString存储和读取字符串。连接逻辑setup()中先尝试读取保存的 WiFi如果能读到则尝试连接。连接成功则进入loop()的用户程序失败则启动 AP 模式。AP 模式下启动 DNS 和 Web 服务器用户通过浏览器提交配置后保存并重启。DNS 劫持dnsServer.start(DNS_PORT, *, apIP)将所有域名请求解析到 ESP32 的 AP IP192.168.4.1。这样用户连接热点后无论访问什么网址如www.baidu.com都会跳转到 ESP32 的配置页面提升体验。超时重启AP 模式下记录开始时间apStartTime若超过AP_TIMEOUT仍未收到配置则自动重启再次尝试连接已保存的 WiFi如果有。用户程序占位在loop()的else分支中写你自己的代码示例中是一个 LED 闪烁代表 WiFi 已连接。注意不同 ESP32 开发板的板载 LED 可能连接在不同 GPIO常见的是 GPIO2 或 GPIO5。若不确定可查阅开发板原理图或先测试。6. 操作步骤6.1 上传程序用 USB 线连接 ESP32 和电脑。在 Arduino IDE 中选择正确的开发板如ESP32 Dev Module和端口如COM3。将上述代码复制到 IDE 中点击上传按钮→。等待编译和上传完成打开串口监视器波特率 115200观察输出。6.2 首次配置如果 ESP32 没有保存过 WiFi 信息它会在串口打印未找到保存的 WiFi 凭据。并启动 AP 模式创建名为ESP32_Config的开放热点。用手机或电脑连接该热点无需密码。连接成功后通常会自动弹出配置页面若未弹出使用浏览器访问http://192.168.4.1。在页面中输入你家 WiFi 的 SSID 和密码点击“保存并重启”。保存成功界面如下:ESP32 保存信息后自动重启尝试连接你输入的 WiFi。6.3 正常使用连接成功后串口会显示获得的 IP 地址LED 开始每秒闪烁一次。且串口输出信息如下:此后每次开机ESP32 都会自动连接上次保存的 WiFi无需再次配置。如果 WiFi 连接失败如密码更改、路由器关闭程序会在超时后重新进入 AP 模式等待新配置。7. 常见问题与解决Q1: 连接 ESP32 热点后没有自动弹出配置页面怎么办确保手机/电脑关闭了移动数据并且已经连接到ESP32_Config热点。手动在浏览器输入http://192.168.4.1访问。Q2: 配置页面提交后ESP32 没有重启或连接不上检查输入的 WiFi 密码是否正确。查看串口监视器输出如果保存成功会显示配置已保存设备即将重启...然后重启。如果 WiFi 名称或密码错误重启后仍会进入 AP 模式可再次配置。Q3: 如何修改配置热点的名称或密码修改代码开头的AP_SSID和AP_PASSWORD即可。若希望 AP 模式有密码可设置AP_PASSWORD为字符串如12345678注意 WiFi 密码至少 8 位。Q4: 如何清除保存的 WiFi 信息可以通过串口发送命令需自己扩展或重新上传一个空白程序来清除 NVS。快速方法在 Arduino IDE 中选择 工具 → ESP32 Sketch Data Upload 下方的 Erase Flash擦除整个 Flash 后再上传程序。Q5: 我想在用户程序中添加更多功能比如读取传感器、控制继电器应该怎么改在loop()的else分支中即configMode false时编写你的主逻辑即可。注意不要使用delay()过长以免影响 WiFi 维持连接。建议用millis()定时或改用多任务FreeRTOS。8. 扩展思考多网络支持可以修改程序保存多个 WiFi 信息按优先级尝试连接。Web 页面美化可添加 CSS 样式使配置界面更美观。安全考虑如果 AP 模式需要密码务必设置复杂密码防止他人误连。远程配置若需要远程修改 WiFi可配合 MQTT 或 BLE 实现。