ESP32 Web Server

Introduction


In this endeavor, you will construct an independent web server utilizing an ESP32 to manage LED outputs. The programming will be done using the Arduino IDE. The resulting web server is designed to be mobile-responsive and accessible through any browser-enabled device on the local network. This guide will walk you through the process of creating the web server and provide a step-by-step explanation of the code functionality.


To delve deeper into the ESP32, check out the ” Basic ESP32 ” available at https://www.oceanlabz.in/category/learn/basic-esp32/.

What is a web server and how does it operate?


A web server is essentially a storage and processing unit where web pages are kept and handled before being delivered to web clients, typically web browsers on computers or mobile devices. Communication between a web client and a web server occurs via the Hypertext Transfer Protocol (HTTP).

Here’s how it works: When a client (such as a web browser) wants to access a specific web page, it sends an HTTP request to the web server. The server then responds by sending back the requested web page content, or alternatively, an error message (like the common 404 Error) if the requested page cannot be found.

Soft Access Point (AP) mode

In Soft Access Point (AP) mode, the ESP32 acts like a WiFi router, creating its own WiFi network. It doesn’t connect to a wired network and can handle up to five connected devices. It assigns a network name (SSID) and an IP address to the network, allowing it to serve web pages to connected devices.

Concept behind using an ESP32 web server to control things:


The concept behind using an ESP32 web server to control things is straightforward. By visiting a specific URL, we trigger an action.

When you enter a URL into a web browser, it sends a request to the web server. In this case, let’s say you enter “http://192.168.1.10/2/off“. This request tells the ESP32 to turn on the LED. The ESP32 recognizes the request, performs the action, and responds by updating the webpage to display the LED’s status as “on”.

Project Overview:

Before delving into the project details, it’s crucial to outline the functionality of our web server to enhance understanding of the subsequent steps.


Before diving into the project, it’s essential to outline the functionality of our web server. Here’s what it will do:

  1. Control inbuilt LEDs connected to the ESP32 GPIO 2.
  2. Access the ESP32 web server by typing its IP address on a browser within the local network.
  3. Instantly change the state of the LED by clicking buttons on the web server.
  4. This serves as a basic example demonstrating how to build a web server that controls outputs. You can easily replace the LEDs with a relay, or any other electronic components as needed.

Configuring the ESP32 board in the Arduino IDE.

To install the ESP32 board in the Arduino IDE, you’ll need an add-on. This add-on enables you to program the ESP32 using the Arduino IDE and its programming language. Follow one of the tutorials below to set up your Arduino IDE:

For Windows: Installing the ESP32 Board in Arduino IDE (Windows)

esp32 Web Server Code

Below is the code necessary to establish the ESP32 web server. Copy the provided code into your Arduino IDE, but refrain from uploading it immediately. Modifications are required to tailor it to your specific setup before proceeding with the upload.

#include <WiFi.h>

// Replace with your network credentials
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";

// Set the web server port number to 80
WiFiServer server(80);

// Variable to store the HTTP request
String header;

// Auxiliary variables to store the current output state
String output2State = "off";

const int output2 = 2;

// Current time
unsigned long currentTime = millis();
// Previous time
unsigned long previousTime = 0; 
// Define timeout time in milliseconds (example: 2000ms = 2s)
const long timeoutTime = 2000;

void setup() {
  Serial.begin(115200);
  // Initialize the output variables as outputs
  pinMode(output2, OUTPUT);
  
  // Set outputs to LOW
  digitalWrite(output2, LOW);
  
  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
 
  // Print local IP address and start the web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
}

void loop() {
  WiFiClient client = server.available();   // Listen for incoming clients

  if (client) {                             // If a new client connects,
    currentTime = millis();
    previousTime = currentTime;
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client

    while (client.connected() && currentTime - previousTime <= timeoutTime) {  // loop while the client's connected
      currentTime = millis();
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;

        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();

            // Turns the GPIOs on and off
            if (header.indexOf("GET /2/on") >= 0) {
              Serial.println("GPIO 2 on");
              output2State = "on";
              digitalWrite(output2, HIGH);
            } else if (header.indexOf("GET /2/off") >= 0) {
              Serial.println("GPIO 2 off");
              output2State = "off";
              digitalWrite(output2, LOW);
            }

            // Display the HTML web page
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            
            client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
            client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;");
            client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
            client.println(".button2 {background-color: #555555;}</style></head>");

            // Web Page Heading
            client.println("<body><h1>ESP32 Web Server</h1>");
            
            // Display the current state and ON/OFF buttons for GPIO 26  
            client.println("<p>GPIO 2 - State " + output2State + "</p>");
            
            // If the output26State is off, display the ON button       
            if (output2State == "off") {
              client.println("<p><a href=\"/2/on\"><button class=\"button\">ON</button></a></p>");
            } else {
              client.println("<p><a href=\"/2/off\"><button class=\"button button2\">OFF</button></a></p>");
            } 
            client.println("</body></html>");

            // The HTTP response ends with another blank line
            client.println();
            
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    
    // Clear the header variable
    header = "";
    
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}


Updating Your Network Credentials:

Make the necessary modifications in the following lines by replacing “SSID” and “password” with your specific network credentials. The code includes comments indicating where these changes should be applied.

Uploading the Code:

To activate the web server, you can now proceed with uploading the code. Follow these steps to upload the code to the ESP32:

  1. Connect your ESP32 board to your computer.
  2. In the Arduino IDE, navigate to Tools > Board, and choose your board (for instance, we’re using the ESP32 Dev Module board in this case).

  1. Choose the COM port under Tools > Port.
  2. Click on the Upload button in the Arduino IDE and wait for a few moments as the code compiles and uploads to your board.
  3. Look for the “Done uploading” message to confirm the upload process is complete.

To find the ESP IP Address:

  1. Upload the code to the ESP32.
  2. Open the Serial Monitor at a baud rate of 115200.
  3. Press the ESP32 EN button (reset).
  4. The ESP32 connects to Wi-Fi and displays its IP address on the Serial Monitor.
  5. Copy the IP address as you’ll need it to access the ESP32 web server.To access the web server:

To access the web server:

  1. Open your web browser.
  2. Paste the ESP32 IP address into the address bar.
  3. You’ll see the web server page displayed. In our example, the IP address is 192.168.1.135.

Testing the Web Server

Now, you can test your web server’s functionality by clicking the buttons to control the LED.

Simultaneously, observe the Serial Monitor to understand the background activity. For instance, when you click the button to turn GPIO 2 ON, the ESP32 receives a request on the /2/on URL.

Upon receiving the request, the ESP32 activates the LED connected to GPIO 2, subsequently updating its status on the web page.

Code description:

This code establishes a web server on an ESP32 microcontroller that controls the state of an LED connected to GPIO pin 2. Let’s break down how the code works:

Setting up Wi-Fi:

const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
WiFiServer server(80);
Replace "your_SSID" and "your_PASSWORD" with your Wi-Fi network credentials.

The code initializes a web server on port 80.

Initializing Variables:

String header;
String output2State = "off";
const int output2 = 2;
unsigned long currentTime = millis();
unsigned long previousTime = 0; 
const long timeoutTime = 2000;

Variables are declared to store HTTP request headers, LED states, GPIO pin number, and timing parameters.

Setting up GPIO Pin:

pinMode(output2, OUTPUT);
digitalWrite(output2, LOW);

GPIO pin 2 is configured as an output and initially set to a low state (LED off).

Connecting to Wi-Fi:

WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
    delay(500);
}

The ESP32 attempts to connect to the specified Wi-Fi network.

Starting the Web Server:

server.begin();

The code starts the web server.

Handling Client Requests:

WiFiClient client = server.available();

The ESP32 checks for incoming client connections.

Processing Requests:

if (client) {
    currentTime = millis();
    previousTime = currentTime;
    // Code for processing request
}

When a client connects, the ESP32 processes its request.

Generating HTTP Response:

if (header.indexOf("GET /2/on") >= 0) {
    // Code to turn LED on
} else if (header.indexOf("GET /2/off") >= 0) {
    // Code to turn LED off
}

The code checks the HTTP request header to determine the requested action (turn LED on/off).

Sending HTML Page:

client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
// Code to generate HTML page

An HTML page displaying the LED state and control buttons is sent back to the client.

Handling Client Disconnect:

client.stop();

Once the response is sent, the client is disconnected.

The code continuously listens for incoming client requests and processes them accordingly, allowing users to control the LED state via a web browser.

    Leave a Reply

    Your email address will not be published.

    Need Help?