ESP32 WiFi Tutorial — Connect to WiFi, Web Server & HTTP Requests
The ESP32 has dual-mode WiFi (2.4 GHz 802.11 b/g/n) built in. Unlike Arduino Uno or Nano which need an external WiFi shield, the ESP32 connects to your router with a few lines of code. This guide covers everything from basic connection to building a web server.
Prerequisite: Install ESP32 board support in Arduino IDE. Go to File → Preferences → Additional Board Manager URLs and add:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
Then: Tools → Board → Boards Manager → search "esp32" → Install.
ESP32 WiFi Modes
| Mode | Description | Use case |
|---|---|---|
| Station (STA) | ESP32 connects to existing WiFi router | Most IoT projects |
| Access Point (AP) | ESP32 creates its own WiFi network | Config portal, direct device connection |
| Station + AP | Both simultaneously | Config portals with internet relay |
Mode 1 — Station Mode (Connect to Your Router)
#include <WiFi.h>
const char* ssid = "YourWiFiName"; // Replace with your SSID
const char* password = "YourPassword"; // Replace with your password
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("Connecting to WiFi...");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
// Wait for connection (max 10 seconds)
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nConnected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Serial.print("Signal strength (RSSI): ");
Serial.print(WiFi.RSSI());
Serial.println(" dBm");
} else {
Serial.println("\nFailed to connect.");
}
}
void loop() {
// Check if still connected
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi lost. Reconnecting...");
WiFi.reconnect();
delay(5000);
}
}
Expected output:
Connecting to WiFi...
..........
Connected!
IP address: 192.168.1.105
Signal strength (RSSI): -58 dBm
Open your router's client list and you'll see the ESP32 with the IP address shown.
Mode 2 — Access Point (Create Your Own WiFi)
#include <WiFi.h>
const char* ap_ssid = "ESP32-Setup";
const char* ap_password = "12345678"; // Min 8 characters, or use "" for open
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_AP);
WiFi.softAP(ap_ssid, ap_password);
Serial.println("Access Point started");
Serial.print("AP IP address: ");
Serial.println(WiFi.softAPIP()); // Usually 192.168.4.1
Serial.print("SSID: ");
Serial.println(ap_ssid);
}
void loop() {
Serial.print("Clients connected: ");
Serial.println(WiFi.softAPgetStationNum());
delay(5000);
}
Connect your phone/laptop to "ESP32-Setup" and navigate to 192.168.4.1 in a browser.
Build a Web Server
Control an LED from any browser on your network:
#include <WiFi.h>
#include <WebServer.h>
const char* ssid = "YourWiFiName";
const char* password = "YourPassword";
WebServer server(80); // Port 80 = standard HTTP
const int LED_PIN = 2; // Built-in LED
// HTML page
const char* htmlPage = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<title>ESP32 Control</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body { font-family: Arial; text-align: center; margin-top: 50px; }
button { padding: 15px 30px; font-size: 20px; margin: 10px; border: none; border-radius: 8px; cursor: pointer; }
.on { background: #4CAF50; color: white; }
.off { background: #f44336; color: white; }
</style>
</head>
<body>
<h1>ESP32 LED Control</h1>
<button class="on" onclick="fetch('/on')">LED ON</button>
<button class="off" onclick="fetch('/off')">LED OFF</button>
</body>
</html>
)rawliteral";
void handleRoot() {
server.send(200, "text/html", htmlPage);
}
void handleLEDOn() {
digitalWrite(LED_PIN, HIGH);
server.send(200, "text/plain", "LED is ON");
Serial.println("LED ON");
}
void handleLEDOff() {
digitalWrite(LED_PIN, LOW);
server.send(200, "text/plain", "LED is OFF");
Serial.println("LED OFF");
}
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected! Open: http://" + WiFi.localIP().toString());
server.on("/", handleRoot);
server.on("/on", handleLEDOn);
server.on("/off", handleLEDOff);
server.begin();
}
void loop() {
server.handleClient();
}
Upload, open Serial Monitor, and navigate to the IP shown. You'll see buttons to control the LED from any device on your network.
HTTP GET Request (Fetch Data from an API)
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
const char* ssid = "YourWiFiName";
const char* password = "YourPassword";
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected!");
}
void loop() {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
// Free test API — returns random numbers
http.begin("https://worldtimeapi.org/api/timezone/America/New_York");
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
// Parse JSON
JsonDocument doc;
deserializeJson(doc, payload);
const char* datetime = doc["datetime"];
Serial.print("Current time: ");
Serial.println(datetime);
} else {
Serial.print("HTTP error: ");
Serial.println(httpCode);
}
http.end();
}
delay(10000); // Fetch every 10 seconds
}
Install ArduinoJson library: Library Manager → search "ArduinoJson" by Benoit Blanchon → Install.
HTTP POST Request (Send Sensor Data)
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "YourWiFiName";
const char* password = "YourPassword";
const char* serverUrl = "https://httpbin.org/post"; // Test endpoint
void postSensorData(float temperature, float humidity) {
HTTPClient http;
http.begin(serverUrl);
http.addHeader("Content-Type", "application/json");
String jsonPayload = "{\"temperature\":" + String(temperature, 1) +
",\"humidity\":" + String(humidity, 1) + "}";
int httpCode = http.POST(jsonPayload);
if (httpCode > 0) {
Serial.print("POST response code: ");
Serial.println(httpCode);
if (httpCode == HTTP_CODE_OK) {
Serial.println("Data sent successfully!");
}
} else {
Serial.print("POST failed: ");
Serial.println(http.errorToString(httpCode));
}
http.end();
}
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected!");
}
void loop() {
float fakeTemp = 23.5 + random(-10, 10) / 10.0;
float fakeHum = 55.0 + random(-50, 50) / 10.0;
Serial.print("Sending: temp=");
Serial.print(fakeTemp);
Serial.print(", hum=");
Serial.println(fakeHum);
postSensorData(fakeTemp, fakeHum);
delay(30000); // Send every 30 seconds
}
WiFi Manager — Auto-Configure WiFi
Instead of hardcoding credentials, WiFiManager lets the user input WiFi settings via a captive portal:
#include <WiFiManager.h> // Install: "WiFiManager" by tzapu
void setup() {
Serial.begin(115200);
WiFiManager wifiManager;
// Will launch AP "AutoConnectAP" if no WiFi saved
// Connect phone to this AP, browser opens config portal
if (!wifiManager.autoConnect("AutoConnectAP", "password123")) {
Serial.println("Failed to connect — restarting");
delay(3000);
ESP.restart();
}
Serial.println("Connected via WiFiManager!");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
}
void loop() {}
Install: Library Manager → search "WiFiManager" by tzapu → Install.
This is the professional way to handle WiFi credentials in production devices — no hardcoded passwords.
Scan Available Networks
#include <WiFi.h>
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
Serial.println("Scanning for WiFi networks...");
int found = WiFi.scanNetworks();
if (found == 0) {
Serial.println("No networks found");
} else {
for (int i = 0; i < found; i++) {
Serial.print(i + 1);
Serial.print(". ");
Serial.print(WiFi.SSID(i));
Serial.print(" (");
Serial.print(WiFi.RSSI(i));
Serial.print(" dBm)");
Serial.println(WiFi.encryptionType(i) == WIFI_AUTH_OPEN ? " [OPEN]" : " [SECURED]");
}
}
}
void loop() {}
Simulate on Wokwi
Wokwi supports ESP32 WiFi simulation. The virtual Wokwi-GUEST network is always available:
const char* ssid = "Wokwi-GUEST";
const char* password = ""; // Open network in Wokwi
This lets you test all WiFi code including HTTP requests before touching real hardware.
See the Wokwi simulator guide for setup.
Troubleshooting
"Connection failed" after many attempts:
- Verify SSID and password (case-sensitive)
- Check if router is on 2.4 GHz — ESP32 doesn't support 5 GHz
- Move ESP32 closer to the router during testing
- Try connecting phone to confirm the network is reachable
IP address is 0.0.0.0:
- DHCP failed — your router may have run out of addresses
- Try assigning a static IP:
WiFi.config(IPAddress(192,168,1,200), gateway, subnet);
Web server works on local network but not from internet:
- You need port forwarding on your router (not recommended for security)
- Better approach: use MQTT broker or cloud services (ThingSpeak, Adafruit IO)
HTTPClient SSL/HTTPS errors:
- Add root CA certificate, or disable SSL verification (not secure):
http.begin("https://example.com/api"); // OR for testing only: WiFiClientInsecure client; client.setInsecure(); http.begin(client, "https://example.com/api");
ESP32 reboots randomly during WiFi use:
- Power issue: USB power can't supply peak WiFi current (~500 mA bursts)
- Add 100µF capacitor between 3.3V and GND near the ESP32
- Use a good USB cable (not a cheap charging-only cable)
Frequently Asked Questions (FAQ)
What frequency WiFi does ESP32 support? 2.4 GHz only. 5 GHz is not supported. Check your router settings — if you have a "combined" network showing one SSID, make sure 2.4 GHz band is enabled.
Can ESP32 connect to a WiFi network with a hidden SSID? Yes. Use WiFi.begin(ssid, password, channel, bssid, connect) with the BSSID (MAC address) of the access point.
How many clients can connect to the ESP32 access point? Maximum 4 clients simultaneously in AP mode.
What is the range of ESP32 WiFi? Typically 30–50 meters indoors, up to 100+ meters outdoors. An external antenna (via U.FL connector) extends range significantly.
Can ESP32 work as both a WiFi client and access point at the same time? Yes. Set WiFi.mode(WIFI_AP_STA) to enable both modes simultaneously. This is used for configuration portals that still maintain internet connectivity.
Related Guides
- ESP32 vs Arduino — When to choose ESP32 over Arduino
- DHT11 Sensor — Send sensor data over WiFi
- Wokwi Simulator Guide — Test ESP32 WiFi in browser
- Arduino Relay Module — Remote relay control via WiFi