Skip to content

WiFi Connection Implementation

WiFi Connection Implementation

This section covers how to connect the ESP32 to a Wi-Fi network. By the end of this section, you will be able to:

  • Write an ESP32 sketch that connects to a Wi-Fi network
  • Implement connection timeout and reconnection logic
  • Display the ESP32’s IP address after connection
  • Handle Wi-Fi disconnection events gracefully
  • ESP32 board set up with Arduino IDE (01-04) or PlatformIO (01-05)
  • A Wi-Fi network with known SSID and password

The ESP32 Wi-Fi subsystem operates in two main modes:

  • Station (STA) Mode: The ESP32 connects to an existing Wi-Fi access point (router). This is the most common mode for IoT devices.
  • Access Point (AP) Mode: The ESP32 creates its own Wi-Fi network that other devices can join. Used for device configuration or direct connections.
  • STA+AP Mode: Both modes simultaneously. The ESP32 connects to your network while also hosting its own AP.

This section focuses on Station Mode, which is used in all course projects.

ESP32 uses the built-in WiFi.h library, which is included with the ESP32 Arduino Core. The key functions are:

FunctionDescription
WiFi.begin(ssid, password)Start connecting to Wi-Fi
WiFi.status()Return current connection status
WiFi.localIP()Get assigned IP address
WiFi.disconnect()Disconnect from Wi-Fi
WiFi.reconnect()Force reconnection
WiFi.mode(mode)Set Wi-Fi mode (STA/AP/AP_STA)
WiFi.setAutoReconnect(true)Enable automatic reconnection
StatusValueMeaning
WL_NO_SHIELD255Wi-Fi module not present
WL_IDLE_STATUS0Wi-Fi module idle
WL_NO_SSID_AVAIL1SSID not found
WL_SCAN_COMPLETED2Network scan complete
WL_CONNECTED3Successfully connected
WL_CONNECT_FAILED4Connection failed (wrong password)
WL_CONNECTION_LOST5Connection lost after being connected
WL_DISCONNECTED6Module disconnected

The simplest connection code:

#include <WiFi.h>
const char* ssid = "YourWiFiSSID";
const char* password = "YourWiFiPassword";
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("Wi-Fi connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
// Your main code here
delay(10000);
}

Important: The while loop blocks execution until the connection is established. For production code, a non-blocking approach (Step 2) is preferred.

Step 2: Non-Blocking Connection with Timeout

Section titled “Step 2: Non-Blocking Connection with Timeout”

A robust connection routine should timeout and retry instead of blocking indefinitely:

#include <WiFi.h>
const char* ssid = "YourWiFiSSID";
const char* password = "YourWiFiPassword";
const int MAX_CONNECTION_ATTEMPTS = 40; // ~20 seconds (40 * 500ms)
void setup() {
Serial.begin(115200);
delay(1000);
connectToWiFi();
}
void connectToWiFi() {
Serial.print("Connecting to Wi-Fi");
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < MAX_CONNECTION_ATTEMPTS) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println();
Serial.println("Wi-Fi connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println();
Serial.println("Wi-Fi connection failed!");
Serial.println("Restarting ESP32...");
delay(2000);
ESP.restart(); // Reboot and try again
}
}
void loop() {
// Check connection status periodically
if (WiFi.status() != WL_CONNECTED) {
Serial.println("Wi-Fi disconnected! Reconnecting...");
connectToWiFi();
}
delay(10000);
}

The ESP32 Arduino Core provides Wi-Fi event handling, which is more robust than polling:

#include <WiFi.h>
const char* ssid = "YourWiFiSSID";
const char* password = "YourWiFiPassword";
// Event handler function
void WiFiEvent(WiFiEvent_t event) {
switch (event) {
case ARDUINO_EVENT_WIFI_STA_START:
Serial.println("Wi-Fi started");
break;
case ARDUINO_EVENT_WIFI_STA_CONNECTED:
Serial.println("Wi-Fi connected to AP");
break;
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
Serial.print("IP address obtained: ");
Serial.println(WiFi.localIP());
break;
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
Serial.println("Wi-Fi disconnected! Attempting to reconnect...");
WiFi.reconnect(); // Auto-reconnect
break;
case ARDUINO_EVENT_WIFI_STA_STOP:
Serial.println("Wi-Fi stopped");
break;
default:
break;
}
}
void setup() {
Serial.begin(115200);
delay(1000);
// Register event handler
WiFi.onEvent(WiFiEvent);
// Enable auto-reconnect (ESP32 built-in feature)
WiFi.setAutoReconnect(true);
// Start connection
WiFi.begin(ssid, password);
Serial.print("Connecting to ");
Serial.println(ssid);
}
void loop() {
// Your main code runs here
// Wi-Fi reconnection is handled automatically by events
delay(10000);
}

Hard-coding credentials in the sketch is fine for development but insecure for production. Alternative approaches:

Option 1: Separate Header File (Recommended for Development)

Create credentials.h:

#ifndef CREDENTIALS_H
#define CREDENTIALS_H
const char* ssid = "YourWiFiSSID";
const char* password = "YourWiFiPassword";
#endif

In main.cpp:

#include "credentials.h"

Add credentials.h to .gitignore:

credentials.h

Option 2: WiFiManager Library (For Production)

The WiFiManager library creates a captive portal on first boot, allowing users to configure Wi-Fi credentials via a web browser.

#include <WiFiManager.h>
void setup() {
Serial.begin(115200);
WiFiManager wm;
// Auto-connect with saved credentials, or start config portal
if (!wm.autoConnect("ESP32-Config")) {
Serial.println("Failed to connect!");
ESP.restart();
}
Serial.println("Wi-Fi connected!");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
}
void loop() {
delay(10000);
}

Credentials are stored in ESP32’s non-volatile storage (NVS) and persist across reboots.

void printSignalStrength() {
long rssi = WiFi.RSSI();
Serial.print("Signal strength (RSSI): ");
Serial.print(rssi);
Serial.print(" dBm (");
// Qualitative assessment
if (rssi > -50) {
Serial.print("Excellent");
} else if (rssi > -60) {
Serial.print("Good");
} else if (rssi > -70) {
Serial.print("Fair");
} else if (rssi > -80) {
Serial.print("Weak");
} else {
Serial.print("Very weak");
}
Serial.println(")");
}
  • ESP32 connects to the Wi-Fi network and obtains an IP address
  • Serial Monitor shows “Wi-Fi connected” with correct IP
  • Disconnecting the router causes the ESP32 to attempt reconnection
  • Reconnecting the router restores the Wi-Fi connection
  • The event-based approach handles disconnections without blocking loop()
  • RSSI reading is reasonable (>-70 dBm for stable operation)

Causes:

  • Wrong SSID or password
  • Router not broadcasting SSID (hidden network)
  • Router in a different frequency band (ESP32 supports 2.4 GHz only)

Solutions:

  1. Double-check SSID and password (case-sensitive)
  2. Ensure your router is broadcasting the SSID
  3. Verify the router uses 2.4 GHz (ESP32 does NOT support 5 GHz Wi-Fi)
  4. If using a hidden SSID, add: WiFi.begin(ssid, password, 0, bssid) with BSSID

Causes:

  • Wi-Fi channel interference
  • ESP32 too far from router
  • Power supply instability

Solutions:

  1. Move ESP32 closer to the router
  2. Use a longer USB cable or external power supply
  3. Add WiFi.setSleep(false) to disable power saving (improves stability)
  4. Implement reconnection logic with exponential backoff

Causes:

  • ESP32 Wi-Fi antenna issue
  • Only 5 GHz networks available
  • ESP32 hardware fault

Solutions:

  1. Scan for networks: Create a sketch that calls WiFi.scanNetworks()
  2. If the list is empty but other devices see networks, the ESP32 may be faulty
  3. Try an external antenna (if the board has a connector)
  • Use event-based Wi-Fi handling (WiFi.onEvent()): More robust and non-blocking than polling WiFi.status() in loop()
  • Implement connection timeout: Never wait indefinitely for connection — use a counter to limit attempts
  • Enable auto-reconnect: WiFi.setAutoReconnect(true) reduces manual reconnection code
  • Separate credentials from code: Use credentials.h or WiFiManager to avoid exposing passwords in source
  • Monitor RSSI: If signal drops below -80 dBm, the connection will be unstable
  • Handle Wi-Fi in a separate file: Create a wifi_manager.h/.cpp for clean project structure
  1. ESP32 connects to Wi-Fi via WiFi.begin(ssid, password) in Station mode
  2. Non-blocking connection with timeout prevents indefinite blocking
  3. Event-based handling (WiFi.onEvent) is the most robust approach
  4. Credentials should be stored separately from main code (header file or WiFiManager)
  5. RSSI monitoring helps diagnose connection quality
  6. The ESP32 only supports 2.4 GHz Wi-Fi — this is a common source of confusion