Phase 4: Connectivity 12 min read

Wi-Fi Basics on ESP32 — Connecting to a Network

Learn how to connect your ESP32 to a Wi-Fi network using Arduino IDE. Covers SSID credentials, connection states, IP address retrieval, and reconnect logic.

Updated June 18, 2026

Introduction to Wi-Fi on ESP32

The ESP32’s built-in Wi-Fi radio is one of its most powerful features. Unlike the Arduino Uno, which needs an external shield to reach the internet, the ESP32 connects natively to any 2.4 GHz 802.11 b/g/n network. This guide walks you through the complete connection sequence — from scanning for networks to reading your assigned IP address and handling dropped connections gracefully.

Required Library

The WiFi.h library is part of the official arduino-esp32 board package and needs no separate installation. Add it to your sketch with a single include:

includes
#include <WiFi.h>

Setting Your Credentials

Hard-coding credentials is acceptable for personal experiments. For anything shared or version-controlled, use the Preferences library instead (covered later). For now:

credentials.ino
const char* ssid     = "YourNetworkName";   // case-sensitive
const char* password = "YourPassword";

The Minimal Connection Sketch

wifi_connect.ino
#include <WiFi.h>

const char* ssid     = "YourSSID";
const char* password = "YourPassword";

void setup() {
  Serial.begin(115200);

  WiFi.mode(WIFI_STA);          // station mode (client)
  WiFi.begin(ssid, password);

  Serial.print("Connecting");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("\nConnected!");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
  Serial.print("Signal (RSSI): ");
  Serial.print(WiFi.RSSI());
  Serial.println(" dBm");
}

void loop() {
  // your application code here
}

Understanding WiFi.status()

The WiFi.status() function returns one of these constants:

Constant Value Meaning
WL_CONNECTED 3 Successfully connected with IP assigned
WL_NO_SSID_AVAIL 1 SSID not found in range
WL_CONNECT_FAILED 4 Wrong password or authentication failed
WL_IDLE_STATUS 0 Wi-Fi hardware idle or switching modes
WL_DISCONNECTED 6 Not connected, but credentials are stored

Setting a Static IP Address

DHCP adds a small delay and the IP can change between reboots. For servers and sensors that other devices need to find reliably, assign a static IP:

static_ip.ino
#include <WiFi.h>

const char* ssid     = "YourSSID";
const char* password = "YourPassword";

IPAddress local_IP(192, 168, 1, 120);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(8, 8, 8, 8);    // optional

void setup() {
  Serial.begin(115200);

  if (!WiFi.config(local_IP, gateway, subnet, primaryDNS)) {
    Serial.println("Static IP configuration failed");
  }

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nConnected with static IP: " + WiFi.localIP().toString());
}

Reconnection Watchdog

Networks drop. Routers reboot. Implement a non-blocking reconnect loop so your device recovers automatically:

wifi_watchdog.ino
#include <WiFi.h>

const char* ssid     = "YourSSID";
const char* password = "YourPassword";

unsigned long lastReconnectAttempt = 0;
const unsigned long RECONNECT_INTERVAL = 10000; // 10 s

void connectWiFi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Connecting to Wi-Fi");
  unsigned long t = millis();
  while (WiFi.status() != WL_CONNECTED && millis() - t < 15000) {
    delay(500);
    Serial.print(".");
  }
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("\nConnected: " + WiFi.localIP().toString());
  } else {
    Serial.println("\nFailed — will retry");
  }
}

void setup() {
  Serial.begin(115200);
  connectWiFi();
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    unsigned long now = millis();
    if (now - lastReconnectAttempt >= RECONNECT_INTERVAL) {
      lastReconnectAttempt = now;
      Serial.println("Wi-Fi lost — reconnecting...");
      WiFi.disconnect();
      connectWiFi();
    }
  }
  // application code here
}

Scanning for Networks

Use WiFi.scanNetworks() to discover nearby SSIDs — useful for diagnostics or let users choose a network at runtime:

wifi_scan.ino
#include <WiFi.h>

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);

  int n = WiFi.scanNetworks();
  if (n == 0) {
    Serial.println("No networks found");
  } else {
    Serial.printf("Found %d networks:\n", n);
    for (int i = 0; i < n; i++) {
      Serial.printf("  %2d: %-30s RSSI:%4d CH:%2d %s\n",
        i + 1,
        WiFi.SSID(i).c_str(),
        WiFi.RSSI(i),
        WiFi.channel(i),
        WiFi.encryptionType(i) == WIFI_AUTH_OPEN ? "OPEN" : "SECURED");
    }
  }
  WiFi.scanDelete();
}

void loop() {}

Power and ADC Considerations

When Wi-Fi is active the ESP32 radio draws up to 240 mA peak. Two side effects matter for hardware design:

  • ADC2 is unusable. Pins GPIO0, 2, 4, 12–15, 25–27 are shared with the RF subsystem. Use ADC1 (GPIO32–39) for any analog reads while Wi-Fi is on.
  • Voltage rail noise. Add a 100 µF electrolytic and 100 nF ceramic capacitor between 3.3V and GND close to the ESP32 module to filter RF-induced supply spikes.

Disabling Modem Sleep

By default the ESP32 enters modem sleep between beacons to save power. This can cause brief disconnections. For always-on applications:

disable_sleep.ino
WiFi.setSleep(false);   // call after WiFi.begin(), before connecting

Reading Network Information

network_info.ino
Serial.println("=== Network Info ===");
Serial.println("SSID:    " + WiFi.SSID());
Serial.println("IP:      " + WiFi.localIP().toString());
Serial.println("Gateway: " + WiFi.gatewayIP().toString());
Serial.println("Subnet:  " + WiFi.subnetMask().toString());
Serial.println("DNS:     " + WiFi.dnsIP().toString());
Serial.println("MAC:     " + WiFi.macAddress());
Serial.printf( "RSSI:    %d dBm\n", WiFi.RSSI());

Next Steps

Now that your ESP32 is on the network, explore what you can do with it:

Frequently Asked Questions

ESP32 supports 802.11 b/g/n at 2.4 GHz. It does not support 5 GHz networks. Maximum theoretical throughput is 150 Mbps but real-world speeds are closer to 20–30 Mbps for TCP traffic.
Use the Preferences library (NVS flash storage) to store SSID and password at runtime rather than hard-coding them. This lets you update credentials without reflashing and keeps them out of version control.
This usually means the SSID is not found or the password is wrong. Double-check both, ensure the router broadcasts 2.4 GHz, and confirm the ESP32 is within range.
Yes. Use WiFi.begin(ssid, password, channel, bssid, connect) with the exact BSSID (MAC address) of the access point, or call WiFi.scanNetworks(false, true) to include hidden networks in the scan.
WiFi.begin() starts a new connection attempt with the provided credentials. WiFi.reconnect() retries the last used credentials — useful in a reconnect loop without storing the password in a local variable again.
Initial connection to a known network typically takes 1–3 seconds. If the router uses DHCP it may add another 500 ms for IP assignment. Static IP assignment skips this delay.
Yes. Wi-Fi and ADC2 share the RF subsystem. ADC2 pins (GPIO0, 2, 4, 12–15, 25–27) are unusable when Wi-Fi is active. Use ADC1 pins (GPIO32–39) for analog readings when Wi-Fi is on.
Call WiFi.config(IPAddress ip, IPAddress gateway, IPAddress subnet) before WiFi.begin(). For example: WiFi.config(IPAddress(192,168,1,100), IPAddress(192,168,1,1), IPAddress(255,255,255,0)).
Router power-saving or ARP timeout can disconnect idle clients. Call WiFi.setSleep(false) to disable ESP32 modem sleep, and implement a watchdog loop that calls WiFi.reconnect() when WiFi.status() != WL_CONNECTED.
Yes. Each gets a unique IP and MAC. You can run up to 10 stations simultaneously in a typical home router. For larger deployments use a business-grade AP that supports more associations.

Projects to Build

Put this knowledge to work — try one of these hands-on projects.