ESP32 Web Server: Control an LED from Your Browser! [Arduino IDE]

Want to control an LED from your browser using an ESP32? In this step-by-step guide, we’ll explore how to create a simple ESP32 web server to control an LED using the Arduino IDE. We will also look at how to move the HTML code to a separate file using SPIFFS for cleaner code.

Keep reading!

Table of Contents

    Wiring the LED

    In case you don’t want to control the built-in LED of your ESP32 development board or your board doesn’t have one, you can hook up an external LED as follows:

    ESP32 Web Server LED Wiring diagram

    Simply connect the LED’s cathode (-) to a GND pin on the ESP32 and connect the anode (+) via a 220Ω resistor to a GPIO pin of your choice.

    If your board has a built-in LED, it is typically hooked up to GPIO 2 or 8.

    Setting Up the Arduino IDE

    You can skip this step if you’ve already set up the Arduino IDE to work with your ESP32.

    Before we can start with programming, we need to install the ESP32 in the Arduino IDE.

    To achieve that, you must paste the following board URL under File > Preferences > Settings > Additional boards manager URLs.

    https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json

    Next, click on Tools > Board > Boards Manager… and search and install the esp32 boards manager by Espressif Systems.

    This should be it! If you need further assistance, you can follow this detailed guide.

    ESP32 Web Server: Serving HTML Directly from Sketch

    We can serve HTML code via a web server on the ESP32 using the following sketch:

    #include <WiFi.h>
    #include <WebServer.h>
    
    const char* ssid = "YOUR_SSID";
    const char* password = "YOUR_PASSWORD";
    
    WebServer server(80);
    const int ledPin = 2;
    
    const char* html = "<!DOCTYPE html>"
    "<html>"
    "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"
    "<style>body { text-align: center; font-family: Arial; padding-top: 50px; }"
    "button { padding: 15px 30px; font-size: 16px; margin: 10px; }</style>"
    "</head><body>"
    "<h1>ESP32 LED Control</h1>"
    "<p><a href='/on'><button>Turn ON</button></a></p>"
    "<p><a href='/off'><button>Turn OFF</button></a></p>"
    "</body></html>";
    
    void handleRoot() {
      server.send(200, "text/html", html);
    }
    
    void handleOn() {
      digitalWrite(ledPin, HIGH);
      server.sendHeader("Location", "/");
      server.send(303);
    }
    
    void handleOff() {
      digitalWrite(ledPin, LOW);
      server.sendHeader("Location", "/");
      server.send(303);
    }
    
    void setup() {
      Serial.begin(115200);
      pinMode(ledPin, OUTPUT);
    
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500); Serial.print(".");
      }
      Serial.println("");
      Serial.println("WiFi connected: ");
      Serial.println(WiFi.localIP());
    
      server.on("/", handleRoot);
      server.on("/on", handleOn);
      server.on("/off", handleOff);
      server.begin();
      Serial.println("HTTP server started");
    }
    
    void loop() {
      server.handleClient();
    }

    ESP32 Web Server: Serving HTML separately from SPIFFS

    Instead of embedding the HTML in your sketch, you can move it to a separate file and store it in the ESP32’s flash memory using SPIFFS.

    What is SPIFFS?

    SPIFFS (Serial Peripheral Interface Flash File System) is a lightweight filesystem created for microcontrollers with SPI flash chips, just like the ESP32. It allows you to store files – like HTML, CSS, or images – directly in your board’s onboard flash memory. This way, you can keep your web content modular and your Arduino sketch clean.

    Step 1: Install SPIFFS Uploader Tool

    Note: The tool we are about to use currently only supports the Arduino IDE 1.x.x. If you are using the Arduino IDE version 2.x.x, you’ll need to manually upload your external files using mkspiffs and esptool. In that case, follow this guide.

    To upload separate files to your ESP32’s flash memory, you’ll need a plugin for the Arduino IDE.

    Download the ESP32 filesystem uploader plugin from GitHub.
    Then, unpack it and place it inside the tools/ folder in your Arduino sketchbook directory. You can find the location of that directory in the Arduino IDE under File > Preferences > Settings > Sketchbook location:

    ESP32 Arduino IDE Sketchbook Location

    If the tools/ folder doesn’t already exist in this location, create it yourself.

    Next, restart the Arduino IDE. You should now see the ESP32 Sketch Data Upload option under Tools.

    ESP32 SPIFFS Sketch Data Upload Tool in Arduino IDE

    Step 2: Add the HTML file

    Now that the SPIFFS uploader tool is installed, we can start adding an index.html file to the sketch. To be able to access separate files using SPIFFS, you need to put your files into a folder called data/ in your project directory.

    Here’s what the folder structure should look like:

    YourProject/
    ├── YourSketch.ino
    └── data/
        └── index.html

    Inside the data/ folder, place your HTML file that should be served via your ESP32 web server.

    Here’s an example HTML code that shows a title and two buttons for switching the LED on or off:

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>ESP32 LED Control</title>
      <style>
        body { font-family: Arial; text-align: center; padding-top: 50px; }
        button { padding: 15px 30px; font-size: 16px; margin: 10px; }
      </style>
    </head>
    <body>
      <h1>ESP32 LED Control</h1>
      <p><a href="/on"><button>Turn ON</button></a></p>
      <p><a href="/off"><button>Turn OFF</button></a></p>
    </body>
    </html>

    After setting up the HTML file, you can upload it to your board using the ESP32 Sketch Data Upload tool under Tools > ESP32 Sketch Data Upload.

    Step 3: SPIFFS ESP32 Web Server Sketch

    If we now want to use the HTML file we just uploaded, we need to use the SPIFFS.h library in our sketch to access the file. Here’s an example sketch of the LED controller using the separate index.html file:

    #include <WiFi.h>
    #include <WebServer.h>
    #include <SPIFFS.h>
    
    const char* ssid = "YOUR_SSID";
    const char* password = "YOUR_PASSWORD";
    
    WebServer server(80);
    const int ledPin = 2;
    
    void handleRoot() {
      File file = SPIFFS.open("/index.html", "r");
      if (file) {
        server.streamFile(file, "text/html");
        file.close();
      } else {
        server.send(404, "text/plain", "File Not Found");
      }
    }
    
    void handleOn() {
      digitalWrite(ledPin, HIGH);
      server.sendHeader("Location", "/");
      server.send(303);
    }
    
    void handleOff() {
      digitalWrite(ledPin, LOW);
      server.sendHeader("Location", "/");
      server.send(303);
    }
    
    void setup() {
      Serial.begin(115200);
      pinMode(ledPin, OUTPUT);
    
      if (!SPIFFS.begin(true)) {
        Serial.println("SPIFFS Mount Failed");
        return;
      }
    
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500); Serial.print(".");
      }
      Serial.println("");
      Serial.println("WiFi connected: ");
      Serial.println(WiFi.localIP());
    
      server.on("/", handleRoot);
      server.on("/on", handleOn);
      server.on("/off", handleOff);
      server.begin();
      Serial.println("HTTP server started");
    }
    
    void loop() {
      server.handleClient();
    }

    Wrapping Up

    Creating a web server on the ESP32 to control an LED is an excellent introduction to IoT and web-based control applications. Once you master this, you can expand to control multiple GPIOs, add sliders, integrate sensors, or build a whole dashboard.

    Next, check out how to assign a static IP address to your ESP32, so that it is always available under the same IP!


    Share your experience with ESP32 Web Servers in the comments!

    Thanks for reading, happy making!

    Links marked with an asterisk (*) are affiliate links which means we may receive a commission for purchases made through these links at no extra cost to you. Read more on our Affiliate Disclosure Page.

    Share this article

    Leave a Reply

    Your email address will not be published. Required fields are marked *