Ir al contenido

WiFi Connection on Button Press

Esta página aún no está disponible en tu idioma.

WiFi Connection on Button Press

This section covers the WiFi connection strategy for the IoT button — connecting to WiFi only when a button press is detected, with minimal delay and power consumption. By the end of this section, you will be able to:

  • Implement fast WiFi connection on wake from deep sleep
  • Optimize WiFi connection parameters for speed
  • Handle connection failures gracefully
  • Configure WiFi credentials for production deployment

Before starting this section, please ensure:

In a battery-powered IoT button, WiFi connection time is the dominant factor in energy consumption:

┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ Wake │ │ Scan │ │ Connect │ │ DHCP │ │ MQTT │
│ from │─►│ WiFi │─►│ to AP │─►│ IP │─►│ Publish │
│ Sleep │ │ Networks │ │ │ │ Acquire │ │ │
└──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘
0ms 500ms 1000-2000ms 300-500ms 500ms

Typical connection time: 2-4 seconds from wake to MQTT ready. Each additional second costs approximately 60 mAs (milliamp-seconds) of energy.

WiFi.begin(ssid, password) ───► WL_DISCONNECTED
│
▼
WL_CONNECTING ──► WL_CONNECTED ──► IP assigned
│
▼
WL_CONNECT_FAILED (retry or sleep)
│
▼
WL_NO_SSID_AVAIL (AP not found)

Since the button wakes from deep sleep and runs setup() each time, the WiFi connection logic goes in setup():

#include <WiFi.h>
#include <esp_wifi.h>
// WiFi credentials
const char* WIFI_SSID = "Factory_WiFi";
const char* WIFI_PASSWORD = "secure_password";
// Connection timeout
const unsigned long WIFI_TIMEOUT = 10000; // 10 seconds max
void connectWiFi() {
Serial.print("Connecting to 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("Connected! IP: ");
Serial.println(WiFi.localIP());
Serial.print("Connection time: ");
Serial.print(millis() - startAttempt);
Serial.println(" ms");
} else {
Serial.println();
Serial.println("WiFi connection FAILED");
}
}

Several techniques can significantly reduce connection time:

void optimizeWiFi() {
// 1. Disable WiFi power saving (reduces connection time)
WiFi.setSleep(false);
// 2. Set WiFi to station mode explicitly
WiFi.mode(WIFI_STA);
// 3. Use stored BSSID (access point MAC) to skip scan
// (Requires first connection to obtain and save the BSSID)
const uint8_t bssid[6] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
WiFi.begin(WIFI_SSID, WIFI_PASSWORD, 0, bssid, true);
// 4. Set channel directly if known
WiFi.begin(WIFI_SSID, WIFI_PASSWORD, 6); // Channel 6
// 5. Reduce connection timeout
esp_wifi_set_timeout(5000); // 5 second timeout instead of default ~15s
}

Connection time comparison:

TechniqueTimeEnergy Saved
Default connection (scan + connect)3-5s—
Skip scan (use BSSID)1.5-2.5s~40%
Set channel directly1-2s~50%
Combine all optimizations0.8-1.5s~65%

Step 3: Fast Reconnect Using Stored Credentials

Section titled “Step 3: Fast Reconnect Using Stored Credentials”

For the button application, store WiFi credentials in RTC memory to survive deep sleep:

// RTC_DATA_ATTR preserves data across deep sleep
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) {
// Fast connect using cached parameters
WiFi.begin(storedSSID, WIFI_PASSWORD,
storedChannel, storedBSSID, true);
} else {
// First time: full scan
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
}
}
bool connectWiFiWithRetry(int maxRetries = 2) {
for (int attempt = 0; attempt < maxRetries; attempt++) {
if (attempt > 0) {
Serial.print("Retry attempt ");
Serial.println(attempt + 1);
}
connectWiFi();
if (WiFi.status() == WL_CONNECTED) {
return true;
}
delay(100); // Brief pause before retry
}
return false; // All attempts failed
}
void setup() {
Serial.begin(115200);
delay(100);
// Configure button pin
pinMode(BUTTON_PIN, INPUT_PULLUP);
// Check wake reason
if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_EXT0) {
Serial.println("Button pressed - connecting to WiFi");
// Connect WiFi with optimizations
bool connected = connectWiFiWithRetry(3);
if (connected) {
// Proceed to MQTT publish
publishButtonPress();
} else {
Serial.println("WiFi failed - going back to sleep");
}
} else {
Serial.println("First boot - initializing");
// Initialization only on first power-on
}
// Go to sleep
goToDeepSleep();
}
  • WiFi connects within 3 seconds after button press
  • Connection succeeds on first attempt in strong signal areas
  • Device handles connection failures gracefully (retries + sleep)
  • RTC memory stores WiFi config across deep sleep cycles
  • No WiFi credentials leaked during deep sleep

Symptom: Connection time > 5 seconds

Possible Causes:

  • AP not in range
  • Channel changed since last connection
  • WiFi power saving enabled

Solution:

// Log connection phases for debugging
void debugWiFiConnection() {
Serial.print("WiFi status: ");
switch (WiFi.status()) {
case WL_NO_SSID_AVAIL:
Serial.println("AP not found - check SSID and range");
break;
case WL_CONNECT_FAILED:
Serial.println("Password incorrect");
break;
case WL_IDLE_STATUS:
Serial.println("Connection in progress...");
break;
}
}

Issue 2: WiFi Not Available at Button Location

Section titled “Issue 2: WiFi Not Available at Button Location”

Symptom: Frequent connection failures

Solution: Consider alternative architectures:

  • Use a WiFi mesh or repeater to extend coverage
  • Implement offline-first with queued messages
  • Change to ESP-NOW for local communication
  • ✅ Store BSSID and channel in RTC memory for fast reconnect
  • ✅ Set connection timeout to avoid hanging on weak signal
  • ✅ Retry at most 2-3 times to conserve battery
  • ✅ Log connection time for monitoring performance
  • ❌ Do not enable WiFi power saving — it adds latency
  • ❌ Do not scan for networks if BSSID is known
  1. WiFi connection takes 2-4 seconds typically, 1-1.5s with optimizations
  2. BSSID and channel caching significantly reduces connection time
  3. 3 retry attempts balance reliability and battery life
  4. WiFi consumes ~60 mA during connection — minimize active time
  5. Connection failures should be fast — retry 2-3 times, then sleep

Target Audience: Alibaba.com IoT Pre-sales Engineers
Status: ✅ Completed


Building a commercial IoT product?

We provide ESP32 ODM design-to-manufacturing services. From prototype to production — the team behind this tutorial can build it with you.

Talk to us →