WiFi Connection on Button Press
WiFi Connection on Button Press
Overview
Section titled “Overview”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
Prerequisites
Section titled “Prerequisites”Before starting this section, please ensure:
- Completed 04-05. Deep Sleep Power Optimization
- Basic WiFi networking knowledge (SSID, password, IP)
- Completed Chapter 01 ESP32 WiFi basics
Key Concepts
Section titled “Key Concepts”The WiFi Connection Challenge
Section titled “The WiFi Connection Challenge”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 500msTypical connection time: 2-4 seconds from wake to MQTT ready. Each additional second costs approximately 60 mAs (milliamp-seconds) of energy.
ESP32 WiFi States
Section titled “ESP32 WiFi States”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)Implementation Steps
Section titled “Implementation Steps”Step 1: Basic WiFi Connection in Setup
Section titled “Step 1: Basic WiFi Connection in Setup”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 credentialsconst char* WIFI_SSID = "Factory_WiFi";const char* WIFI_PASSWORD = "secure_password";
// Connection timeoutconst 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"); }}Step 2: Optimize WiFi Connection Speed
Section titled “Step 2: Optimize WiFi Connection Speed”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:
| Technique | Time | Energy Saved |
|---|---|---|
| Default connection (scan + connect) | 3-5s | — |
| Skip scan (use BSSID) | 1.5-2.5s | ~40% |
| Set channel directly | 1-2s | ~50% |
| Combine all optimizations | 0.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 sleepRTC_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); }}Step 4: Connection Failure Handling
Section titled “Step 4: Connection Failure Handling”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}Step 5: Complete Button WiFi Logic
Section titled “Step 5: Complete Button WiFi Logic”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();}Verification
Section titled “Verification”- 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
Troubleshooting
Section titled “Troubleshooting”Issue 1: WiFi Takes Too Long to Connect
Section titled “Issue 1: WiFi Takes Too Long to Connect”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 debuggingvoid 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
Best Practices
Section titled “Best Practices”- ✅ 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
Summary
Section titled “Summary”- WiFi connection takes 2-4 seconds typically, 1-1.5s with optimizations
- BSSID and channel caching significantly reduces connection time
- 3 retry attempts balance reliability and battery life
- WiFi consumes ~60 mA during connection — minimize active time
- Connection failures should be fast — retry 2-3 times, then sleep
References
Section titled “References”Target Audience: Alibaba.com IoT Pre-sales Engineers
Status: ✅ Completed