跳转到内容

按键按下时WiFi连接

按键按下时WiFi连接

本节介绍物联网按钮的WiFi连接策略——仅在检测到按键按下时连接WiFi,并尽可能减少延迟和功耗。通过本节学习,你将能够:

  • 实现从深度睡眠唤醒后的快速WiFi连接
  • 优化WiFi连接参数以提高连接速度
  • 优雅地处理连接失败
  • 为生产部署配置WiFi凭证

开始本节之前,请确保:

在电池供电的物联网按钮中,WiFi连接时间是能耗的主导因素:

┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 唤醒 │ │ 扫描 │ │ 连接 │ │ DHCP │ │ MQTT │
│ 自 │─►│ WiFi │─►│ 至 │─►│ IP │─►│ 发布 │
│ 深度睡眠 │ │ 网络 │ │ 接入点 │ │ 获取 │ │ │
└──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘
0ms 500ms 1000-2000ms 300-500ms 500ms

典型连接时间:从唤醒到MQTT就绪需 2-4秒。 每增加一秒大约消耗 60 mAs(毫安秒) 的能量。

WiFi.begin(ssid, password) ───► WL_DISCONNECTED
WL_CONNECTING ──► WL_CONNECTED ──► IP已分配
WL_CONNECT_FAILED(重试或睡眠)
WL_NO_SSID_AVAIL(未找到接入点)

第一步:在Setup中建立基础WiFi连接

Section titled “第一步:在Setup中建立基础WiFi连接”

由于按钮从深度睡眠唤醒后每次都会执行 setup(),因此WiFi连接逻辑放在 setup() 中:

#include <WiFi.h>
#include <esp_wifi.h>
// WiFi凭证
const char* WIFI_SSID = "Factory_WiFi";
const char* WIFI_PASSWORD = "secure_password";
// 连接超时
const unsigned long WIFI_TIMEOUT = 10000; // 最多10秒
void connectWiFi() {
Serial.print("正在连接WiFi:");
Serial.println(WIFI_SSID);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
unsigned long startAttempt = millis();
while (WiFi.status() != WL_CONNECTED &&
millis() - startAttempt < WIFI_TIMEOUT) {
delay(100);
Serial.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println();
Serial.print("已连接!IP地址:");
Serial.println(WiFi.localIP());
Serial.print("连接耗时:");
Serial.print(millis() - startAttempt);
Serial.println(" 毫秒");
} else {
Serial.println();
Serial.println("WiFi连接失败");
}
}

以下几种技术可以显著减少连接时间:

void optimizeWiFi() {
// 1. 禁用WiFi省电模式(减少连接时间)
WiFi.setSleep(false);
// 2. 明确设置为站点模式
WiFi.mode(WIFI_STA);
// 3. 使用存储的BSSID(接入点MAC)跳过扫描
// (需要首次连接获取并保存BSSID)
const uint8_t bssid[6] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
WiFi.begin(WIFI_SSID, WIFI_PASSWORD, 0, bssid, true);
// 4. 已知信道时直接设置
WiFi.begin(WIFI_SSID, WIFI_PASSWORD, 6); // 信道6
// 5. 缩短连接超时
esp_wifi_set_timeout(5000); // 5秒超时代替默认的约15秒
}

连接时间对比

技术时间节省能耗
默认连接(扫描+连接)3-5秒
跳过扫描(使用BSSID)1.5-2.5秒~40%
直接设置信道1-2秒~50%
综合所有优化0.8-1.5秒~65%

第三步:使用存储凭证快速重连

Section titled “第三步:使用存储凭证快速重连”

对于按钮应用,将WiFi凭证存储在RTC内存中以在深度睡眠后保持:

// RTC_DATA_ATTR 在深度睡眠期间保留数据
RTC_DATA_ATTR bool wifiConfigured = false;
RTC_DATA_ATTR char storedSSID[32] = "";
RTC_DATA_ATTR uint8_t storedBSSID[6] = {0};
RTC_DATA_ATTR int storedChannel = 0;
void saveWiFiConfig() {
wifiConfigured = true;
strcpy(storedSSID, WiFi.SSID().c_str());
memcpy(storedBSSID, WiFi.BSSID(), 6);
storedChannel = WiFi.channel();
}
void connectWithCachedConfig() {
if (wifiConfigured && storedChannel > 0) {
// 使用缓存参数快速连接
WiFi.begin(storedSSID, WIFI_PASSWORD,
storedChannel, storedBSSID, true);
} else {
// 首次:完整扫描
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
}
}
bool connectWiFiWithRetry(int maxRetries = 2) {
for (int attempt = 0; attempt < maxRetries; attempt++) {
if (attempt > 0) {
Serial.print("重试第 ");
Serial.println(attempt + 1);
Serial.println("");
}
connectWiFi();
if (WiFi.status() == WL_CONNECTED) {
return true;
}
delay(100); // 重试前短暂停顿
}
return false; // 所有尝试均失败
}
void setup() {
Serial.begin(115200);
delay(100);
// 配置按键引脚
pinMode(BUTTON_PIN, INPUT_PULLUP);
// 检查唤醒原因
if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_EXT0) {
Serial.println("检测到按键按下 - 正在连接WiFi");
// 使用优化方式连接WiFi
bool connected = connectWiFiWithRetry(3);
if (connected) {
// 继续执行MQTT发布(第04-08节)
publishButtonPress();
} else {
Serial.println("WiFi连接失败 - 返回睡眠");
}
} else {
Serial.println("首次启动 - 正在初始化");
// 仅在首次上电时初始化
}
// 进入深度睡眠
goToDeepSleep();
}
  • 按键按下后3秒内完成WiFi连接
  • 在信号强的区域首次连接即成功
  • 设备优雅处理连接失败(重试+睡眠)
  • RTC内存在深度睡眠周期间保留WiFi配置
  • 深度睡眠期间不会泄露WiFi凭证

症状:连接时间 > 5秒

可能原因

  • 接入点不在范围内
  • 自上次连接后信道已更改
  • 启用了WiFi省电模式

解决方案

// 记录连接阶段用于调试
void debugWiFiConnection() {
Serial.print("WiFi状态:");
switch (WiFi.status()) {
case WL_NO_SSID_AVAIL:
Serial.println("未找到接入点 - 请检查SSID和信号范围");
break;
case WL_CONNECT_FAILED:
Serial.println("密码错误");
break;
case WL_IDLE_STATUS:
Serial.println("连接进行中...");
break;
}
}

症状:频繁连接失败

解决方案:考虑替代架构:

  • 使用WiFi Mesh或中继器扩展覆盖范围
  • 实现离线优先模式,消息排队发送
  • 改用ESP-NOW进行本地通信
  • 将BSSID和信道存储在RTC内存中,实现快速重连
  • 设置连接超时,避免在弱信号下卡住
  • 最多重试2-3次以节省电量
  • 记录连接时间以便监控性能
  • 不要启用WiFi省电模式——它会增加延迟
  • 如果已知BSSID,不要扫描网络
  1. WiFi连接通常需要2-4秒,经过优化可缩短至1-1.5秒
  2. 缓存BSSID和信道可显著减少连接时间
  3. 3次重试在可靠性和电池寿命之间取得平衡
  4. WiFi连接时耗电约60 mA——应尽量减少活动时间
  5. 连接失败应快速处理——重试2-3次后进入睡眠