How to Build a Simple ESP32 Web Server to Control an LED

One of the very first projects every ESP32 beginner should build demonstrates the chip’s biggest advantage over an Arduino Uno: built-in Wi-Fi functionality. In this tutorial, you will turn an LED on and off from any phone or laptop on the same network. Consequently, you will host a simple webpage directly on the ESP32 itself without installing an extra app, setting up a cloud account, or adding a separate Wi-Fi module.
What You Will Learn
- Connect your ESP32 board directly to your local Wi-Fi network.
- Run a lightweight web server on the ESP32 chip using Arduino IDE.
- Create intuitive HTML buttons and handle web requests in your code.
- Toggle a GPIO pin reliably based on incoming HTTP requests.
Project Prerequisites
- Difficulty: Beginner
- Time Required: 20–30 minutes
- Estimated Cost: Under $5 (if you already own an ESP32 board)
Components Needed
- 1x ESP32 development board (e.g., ESP32 DevKit V1)
- 1x LED (any color)
- 1x 220Ω resistor
- 1x Breadboard and jumper wires
- 1x USB-C or Micro-USB cable
Circuit Wiring Diagram
Before uploading the code, wire your components as outlined in the reference table below. First, connect the longer leg (anode) of the LED through the 220Ω resistor to GPIO 2. Next, connect the shorter leg (cathode) directly to a GND pin.
| ESP32 Pin | Connected Component |
| GPIO 2 | 220Ω resistor → LED anode (+) |
| GND | LED cathode (–) |
Pro Tip: Most ESP32 DevKit boards feature a built-in LED on GPIO 2. Therefore, you can test this code immediately without external wiring if you want to see the onboard LED respond.
Step-by-Step Setup Guide
Step 1: Install the ESP32 Board Package
- Open Arduino IDE and navigate to File → Preferences.
- Paste the following URL into the Additional Board Manager URLs field:
[https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json](https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json) - Go to Tools → Board → Board Manager, search for esp32, and install the official package by Espressif Systems.
- Select your specific board model under Tools → Board → ESP32 Arduino.
Step 2: Wire the Hardware Circuit
Follow the table provided above to complete your wiring. Furthermore, double-check that your resistor sits in series with the LED to avoid damaging the GPIO pin.
Step 3: Upload the ESP32 Code
Copy the full sketch below into your Arduino IDE, update the network credentials with your Wi-Fi name and password, and upload it to your board.
C++
#include <WiFi.h>
const char* ssid = "YOUR_WIFI_NAME";
const char* password = "YOUR_WIFI_PASSWORD";
WiFiServer server(80);
const int ledPin = 2;
String header;
String ledState = "off";
void setup() {
Serial.begin(115200);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
server.begin();
}
void loop() {
WiFiClient client = server.available();
if (client) {
String currentLine = "";
while (client.connected()) {
if (client.available()) {
char c = client.read();
header += c;
if (c == '\n') {
if (currentLine.length() == 0) {
if (header.indexOf("GET /led/on") >= 0) {
ledState = "on";
digitalWrite(ledPin, HIGH);
} else if (header.indexOf("GET /led/off") >= 0) {
ledState = "off";
digitalWrite(ledPin, LOW);
}
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();
client.println("<!DOCTYPE html><html><body>");
client.println("<h1>ESP32 LED Control - iotjournal.net</h1>");
client.println("<p>LED is currently: " + ledState + "</p>");
client.println("<p><a href=\"/led/on\"><button>Turn ON</button></a></p>");
client.println("<p><a href=\"/led/off\"><button>Turn OFF</button></a></p>");
client.println("</body></html>");
client.println();
break;
} else {
currentLine = "";
}
} else if (c != '\r') {
currentLine += c;
}
}
}
header = "";
client.stop();
}
}
Step 4: Obtain the ESP32 IP Address
Open the Serial Monitor by clicking Tools → Serial Monitor and set the baud rate to 115200. Once the board connects to your Wi-Fi network, it prints a local IP address (e.g., [http://192.168.1.42](http://192.168.1.42)).
Step 5: Control Your LED from a Browser
- Connect your smartphone, tablet, or laptop to the same Wi-Fi network as the ESP32.
- Enter the assigned IP address directly into your web browser address bar.
- Click the Turn ON or Turn OFF buttons on the web interface to switch the LED state instantly.
How It Works
The ESP32 connects to your Wi-Fi router and continuously listens for incoming HTTP requests on port 80. When you click a button in your browser, it sends a GET request such as /led/on. The Arduino code reads this incoming data line by line, checks for specific routes, switches the GPIO pin state accordingly, and serves an updated HTML webpage to reflect the new state.
Troubleshooting Common Issues
- Board fails to connect to Wi-Fi: Verify your SSID and password details. Additionally, ensure you connect to a 2.4 GHz network because the ESP32 does not support 5 GHz Wi-Fi.
- Web page fails to load: Confirm that your phone or computer shares the exact same network connection as your micro-controller.
- LED remains off: Check the orientation of your component leads. The longer anode leg must connect directly to the resistor.
- Serial Monitor outputs garbled text: Set your Serial Monitor baud rate setting to 115200 to match the code setup.
Next Steps and Project Extensions
- Extend your code to control multiple LEDs or relays using separate routes (e.g.,
/led1/on,/led2/on). - Integrate live sensor readings like temperature or humidity directly onto the web dashboard.
- Enhance the basic interface using modern CSS styles and responsive design elements.
- Check out our related guide on DHT22 Temperature and Humidity Sensor Integration for your next smart home step, or review the Official Espressif Hardware Documentation to explore pinouts in detail.
Published on iotjournal.net — part of the ‘Practical ESP32 Projects’ series.



