Files
BotanicalBuddy/components/wifi-connect/BLOG.md
Wang Beihong 7261022611 feat: 初始化 BotanicalBuddy 项目并集成 Wi-Fi 配网组件
- 新增 wifi-connect 组件(AP 配网、DNS 劫持、Captive Portal)

- 支持长按按键进入配网,网页配置路由器 SSID/密码

- 增加清除已保存 Wi-Fi 参数能力(API + 页面按钮)

- 增加中文状态日志与中文注释,优化配网交互

- 补充组件文档:README、USER_GUIDE、QUICK_POSTER、BLOG
2026-03-05 12:41:15 +08:00

220 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 从 0 到 1我在 ESP32-C3 上做了一个可落地的 Wi-Fi 配网组件(含中文日志与一键清除配置)
> 项目BotanicalBuddy
> 平台ESP-IDF v5.5.2ESP32-C3
---
## 一、为什么要自己做一个配网组件?
很多物联网项目都会遇到同一个问题:
- 设备第一次上电,怎么让用户把它连进家里 Wi-Fi
- 配网失败时,怎么给用户清晰反馈?
- 现场调试时,日志如何快速看懂?
我这次的目标很明确:
1. **用户侧简单**:长按按键 → 连接热点 → 打开网页 → 输入密码;
2. **开发侧可维护**:接口清晰、状态可追踪、日志可读;
3. **现场可排障**:失败能看到原因,支持“一键清除历史配置”。
最终我把这些能力收敛成一个组件:`wifi-connect`
---
## 二、组件能力概览
`wifi-connect` 目前实现了这些核心能力:
- 长按按键进入配网模式;
- 设备开启 SoftAP`ESP32-xxxxxx`
- 内置 HTTP 配网页面(扫描、提交、状态轮询);
- DNS 劫持 + Captive Portal 路径兼容(提升手机弹窗成功率);
- 配网成功后保存凭据到 NVS
- 上电自动重连已保存网络;
- 中文状态日志(便于现场阅读);
- **清除已保存配置**(网页按钮 + API + SDK 接口)。
---
## 三、整体架构(简化)
```text
[按键任务] --长按--> [进入配网]
|
+--> APSTA 模式
+--> HTTP Server网页
+--> DNS 劫持服务
[网页] --POST /api/connect--> [设置 STA 参数并连接]
[网页] --GET /api/status --> [轮询状态]
[网页] --POST /api/clear --> [清除 NVS 凭据]
[Wi-Fi/IP 事件] --> [更新状态机 + 打印中文日志 + 保存凭据]
```
核心状态枚举:
- `idle`
- `provisioning`
- `connecting`
- `connected`
- `failed`
- `timeout`
---
## 四、最关键的实现点
### 1配网页面的“够用即好”设计
我没有引入前端框架,而是把 HTML/JS 直接内嵌在 C 字符串里,避免增加构建复杂度。页面只保留 3 个动作:
- 扫描网络
- 提交连接
- 清除已保存配置
这种做法的好处是:**部署轻、调试快、资源占用低**。
---
### 2手机“连上热点但不弹页面”的处理
这是配网常见痛点。为了提高兼容性,我做了两件事:
1. 注册常见探测路径(如 `/generate_204``/hotspot-detect.html` 等);
2. 对探测/未知 GET 请求统一返回 `302``http://192.168.4.1/`
这样很多手机系统会更容易触发门户页面。
---
### 3连接超时问题的根因与修复
我遇到过这样一条典型日志:
- `sta is connected, disconnect before connecting to new ap`
说明设备当时还连着旧网络,却直接尝试切到新网络,最终走到连接超时。修复方案很直接:
-`esp_wifi_set_config + esp_wifi_connect` 前,先 `esp_wifi_disconnect()`
- 若断开失败(非 `NOT_CONNECT`),记录告警日志。
这一步对稳定性提升很明显。
---
### 4新增“清除已保存配置”能力
为了提升可恢复性,我新增了完整链路:
- SDK API`wifi_connect_clear_config()`
- HTTP API`POST /api/clear`
- 页面按钮:“清除已保存”
执行逻辑:
1. 清除 NVS 的 `ssid`/`pass`
2. 清空运行时 pending 参数;
3. 若正在连接中,取消当前连接流程;
4. 在配网模式下把状态恢复为 `provisioning`,并清空旧错误文案。
这让“失败后重试”路径变得非常顺畅。
---
## 五、中文日志:现场效率提升非常大
为了让非固件同学也能看懂串口,我统一了状态日志风格:
- `【状态】配网已启动配网热点已开启SSID=...`
- `【状态】开始连接路由器:收到配网请求,目标网络:...`
- `【状态】联网成功:已连接 ...,获取 IP=...`
- `【状态】连接路由器超时:请确认密码和路由器信号`
这类日志在现场排障时比纯英文驱动日志直观很多。
> 注:`wifi:`、`esp_netif_lwip:` 前缀日志依然是 ESP-IDF 框架默认输出。
---
## 六、前端交互做了哪些“小而有效”的优化?
在配网页面里,我加了几项很实用的小优化:
- 连接/清除时禁用按钮,防止连点并发请求;
- 清除成功后自动清空密码框;
- 清除后自动刷新状态和扫描结果;
- 状态枚举映射成中文显示(`connecting -> 连接中`)。
这些改动代码不多,但用户体验差异非常明显。
---
## 七、对外 API当前版本
```c
esp_err_t wifi_connect_init(void);
esp_err_t wifi_connect_start(void);
esp_err_t wifi_connect_stop(void);
wifi_connect_status_t wifi_connect_get_status(void);
esp_err_t wifi_connect_get_config(wifi_connect_config_t *config);
esp_err_t wifi_connect_clear_config(void);
```
建议调用顺序:
1. 启动时调用 `wifi_connect_init()`
2. 用户长按或业务触发时调用 `wifi_connect_start()`
3. 成功后由组件自动收口,必要时可手动 `wifi_connect_stop()`
4. 需要重置时调用 `wifi_connect_clear_config()`
---
## 八、测试与验证建议
建议至少覆盖以下场景:
1. 首次配网成功;
2. 密码错误后重试成功;
3. 已连接旧网时切换到新网;
4. 清除配置后重新配网;
5. 空闲超时自动退出;
6. 断电重启后自动重连。
如果这 6 条都稳定通过,组件可用性通常已经比较高。
---
## 九、我这次的经验总结
如果你也在做 ESP32 配网,我建议优先做好三件事:
1. **状态机清晰**:每个阶段可见、可回退;
2. **日志可读**:现场的人不一定是固件开发;
3. **失败可恢复**:必须有“清除历史配置”的入口。
很多时候,不是“功能没做出来”,而是“异常路径没兜住”。把恢复路径做顺,产品体验会提升一大截。
---
## 十、后续可继续优化的方向
- 增加多语言页面(中/英切换);
- 增加 AP 密码与会话保护;
- 支持 BLE 辅助配网;
- 接入云端激活与设备绑定流程;
- 做更细粒度的连接错误码映射(前端可读提示)。
---
## 参考(项目内文档)
- `components/wifi-connect/README.md`
- `components/wifi-connect/USER_GUIDE.md`
- `components/wifi-connect/QUICK_POSTER.md`
---
如果你正在做类似项目,希望这篇实践记录能帮你少踩一些坑。