ESP8266 Web Server: create UI using HTML Pages

This ESP8266 tutorial covers how to create an HTML User Interface to interact with an ESP8226 device developing an ESP8266 Web server.

Problem: We want to build an HTML user interface provided by the ESP822 to interact with it. Through the ESP8266 we will a user interface to send commands to the device to control outputs PIN or to visualize sensor readings.

Where to use HTML User interface with ESP8266

Every time we want to send commands to the ESP8266 using an HTML interface.

A classic example is building an HTML interface so that a user can interact with remote peripherals, such as turning on or off a remote LED, or check the sensor readings (temperature, humidity, pressure and so on). This UI generated by the HTML pages are available through a Web browser running on the ESP8266.

There are also other scenario where we need to implement a Web User interface to interact with the ESP8266. Imagine for example we want to configure the device. Therefore we have to develop an HTML interface so that an user can interact with it. In this case, the ESP8266 should act as an access point so that we can use our smart phone.

By the way, if you want to know more about IoT devices and smartphone integration you can read how to connect the ESP32 to a smartphone.

What we will learn

  • How to implement a Web server running on an ESP8266
  • Configuring the ESP8266 as an Access point
  • Using the Web server to server HTML
  • How to develop a Web user interface using ESP8266
  • Sending commands to the ESP8266 through the Web server

Project Components

  • ESP8266 or a compatible device
  • one LED
  • BME280 or BMP280 sensor
  • a little knowledge about HTML

Implementing an ESP8266 Web server

Firstly, it is necessary to implement the Web server on ESP8266. The code is shown below:

#include <ESP8266WebServer.h>
ESP8266WebServer server(80);
void setup() {
  server.on("/", handle_home_page);
  server.on("/led/on", handle_led_on);
  server.on("/led/off", handle_led_off);
void loop() {
}Code language: C++ (cpp)

Let us describe the code:

  • Line 3 defines a Web server listening on port 80. If you want to change the port simply change this value.
  • In the setup method, the code defines the URI that the ESP8266 has to handle and the corresponding method:
    • / this is the home page while handle_home_page is the method to invoke
    • /led/on is the URI we will use to turn on the LED
    • /led/off is the URI we will use to turn off the LED
  • Line 9 we start the Web server
  • Line 13, we handle the incoming HTTP request.

Smart Home tutorial: ESP8266, Alexa and Amazon Echo
How to invoke HTTPS Rest JSON API using ESP8266: ClimaCell API

Developing a UI Web interface using HTML Serving the HTML

When invoking the home page, the ESP8266 has to serve an HTML page that will hold the senosr readings (BME 280 sensor). Firstly, it is necessary to build the HTML page. This is trivial, therefore we show the code and the result:

    <title>ESP8266 Page</title> 
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>  
       h1 {text-align:center; }     
       td {font-size: 50%; padding-top: 30px;}     
       .temp {font-size:150%; color: #FF0000;}     
       .press {font-size:150%; color: #00FF00;}     
       .hum {font-size:150%; color: #0000FF;}  
     <p>ESP8266 Sensor Page</p>    
     <div id='div1'>        
           <td>Temperature</td><td class='temp'>%.2f</td>          
           <td>Pressure</td><td class='press'>%.2f</td>   
           <td>Humidity</td><td class='hum'>%.2f</td>  
</html>Code language: HTML, XML (xml)

The result is:

Web server HTML page

Implementing the HTML UI page on ESP8266

Then, it is necessary to implement the method handle_home_page:

void handle_home_page() {
  temperature = bme.readTemperature();
  humidity = bme.readHumidity();
  pressure = bme.readPressure() / 100.0F;
  char body[1024];
  sprintf(body,  "<html> <head>   <title>ESP8266 Page</title> <meta name='viewport' content='width=device-width, initial-scale=1.0'>  <style>     h1 {text-align:center; }     td {font-size: 50%; padding-top: 30px;}     .temp {font-size:150%; color: #FF0000;}     .press {font-size:150%; color: #00FF00;}     .hum {font-size:150%; color: #0000FF;}   </style> </head>  <body>    <h1>ESP8266 Sensor Page</h1>    <div id='div1'>        <table>           <tr>            <td>Temperature</td><td class='temp'>%.2f</td>          </tr>          <tr>   <td>Pressure</td><td class='press'>%.2f</td>   </tr>  <tr>   <td>Humidity</td><td class='hum'>%.2f</td>  </tr> </div> </body>  </html>", bme.readTemperature(), (bme.readPressure() / 100.0F), bme.readHumidity());
  server.send(200, "text/html", body);
}Code language: HTML, XML (xml)

In this example, we read the three values using BME280 Sensor:

  • temperature
  • humidity
  • pressure

The interesting part to notice is the last line where we send back the response to the client using an HTTP status code 200 and setting the content type as text/html.

Handling the command to turn LED on or off through the HTML UI

Once, we have developed the home page to the server when a client connects to the ESP8266 Web server, the next step is implementing the method to turn the LED on. Before, we have defined:

server.on("/led/on", handle_led_on);Code language: C++ (cpp)

Then, it is necessary to implement the method handle_led_on. Therefore, in this method, we turn the LED on. If you want to see the schematic, please refer to the diagram in the next paragraph. The code is:

void handle_led_on() {
  digitalWrite(LED_PIN, HIGH);
}Code language: JavaScript (javascript)

In the same way, we can turn the LED off:

void handle_led_off() {
  digitalWrite(LED_PIN, LOW);
}Code language: JavaScript (javascript)

Using the ESP8266 as Access Point

Furthermore, in this ESP8266 tutorial, we will not connect the ESP8266 to the WiFi. Instead of using this approach, we will use the ESP8266 as Access Point. Therefore, we can connect our smartphone to the ESP8266 directly and access the Web Server running on the ESP8266. To do it let us add the following code:

#include <Arduino.h>
#include <ESP8266WiFi.h>
// WiFi AP Config
IPAddress localIp(192,168,1,1);
IPAddress gatewayIp(192,168,1,1);
IPAddress subnet(255,255,255,0);
const char *ssid="esp8266_swa";
const char *pwd="swa12345678";
void setup() {
  // Setup Wifi
  Serial.println("Initializing AP...");
  if (WiFi.softAP(ssid, pwd)) {
    Serial.println("AP ready....");
    WiFi.softAPConfig(localIp, gatewayIp, subnet);
}Code language: PHP (php)

The code above is quite simple:

  • Firstly, we define the gateway, the IP address and the subnet of the WiFi we are creating
  • Secondly, we give a name to the WiFi and the password the client must use to access the WiFi.

Finally, the code starts the WiFi and configures all the parameters described above.

Schematic ESP8266 BME280 sensor + LED

Now it is time to show the schematic used in this project to send commands to control LED and get the temperature, humidity, and pressure through the Web server running on ESP8266. The schematic is shown below:

ESP8266 with BME280 and LED and Web Server

The schematic is very simple:

  • The LED is connected to D4 pin
  • The BME280 uses I2C with 0x76 address

Code to connect ESP8266 to BME280

The code is shown below:

#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define LED_PIN D4
// BME280
Adafruit_BME280 bme;
void setup() {
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
}Code language: PHP (php)

Test the HTML Web Interface

Connecting to the ESP8266 Access point using a smartphone

Once the WiFi is configured, if we run the code above, we can connect to the WiFi named esp8266_swa. The image below shows the WiFi on the smartphone:

Connecting to the ESP8266 Web server

Now open your browser and type and you will have the following result:

ESP8266 Web server with BME280 to read temperature, pressure and humidity

That’s all!! The picture below shows the ESP8266 Web server when the client sends the command to turn on the LED:

Control LED using ESP8266 Web server

Wrapping up…

At the end of this ESP8266 tutorial, you learned how to build an ESP8266 Web server to build HTML UI pages. Using the HTML UI we can interact with the ESP8266 through the Web server. We showed how to use the Web server in two different ways:

  • sends HTML page with readings to a client
  • send commands to the ESP8266 using specific URI

Moreover, you learned how to implement an Access Point using ESP8266 so that a smartphone can connect to the WiFi managed by the ESP8266.

    1. Jon Raymond January 29, 2020
      • Francesco Azzola January 29, 2020

    Add Your Comment