ESP32 Relay Web Server

Contributors: Elias The Sparkiest
Favorited Favorite 6


The goal of this project is to have a website hosted on an ESP32 that controls any relay controlled device connected to a local network and keeps a dynamically updated state of those devices. The website must look good but more importantly, be responsive. The goal of this tutorial is to be instructive in the topics associated with each component that make up the project. Clearly it will outline the steps to get the project up and running, but it will also delve into each concept with some depth to give you more information on how this project works; with some attempt to keep you, the reader, from falling asleep. Through out this tutorial "device" is synonymous with "relay" because a relay will be controlling the device.

This is a continuation of the Infrared tripwires to automate light switching and The ESP32 Web Server blog posts. After achieving the primary goal outlined above, there will be another section added to go over how to integrate the IR tripwires as a "user" controlling the relays. Let's go over what each individual piece of the project looks like.

How - ESP32 and SPIFFS

Using an ESP32 or ESP8266 and utilizing the SPIFFS Filesystem (SPI Flash File System) library, the ESP becomes a simple computer using it's memory as a flash drive. This opens up many possibilities because we can now store and open webpage files, small images, and files for tracking states of the devices. This tutorial uses an ESP32 in place of an ESP8266 because of it's larger memory capacity. More memory increases our file size capabilities and gives the micro-controller longer life because we're not butting up against its maximum storage capacity.

Responsiveness - ESPAsync and Websockets

The ESPAsync Library includes example code which provides the basis for the tutorial's source code. The ESPAsync library, as the name suggests, manages asynchronous web requests. This is important; the website needs to handle a case in which two people are on the webpage at the same time, or when someone trips the IR tripwire while someone is on the webpage. Because the website is asynchronous by design that means it will queue requests in the background without explicit code in the Arduino sketch and can change the state of the relay and the website's indicators as requested.

"State Machine" - ArduinoJson and JSON files

The state of each device will be kept in a JSON file within the SPIFFS file system. The JSON file will be very simple and look something like this:

        "password" : "super secret password"

Alternatively a simple text file could do the same thing. So why a JSON file? JSON being a markup language is designed to organize data into parsable objects which makes the interaction with JSON files more intuitive. In addition WiFi network names and passwords can also be saved within other objects without having to modify the Arduino Sketch: that saves an upload and allows for easier modification. To parse the JSON file we'll leverage the very well written and very well documented ArduinoJson Library.

The Feel - BootStrap, CSS and Javascript

The web page's theme and its' scalability from desktop to mobile phone will be made possible with Bootstrap - a toolkit for HTML, JS, and CSS. The tutorial will outline how to keep the file size small and get the most out of the simplicity of the Bootstrap toolkit.

What's next?

You can check back here to see what's next to be updated, this will be updated as the tutorial grows. If you have any questions or suggestions, place them in the comments below.

To Do

1. Add section on Bootstrap fies: bootstrap.min.CSS and bootstrap.min.JS. What are they and what do they do?
2. Add section on the ESP32 File Structure and where files live.
3. Add section on JSON files and Arduino JSON to store data related to WiFi settings and the state of each individual relay.
4. Add section on AJAX requests and Websockets in place of straight GET requests.
5. Add relay control function to our requests.
6. Add Hardware Section for ESP32 and Relay.
7. Add trouble-shooting section to tutorial.
8. Update tutorial with the Infrared tripwires Arduino Sketch and fill in details on the hardware hookup.


Arduino Software

Library Installation

Undoubtedly the hardest part of the project is downloading and installing the libraries. There's only one way to do this and that's to install them manually. If you haven't installed a library before, then check out this helpful tutorial here. All of the links are also at the the project's Github repo here and linked in the source code (home.ino) Arduino sketch. I've also included a links to all information convered in this tutorial, including the libraries below, in Resources and Going Further.

  1. Async TCP Library for ESP32 (Github Link) - Dependency for ESPAsync below
  2. ESPAsync Web Server for ESP8266 and ESP32 (Github Link) - Asyncronous Web Request Library
  3. SPIFFS (Github Link) - Allows the user to use ESP32's Memory for file storage.
  4. ESP32 File Uploader Tool (Github Link) - Tool for uploading files onto and ESP32
  5. Arduino JSON Library (Website) - For serializing and de-serializing information.

Take special care when installing the fourth item ESP32 File Uploader Tool. This tool is not a library installed in the normal location because it's a tool specific to ESP32's hardware. For this reason it's installed within the Tools directory of the ESP32 Hardware files. Follows the instructions outlined in the link above carefully.

Download the Source Files

After installing the Libraries detailed above you can now download the source files here or clink the button below. From here you can modify a few lines within the config.json file and then move onto the Hardware section. However if you want to get down with some website modification and educate yourself on its' components then keep reading.

Webpage Files

A Brief note on CSS, JS, and HTML Files

HTML literally makes up the backbone of any website. It's a markup language (like JSON), meaning that it's purpose is to provide information on what parts of the webiste are! For example:

<h1>Press Me!</h1>

The attribute of "Press Me!" is header one: h1 (header defines text of certain size and it's purpose on the page). To give a website a common look and feel using just HTML, additional attributes have to be added to define color, size, or font.

<h1><font color="red"> Press Me! </font></h1>

There's a font color attribute in addition to the header, but how about size, or a different font? Now the website is finished, but wait, all the headers now need to be green! What an increasingly painful thing to have to change. Enter Cascading Style Sheets. CSS files live apart from the HTML files and can determine what every header file should look like in a single line of code. No need to assign attributes to every header in the HTML file itself! Simply import it at the top of your HTML file!

Easy, now let's breifly discuss Javascript. Javacript is the programming language that determines what happens when a button on the website is pressed. In this project, Javascript will change the text on the button when a button is pressed and then send requests to the ESP32 to flip on a relay. Again, import this JS file at the top of your HTML file.

Enter the Bootstrap

Bootstrap is a toolkit that provides pre-written CSS and JS files with a focus on making websites scalable to fit large and small screens. The following link will send you to the Bootstrap download webpage. Scroll down to the Source Files section and click download.

After downloading the Bootstrap source files and unzipping them, there are two folders, one labeled CSS (Cascading Style Sheets) and another labeled JS (Javascript). Ignore any file with the following modifier in their names:

  • grid
  • reboot
  • map
  • bundle

.....and locate the files labeled bootstrap.min.js and bootstrap.min.css. These files are the "minified" versions of the CSS or JS files found in the same folder, but have had all of the white spaces removed to decrease the file size. Just how much?

alt text
"Minified" CSS vs. regular CSS

alt text
"Minified" JS vs. regular JS

A saving of over 40KB - 70KB per file will make a huge difference in the size impact on the ESP32. The rest of these files can be ignored for this project. The following button links to a website that offers Bootstrap CSS files with different thematic colors. For example, in the image below is the "Solar" theme (based on the popular Text Editor coloring scheme) - about half way down the webpage. Simply click download and get the bootstrap.min.css file which can/will replace the CSS source file downloaded from Bootstrap's web page.

alt text
Solar Theme

To help give context to this project, here is the HTML for the website pictured above, which includes imports of the Bootstrap JS and CSS files at the top, lines for button creations, and the title bar at the top.

<!DOCTYPE html>
<html lang="en">

        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

        <!-- Bootstrap CSS -->
        <link rel="stylesheet" href="bootstrap/bootstrap.min.css" media="screen"> 

        <script src="jquery/jquery.min.js"></script>
        <script src="bootstrap/bootstrap.min.js"></script>
        <script src="relay_scripts.js"></script>



    <div class="jumbotron jumbotron-fluid" style="text-align:center">
      <h1 class="text-primary">Faux Solar Hub</h1>

    <!-- Buttons ================================================== -->
    <div class="container" style="text-align:center">
        <h5>---  Relays  ---</h5>
        <div class="btn-group-lg " role="group" aria-label="Relay Buttons">
            <button type="button btn-lg" class="btn btn-primary btn-lg" id="relay1" data-toggle="buttons">Off</button>
            <button type="button btn-lg" class="btn btn-secondary btn-lg" data-toggle="buttons" id="relay2">Off</button>
        <div class="btn-group-lg" role="group" aria-label="Relay Buttons">
            <button type="button btn-lg" class="btn btn-warning btn-lg" data-toggle="buttons" id="relay3">Off</button>
            <button type="button btn-lg" class="btn btn-danger btn-lg" data-toggle="buttons"  id="relay4">Off</button>

    <div class="container" style="text-align:center">
        <button type="button btn-lg" class="btn btn-success btn-block" data-toggle="buttons" id="totalControl">All On</button>


ESP32 File Structure

So where do all of these files live?

Hardware Assembly - ESP32 Web Server and Quad relay

Hardware for the web server:

The parts I'm using for this part of the project are the following (not listed is the lamp).

SparkFun Thing Plus - ESP32 WROOM

SparkFun Thing Plus - ESP32 WROOM


SparkFun Qwiic Quad Relay

1 Retired
Qwiic Cable - 200mm

Qwiic Cable - 200mm


Hardware Hookup

Here we get to cheat a bit because we're using Qwiic capable boards. Power needs to be provided to the ESP32, to the relays on the Qwiic Quad Relay, to the IC on the Qwiic Quad Relay, and an I2C connection needs to be made as well. Wall warts are providing power to both the relays on the Qwiic Quad Relay and to the ESP32 in the image below. Then, to provide power and establish a connection over I2C between the Qwiic Quad Relay and the ESP32, a Qwiic cable is used. No soldering necessary, very very nice.

This image shows a picture of SparkFun's ESP32 thing Plus and Quad Relay connected together with a Qwiic connector, each being powered through a wall wart.

Not listed is the connection from the relay to the lamp. First, a short review on relays.

How does a relay work?

Simply put, relays are switches. However, they are switches utilizing the magnetic property of electricity to allow the switch to be separate from what flips it. This is the root of what makes them so special - utilizing a low voltage system (3.3V in this case) a person can control the electricity coming out of the wall and to a device like a lamp! Relays are differentiated by how much voltage is needed to flip the switch, and how much power can travel across the switch when it's flipped (some combination of voltage and current). The relays on the Qwiic Quad relay can handle five amps at 250V AC and requires at least 3.3V to flip the switch.

Lamp hookup

To hookup the lamp to the Qwiic Quad Relay, one of the connections from the lamp will have to be broken so that it can later be closed by the relay when we turn it on. To do that, cut one side of the cable and then strip the cable to expose the protected wire underneath.

Cutting Cable

Now peel the wire apart and strip the two ends.

Strip Wire Ends

Put one of the ends in the Common (COM) input of the screw terminal and the other end in the Normally Open (NO) input. The common input is the center of our switch, and the normally open input is the end of the switch that will be closed when the switch is flipped. The image below should help clear any confusion.

SPDT Switch

That's it!

Hardware Assembly - Infrared Trip Wire

Hardware for the Infrared Tripwires:

Resistor Kit - 1/4W (500 total)

Resistor Kit - 1/4W (500 total)

Jumper Wires - Connected 6" (M/M, 20 pack)

Jumper Wires - Connected 6" (M/M, 20 pack)

SparkFun ESP8266 Thing - Dev Board

SparkFun ESP8266 Thing - Dev Board

IR Receiver Diode - TSOP38238

IR Receiver Diode - TSOP38238

Transistor - NPN, 50V 800mA (BC337)

Transistor - NPN, 50V 800mA (BC337)

LED - Infrared 950nm

LED - Infrared 950nm


This image shows a Fritzing diagram that outlines the circuits connections.

Resources and Going Further