Skip to content

WiFi Connection on Button Press

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