在嵌入式开发中,最头疼的问题之一就是:换个 Wi-Fi 环境就要重新改代码编译?
今天,我们用 Rust 语言 基于 esp-idf-svc 框架,为 ESP32-C3 Super Mini 开发一套完整的解决方案。它具备以下硬核功能:
🛠️ 硬件准备
🚀 核心逻辑流程
程序运行分为三个阶段:
ssid 和 password,有则尝试连接。
ESP32-Config-AP 的无密码热点,运行 Web 服务器接收表单数据。
💻 核心代码解析
1. 状态共享与并发
在 Rust 中,Web 服务器的任务回调是在独立线程中运行的。为了跨线程修改 LED 状态或 Wi-Fi 配置,我们使用了 Arc<Mutex<T>>:
// 共享状态:用于跨线程接收配网信息type SharedCreds = Arc<Mutex<Option<(String, String)>>>;let led_shared = Arc::new(Mutex::new(led));
2. NVS 持久化存储
使用 ESP32 的非易失性存储(NVS)来保存 SSID 和密码,确保掉电不丢失:
let nvs_storage = EspNvs::new(nvs_default_partition.clone(), "wifi_cfg", true)?;// 读取保存的配置if let (Some(s), Some(p)) = (saved_ssid, saved_pass) {info!("💾 发现保存的配置,正在尝试自动连接...");is_connected = connect_sta_logic(&mut blocking_wifi, s, p);}
3. 优雅的网页配网 UI
代码中内置了一个极简的 HTML/CSS 界面,适配手机端。通过 POST 请求接收 Wi-Fi 凭据并进行 URL 解码:
setup_server.fn_handler("/", Method::Get, |req| {let html = r#"<form action="/connect" method="post"><input name="ssid" placeholder="WiFi名称"><input name="password" type="password" placeholder="WiFi密码"><button type="submit">保存并连接</button></form>"#;req.into_ok_response()?.write_all(html.as_bytes())?;Ok(())})?;
4. 混合模式(STA + AP)
为了方便调试,当 ESP32 连上路由器(STA 模式)后,它依然会开启一个自己的热点(AP 模式),你可以通过两个 IP 访问控制台:
// 核心逻辑:获取路由器信道并开启混合模式let _ = wifi.set_configuration(&Configuration::Mixed(client_config, ap_config));
⚡ 细节决定成败:功率踩坑指南
在代码中有一行看似不起眼但至关重要的 unsafe 调用:
unsafe { esp_idf_svc::sys::esp_wifi_set_max_tx_power(40); }
为什么要这样做?
ESP32-C3 在启动 Wi-Fi 瞬时电流巨大,如果使用电脑 USB 供电或劣质数据线,经常会导致供电不足触发重置。将最大发射功率限制在 10dBm(参数 40),能极大提高小型开发板的稳定性。
💡 如何一键重置?
如果 Wi-Fi 密码改了,或者想带去公司用,只需要在 Web 界面点击“清除 WiFi 配置并重启”。程序会执行 nvs.remove(...) 并调用系统重启:
main_server.fn_handler("/reset", Method::Get, move |req| {// 清除 NVS 记录...thread::spawn(|| {thread::sleep(Duration::from_secs(2));unsafe { esp_idf_svc::sys::esp_restart(); } // 重启系统});Ok(())})?;
📥 结语
使用 Rust 开发 ESP32 不仅能享受类型安全带来的愉悦,配合 esp-idf-svc 强大的生态,我们可以快速构建出媲美工业级产品的配网系统。
想要获取完整代码工程?
欢迎关注本公众号,后台回复 “ESP32网页配网” 获取源码仓库地址!