- 物联网
- 嵌入式
【免费下载链接】WiFiManager
ESP8266 WiFi Connection manager with web captive portal
导读
WiFiManager 是一个面向 ESP8266 / ESP32(Espressif ESPx)Arduino 平台的 WiFi 连接管理库,核心能力是:设备开机自动尝试连接已保存的网络,失败时自动切换为 SoftAP(Access Point)模式并启动带Captive Portal(强制门户)的 Web 配置界面,用户用手机或电脑连上该热点即可在浏览器中完成 WiFi 配置。本文以仓库根目录 README.md 为主线,结合 WiFiManager.h、WiFiManager.cpp 源码与 examples 示例,系统讲解它的工作原理、安装方式、核心 API、配置技巧与故障排查方法,读完后你将能够独立完成从"零配置配网"到"自定义参数采集、静态 IP、主题定制"的完整实战方案。
⚠️ 提示:README 开头明确标注 "This Documentation is out of date, see notes below",部分早期 API 名称(如
setTimeout)已被新 API 取代,本文以当前仓库源码 WiFiManager.h 中的实际声明为准。
工作原理:从 STA 失败到 Captive Portal 的完整链路
自动连接流程
从源码 WiFiManager.cpp 中autoConnect()的实现可以看出,整个工作流程分以下几个阶段:
- 启动即 STA 模式尝试连接:ESP 上电后先以 Station(客户端)模式尝试连接此前保存的 Access Point;
- 连接失败(或无已保存网络)则切换 AP 模式:设备转入 Access Point 模式,默认网关 IP 为
192.168.4.1,并启动 DNS 服务器与 WebServer; - 用户连接热点触发 Captive Portal:使用任何带浏览器且支持 WiFi 的设备(电脑、手机、平板)连接新建的热点,由于配置门户属于Captive Portal(强制门户)类型,设备会弹出"加入网络"之类的提示,或者将任意域名访问重定向到配置门户;
- 扫描并配置:在门户页面中选择扫描到的某个 AP、输入密码、点击保存;
- 重新连接并交还控制权:ESP 尝试连接;成功则把控制权交还给用户应用;失败则重新回到 AP 模式等待再次配置。
从源码 WiFiManager.cpp 可以看到,无参调用autoConnect()时会通过getDefaultAPName()自动生成ESP加 Chip ID 的 AP 名称;WiFiManager.h 中 ESP8266 使用ESP.getChipId(),ESP32 使用(uint32_t)ESP.getEfuseMac()生成。
此外,README 强调:可以选择改变这一默认行为,例如手动启动配置门户(configportal)与 Web 门户(webportal),也可以让它们以非阻塞(non-blocking)模式运行。
Captive Portal 的底层实现
在 WiFiManager.cpp 中可以看到门户的两个关键组件:
setupDNSD():创建DNSServer,把*通配的所有域名请求都重定向到WiFi.softAPIP()(即默认192.168.4.1),这正是"访问任意域名都会被拉回配置页"的机制来源;setupConfigPortal():调用setupHTTPServer()注册/、状态页、更新页等 HTTP 路由并启动 WebServer,同时清空网络扫描缓存,可选的预扫描(_preloadwifiscan)以异步方式预缓存 WiFi 扫描结果以加速页面加载。
快速开始:安装与最小可用代码
Arduino IDE 安装
- 打开 Arduino IDE,选择Sketch → Include Library → Manage Libraries;
- 搜索
WiFiManager; - 点击 Install,然后进入 使用 章节开始编码。
注意:README 说明0.8 及以上版本要求 ESP8266 Arduino core 2.4.0 或更新版本;如果是从 GitHub 检出最新代码,可能还需要同步升级 ESP8266 core 到最新版,因为库会使用一些新增函数。
PlatformIO 安装
推荐在项目根目录的platformio.ini中把WiFiManager加到顶层通用环境的lib_deps:
[env] lib_deps = WiFiManager也可以直接引用仓库地址安装:
[env] lib_deps = https://github.com/tzapu/WiFiManager.git最小示例:autoConnect
在 sketch 中引入头文件并实例化:
#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager WiFi Configuration Magic WiFiManager wifiManager;⚠️ README 特别提醒:如果使用非阻塞模式,
WiFiManager对象必须创建在全局作用域,或者自行妥善管理其生命周期;放在setup()局部变量中会导致非阻塞模式失效。
然后在setup()中调用:
//第一个参数是 AP 名称,第二个参数是 AP 密码 wifiManager.autoConnect("AP-NAME", "AP-PASSWORD");如果只想创建无密码的热点:
wifiManager.autoConnect("AP-NAME");如果想使用由ESP加 Chip ID 自动生成的热点名称:
wifiManager.autoConnect();烧录后启动:ESP 先尝试连接 WiFi,失败则进入 AP 模式;此时连接该热点,用浏览器打开网关 IP(默认192.168.4.1)完成配置并保存,设备会自动重启并连上网络。完整的可运行示例见 examples/Basic/Basic.ino,其中还演示了用返回值res判断是否连接成功,失败时可选ESP.restart()重启。
配置门户的语言切换
配置网站的界面语言在编译期决定,默认是英文(LANG_EN)。在 PlatformIO 中通过build_flags指定:
[env] build_flags = -D LANG_EN当前仓库支持的语言宏如下(见 WiFiManager.h 中字符串头文件的选择逻辑):
LANG_DE LANG_EN LANG_ES LANG_FR LANG_PT LANG_PT_BR对应仓库根目录下的 wm_strings_de.h、wm_strings_en.h、wm_strings_es.h、wm_strings_fr.h、wm_strings_pt.h、[wm_strings_pt_br.h] 语言包,另有 wm_consts_en.h 等常量文件与 strings_en.h。这些字符串头文件同时包含 HTML 模板与界面文案,库的字符串全部被移入 PROGMEM 以节省 RAM。
密码保护配置热点
强烈建议为配置热点设置密码,把密码作为autoConnect的第二个参数传入:
wifiManager.autoConnect("AutoConnectAP", "password")README 提醒:过短的密码行为不可预测,应使用约 8 个字符或更长的密码。WiFi 密码规范为 8~63 个 ASCII 编码字符,取值在十进制 32~126 范围内。这一点在源码 WiFiManager.cpp 的validApPassword()中得到印证:非空密码长度小于 8 或大于 63 时会被判为非法(fail secure),清空密码并返回失败。
回调机制(Callbacks)
进入配置模式回调(setAPCallback)
当设备因 WiFi 连接失败而进入配置模式时,如果需要执行一些操作(比如点亮指示灯、输出提示),在调用autoConnect()之前注册:
wifiManager.setAPCallback(configModeCallback);回调声明与示例(注意回调参数是WiFiManager*指针,可调用getConfigPortalSSID()获取门户热点名称):
void configModeCallback (WiFiManager *myWiFiManager) { Serial.println("Entered config mode"); Serial.println(WiFi.softAPIP()); Serial.println(myWiFiManager->getConfigPortalSSID()); }保存设置回调(setSaveConfigCallback)
当自定义参数已被设置且连接建立成功时,saveConfigCallback会被调用。典型用途是置一个标志位,待 WiFiManager 把控制权交还应用后,再把你关心的额外参数持久化(如写入 SPIFFS 的 JSON)。
⚠️ README 特别说明:如果你希望在 WiFi 连接失败或参数为空时也要保存参数,必须先把setBreakAfterConfig(true)打开,否则saveConfigCallback不会被调用:
//如果设置了此项,即使连接不成功也会在配置完成后退出 void setBreakAfterConfig(boolean shouldBreak);示例:
wifiManager.setSaveConfigCallback(saveConfigCallback);//flag for saving data bool shouldSaveConfig = false; //callback notifying us of the need to save config void saveConfigCallback () { Serial.println("Should save config"); shouldSaveConfig = true; }完整的"自定义参数读写 SPIFFS JSON"示例见 examples/Parameters/SPIFFS/AutoConnectWithFSParameters/AutoConnectWithFSParameters.ino,其中用DynamicJsonDocument解析/config.json,并在shouldSaveConfig为真时把mqtt_server、mqtt_port、api_token写回文件系统。
配置门户超时(Configuration Portal Timeout)
如果不想让 ESP 无限期挂起等待配置(例如断电恢复后设备卡在 AP 模式),可以设置超时:
wifiManager.setConfigPortalTimeout(180);这会让门户在 3 分钟(180 秒)后自动关闭,届时autoConnect()无论结果如何都会返回。之后应检查连接状态,仍未连上就执行需要的兜底策略(有些模块重启重试,有些进入深度睡眠)。源码实现见 WiFiManager.cpp:setConfigPortalTimeout(unsigned long seconds)内部将秒数乘以 1000 存入_configPortalTimeout。
与之相关、常与排错搭配使用的还有setConnectTimeout(seconds)(尝试连接的超时,见 WiFiManager.cpp)和setConnectRetries(numRetries)(自动连接重试次数,默认 1,会被约束在 1~10 之间,见 WiFiManager.cpp)。注意 README 提到旧版setTimeout(seconds)已更名为setConfigPortalTimeout(seconds),当前头文件中setTimeout仅是@deprecated别名(见 WiFiManager.h)。
按需启动配置门户(On Demand Configuration Portal)
如果希望配置门户只在需要时手动启动,而不是连接失败时自动弹出,就不要调用autoConnect()(它会自动完成连接与失败回退),改用startConfigPortal()。两者不要同时使用。
void loop() { // 配置门户是否被请求? if ( digitalRead(TRIGGER_PIN) == LOW ) { WiFiManager wifiManager; wifiManager.startConfigPortal("OnDemandAP"); Serial.println("connected...yeey :)"); } }从源码看,startConfigPortal()的执行链路是(WiFiManager.cpp):_begin()→ 校验 AP 密码 → 必要时关闭 STA →startAP()启动热点 → 触发_apcallback→setupConfigPortal()启动 WebServer →setupDNSD()启动 DNS 重定向 → 进入阻塞循环while(1)等待保存或超时/中止。
更完整的实战版本见 examples/OnDemand/OnDemandConfigPortal/OnDemandConfigPortal.ino:它把TRIGGER_PIN(默认 GPIO0,内部上拉)拉低时启动门户,运行timeout = 120秒后自动关闭,失败则打印提示并ESP.restart()。README 还提到autoConnect与startConfigPortal都支持autoConnect()/startConfigPortal()的无参形式,此时自动生成 AP 名称。
从配置门户退出
正常情况下,门户会一直循环,直到成功输入 WiFi 凭据或达到超时。如果你不想加入任何 WiFi 网络(比如准备让 ESP 进入纯 AP 模式),可以直接点击主页面的"Exit"(退出)按钮。若门户是通过autoConnect或startConfigPortal启动的,此时会返回false (portalAbortResult)。
自定义参数(Custom Parameters)
除了 SSID 与密码,WiFiManager 还能帮你采集更多参数,比如 MQTT 主机与端口、blynk 或 emoncms 的 token 等。
⚠️这些自定义值的保存与加载完全由你自己负责,库只负责在页面上收集和展示数据。
典型使用场景:
- 从某处(EEPROM / FS)加载已有值,或生成默认值;
- 把自定义参数加入 WiFiManager:
// id/name, placeholder/prompt, default, length WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40); wifiManager.addParameter(&custom_mqtt_server);- 若连接 AP 失败,配置门户启动后即可修改这些值(或使用按需门户);
- 配置完成且连接建立后,
saveConfigCallback()被调用; - WiFiManager 把控制权交回应用后,用
WiFiManagerParameter对象读出新值并保存:
mqtt_server = custom_mqtt_server.getValue();WiFiManagerParameter的完整构造函数族见 WiFiManager.h:支持id + label两参数、id + label + defaultValue + length四参数,以及追加customHTML 的五参数形式和再追加labelPlacement的六参数形式。字段 id 用作 HTTP 查询参数名,README 与源码都要求其只能包含字母数字与下划线:addParameter()在 WiFiManager.cpp 中会对非字母数字字符返回false,参数数组以WIFI_MANAGER_MAX_PARAMS(默认 5,见 WiFiManager.h)为增量自动realloc扩容,用户无需再手动指定上限。
完整的"SPIFFS 读写 JSON 形式自定义参数"示例见 examples/Parameters/SPIFFS/AutoConnectWithFSParameters/AutoConnectWithFSParameters.ino;另有演示自定义 IP 配置的 examples/Parameters/SPIFFS/AutoConnectWithFSParametersAndCustomIP/AutoConnectWithFSParametersAndCustomIP.ino,以及演示继承子类方式的 examples/ParamsChildClass/ParamsChildClass.ino。EEPROM 版本在 README 中标注为"尚未完成"。
自定义 IP 配置
可以分别为 AP(配置模式)和 STA(客户端模式、正常运行状态)设置自定义 IP。
自定义 AP 静态 IP
如果需要把强制门户固定在某个 IP 上,在autoConnect()前加入:
//为门户设置自定义 IP wifiManager.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));源码实现见 WiFiManager.cpp,参数依次写入_ap_static_ip、_ap_static_gw、_ap_static_sn。
自定义 STA(客户端)静态 IP
在 STA 模式使用指定 IP 配置替代 DHCP:
wifiManager.setSTAStaticIPConfig(IPAddress(192,168,0,99), IPAddress(192,168,0,1), IPAddress(255,255,255,0)); // 可选第 4 个参数 DNS带 DNS 的重载版本见 WiFiManager.cpp,会把第 4 个参数存入_sta_static_dns。
⚠️ README 提醒:如果你有带主机名的 HTTP 请求,或需要同步时间(NTP),务必填写 DNS 服务器,可以填网关 IP 或公共 DNS(如 Google DNS:8.8.8.8)。
注入自定义 HTML / CSS / JavaScript
有几种方式可以向配置门户注入自定义内容:
- 注入自定义 head 元素:可用于向门户所有页面的
<head>添加任意 HTML;如果加了<style>元素,注意它是覆盖内置 CSS,而不是追加替换:
wifiManager.setCustomHeadElement("<style>html{filter: invert(100%); -webkit-filter: invert(100%);}</style>");- 在配置/参数表单中注入自定义 HTML 片段(例如段落文字、标签):
WiFiManagerParameter custom_text("<p>This is just a text paragraph</p>"); wifiManager.addParameter(&custom_text);- 在某个表单元素上注入自定义 HTML:把要附加的内容作为自定义参数构造函数的最后一个参数传入(例如给输入框加
readonly只读属性):
WiFiManagerParameter custom_mqtt_server("server", "mqtt server", "iot.eclipse", 40, " readonly"); wifiManager.addParameter(&custom_mqtt_server);主题定制(Theming)
可以用内置类定制默认模板的某些元素:
wifiManager.setClass("invert"); // 暗色主题 wifiManager.setScanDispPerc(true); // 用百分比替代信号强度图形setClass与setDarkMode的声明见 WiFiManager.h,模板中还有更多可在自定义 HTML 中使用的 CSS 类,可参考 extras/WiFiManager.template.html 与 extras/template.h。
网络过滤(Filter Networks)
可以按信号质量过滤网络,并控制是否显示重复网络:
- 屏蔽低信号质量网络(低于指定百分比的不显示,省略参数时默认为 8%):
wifiManager.setMinimumSignalQuality(10);源码见 WiFiManager.cpp,默认值 8 定义在 WiFiManager.h 的setMinimumSignalQuality(int quality = 8)。
- 显示(或隐藏)重复网络(默认是移除重复项):
wifiManager.setRemoveDuplicateAPs(false);调试输出(Debug)
- 非稳定版默认开启
Serial调试输出,在autoConnect/startConfigPortal之前关闭:
wifiManager.setDebugOutput(false);- 通过构造函数传入自定义输出流:
WiFiManager wifiManager(Serial1);WiFiManager(Print& consolePort)构造重载见 WiFiManager.h。
- 调试级别通过修改源码中的
_debugLevel定制,可选级别定义在 WiFiManager.h 的wm_debuglevel_t枚举中:
WM_DEBUG_SILENT // 关闭 WM_DEBUG_ERROR // 仅错误 WM_DEBUG_NOTIFY // 默认稳定版级别,INFO WM_DEBUG_VERBOSE // 更多细节 WM_DEBUG_DEV // 开发调试信息 WM_DEBUG_MAX // 最大审计信息(超出 MAX 还会打印 timing、mem、frag 信息)还可以用setDebugOutput(boolean debug, String prefix)自定义日志前缀(默认*wm:),或用setDebugOutput(boolean debug, wm_debuglevel_t level)直接设置级别(见 WiFiManager.cpp)。
故障排查(Troubleshooting)
README 给出了常见的几个问题与对策:
- 编译报错:多半需要安装更新版本的 ESP8266 Arduino core。0.8 版本改动后应兼容最新主干,官方声称向下测试到 ESP8266 core 2.0.0;若直接 checkout GitHub 最新代码,有时需要同步升级 core 到最新版(因为用到了新增函数);
- 连上了配置热点但门户不弹出:直接用浏览器访问 Web 门户 IP,默认
192.168.4.1; - 连接陷入死循环:在
autoConnect()前加setConnectTimeout(60),参数是以秒为单位的连接尝试超时; - 断电或 modem 复位后卡在 AP 模式:设置
setConfigPortalTimeout(seconds),门户在无活动后自动关闭,然后可以在代码里重启或重新尝试连接。
进阶能力:1.0.1 及后续版本公开 API 概览
README 的 Releases 章节列出了 1.0.1 及后续开发版本新增的公开方法(对应源码 WiFiManager.h 中的声明,均已实现):
- 门户控制:
setConfigPortalBlocking(阻塞/非阻塞)、setEnableConfigPortal(连接失败时是否自动启动门户)、setDisableConfigPortal、setCaptivePortalEnable、setAPClientCheck、setWebPortalClientCheck、startWebPortal/stopWebPortal(独立 Web 门户)、process(非阻塞模式下手动驱动服务器处理)、stopConfigPortal; - 连接管理:
disconnect、erase、setWiFiAutoReconnect、setCleanConnect、setSaveConnect、setConnectTimeout/setConnectRetries、getLastConxResult、getWLStatusString、getModeString、getWiFiIsSaved、getWiFiSSID/getWiFiPass; - 网络与门户配置:
setSTAStaticIPConfig(.., dns)、setShowStaticFields、setShowDnsFields、setHostname、setCountry、setWiFiAPChannel、setWiFiAPHidden、setHttpPort; - 界面定制:
setMenu(menu_page_t[])/setMenu(const char*[], uint8_t)、setParamsPage、setClass、setScanDispPerc、setShowInfoErase、setShowInfoUpdate、setTitle、setCustomBodyHeader/setCustomBodyFooter、setCustomMenuHTML、setShowPassword、htmlEntities; - 调试与状态:
debugSoftAPConfig、debugPlatformInfo、getConfigPortalSSID、getConfigPortalActive/getWebPortalActive、getDefaultAPName、getWiFiHostname、setRestorePersistent、preloadWiFi; WiFiManagerParameter扩展:WiFiManagerParameter(id, label)构造、setValue(value, length)、getParameters、getParametersCount(见 WiFiManager.h)。
编译期宏定义(⚠️ 不能在用户 sketch 里通过#define覆盖,需在库编译层面处理),见 WiFiManager.h:
#define WM_MDNS // 使用 MDNS,配合 setHostname #define WM_FIXERASECONFIG // 使用 erase flash 修复(esp8266 2.4.0) #define WM_ERASE_NVS // esp32 下 erase(true) 会擦除 NVSESP32 的信息页如需显示最近复位原因,需包含#include <rom/rtc.h>(库内对应WM_RTC宏,见 WiFiManager.h)。
1.0.1 变更要点
- ESP32 支持(较为稳定);
- 字符串全面重构并移入 strings_en.h 等语言包,wifiscan 新增图标、
left、invert icons、MSG 颜色等 token 与状态 callout 面板(默认/primary/special 颜色); - 信息页信息量大幅增加,并加入 erase 能力;信号强度以图标替代百分比(带 hover 标题),所有输入框加 label 替代 placeholder;
- 持久化默认关闭,通过
setRestorePersistent恢复用户设置,库不再擦除或覆盖 ESP8266 上已存储的配置; - ⚠️返回值可能变化:门户中止/超时分别对应
portalAbortResult/portalTimeoutResult; - 参数内存按
WIFI_MANAGER_MAX_PARAMS(5)自动增量分配,addParameter现在返回bool,非字母数字 id 返回false; - 支持
#define FIXERASECONFIG应对 esp8266/Arduino PR#3635 相关问题; - 门户可报告失败原因;ESP8266 STA 主机名、ESP32 STA+AP 主机名(DHCP client id)均可设置;
- 调试输出支持传入自定义流与分级;wifiscan 预缓存异步加载以加速页面响应。
早期版本历史(0.11 / 0.10)
- 0.12:移除 204 header 响应;修复与其它库在
isnan及std::函数未加命名空间时的兼容问题; - 0.11:更可靠的网络重连;自定义参数支持自定义 HTML(只读参数)、自定义表单 HTML(标签)、自定义 head 元素(CSS);网络按信号质量排序;移除重复网络;
- 0.10:部分 CSS 改动、bug 修复与提速;新增
waitForConnectResult()的调试替代方案;setTimeout(seconds)更名为setConfigPortalTimeout(seconds)。
相关资源
- 核心实现:WiFiManager.cpp(约 4000 行,含全部 API 与门户逻辑)、WiFiManager.h(公开接口与类型定义);
- 界面模板:extras/WiFiManager.template.html、extras/template.h,可用于了解门户页面结构与可定制 token;
- 语言包:wm_strings_en.h、wm_strings_de.h、wm_strings_fr.h、wm_strings_es.h、wm_strings_pt.h、wm_strings_pt_br.h;
- 示例代码:examples/Basic/Basic.ino(最小示例)、examples/OnDemand/OnDemandConfigPortal/OnDemandConfigPortal.ino(按需门户)、examples/Parameters/SPIFFS/AutoConnectWithFSParameters/AutoConnectWithFSParameters.ino(自定义参数 + FS 存储)、examples/Advanced/Advanced.ino(进阶用法);
- 构建配置:仓库根目录的 library.json、library.properties、CMakeLists.txt 与 keywords.txt 定义了库的元信息与 Arduino 关键字高亮。
- 物联网
- 嵌入式
【免费下载链接】WiFiManager
ESP8266 WiFi Connection manager with web captive portal
相关推荐
WiFiManager完全解析:ESP8266/ESP32 WiFi连接与配置门户终极指南
WiFiManager完全解析:ESP8266/ESP32 WiFi连接与配置门户终极指南 你还在为ESP8266/ESP32设备的WiFi配置烦恼吗?还在为硬
物联网嵌入式ESP8266 Captive Portal 项目推荐
ESP8266 Captive Portal 项目推荐 项目基础介绍和主要编程语言 ESP8266 Captive Portal 是一个基于 ESP8266 模
ESP8266 Captive Portal 项目教程
ESP8266 Captive Portal 项目教程 1. 项目的目录结构及介绍 ESP8266 Captive Portal 项目的目录结构如下: ESP8
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考