Random Nerd Tutorials
Shares

ESP32/ESP8266 MicroPython Web Server – Control Outputs

Shares

Learn how to build a web server to control the ESP32 or ESP8266 outputs using MicroPython framework. As an example we’ll build a web server with ON and OFF buttons to control the on-board LED of the ESP32/ESP8266. We’ll use sockets and the Python socket API.

esp32 web server with micropython on smartphone

Prerequisites

To program the ESP32 and ESP8266 with MicroPython, we use uPyCraft IDE as a programming environment. Follow the next tutorials to install uPyCraft IDE and flash MicroPython firmware on your board:

If this is your first time dealing with MicroPython you may find these next tutorials useful:

Parts required

For this tutorial you need an ESP32 or ESP8266 board:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Preparing the Files

Connect the ESP32 or ESP8266 board to your computer. Open uPyCraft IDE, and go to Tools > Serial and select the serial port.

uPyCraft IDE selecting serial port

You should see the files on the ESP32/ESP8266 board on the device folder. By default, when you burn MicroPython firmware, a boot.py file is created.

For this project you’ll need a boot.py file and a main.py file. The boot.py file has the code that only needs to run once on boot. This includes importing libraries, network credentials, instantiating pins, connecting to your network, and other configurations.

The main.py file will contain the code that runs the web server to serve files and perform tasks based on the requests received by the client.

Creating the main.py file on your board

1. Press the “New file” button to create a new file.

2. Press the “Save file” button to save the file in your computer.

3. A new window opens, name your file main.py and save it in your computer:

4. After that, you should see the following in your uPyCraft IDE (the boot.py file in your device and a new tab with the main.py file):

5. Click the “Download and run” button to upload the file to your ESP board:

6. The device directory should now load the main.py file. Your ESP has the file main.py stored.

uPycraft IDE creating main.py file

boot.py

Copy the following code to the ESP32/ESP8266 boot.py file.

As mentioned previously, we create our web server using sockets and the Python socket API. The official documentation imports the socket library as follows:

try:
  import usocket as socket
except:
  import socket

We need to import the Pin class from the machine module to be able to interact with the GPIOs.

from machine import Pin

After importing the socket library, we need to import the network library. The network library allows us to connect the ESP32 or ESP8266 to a Wi-Fi network.

import network

The following lines turn off vendor OS debugging messages:

import esp
esp.osdebug(None)

Then, we run a garbage collector:

import gc
gc.collect()

A garbage collector is a form of automatic memory management. This is a way to reclaim memory occupied by objects that are no longer in used by the program. This is useful to save space in the flash memory.

The following variables hold your network credentials:

ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'

You should replace the words highlighted in red with your network SSID and password, so that the ESP is able to connect to your router.

Then, set the ESP32 or ESP8266 as a Wi-Fi station:

station = network.WLAN(network.STA_IF)

After that, activate the station:

station.active(True)

Finally, the ESP32/ESP8266 connects to your router using the SSID and password defined earlier:

station.connect(ssid, password)

The following statement ensures that the code doesn’t proceed while the ESP is not connected to your network.

while station.isconnected() == False:
  pass

After a successful connection, print network interface parameters like the ESP32/ESP8266 IP address – use the ifconfig() method on the station object.

print('Connection successful')
print(station.ifconfig())

Create a Pin object called led that is an output, that refers to the ESP32/ESP8266 GPIO2:

led = Pin(2, Pin.OUT)

main.py

Copy the following code to the ESP32/ESP8266 main.py file.

The script starts by creating a function called web_page(). This function returns a variable called html that contains the HTML text to build the web page.

def web_page():

The web page displays the current GPIO state. So, before generating the HTML text, we need to check the LED state. We save its state on the gpio_state variable:

if led.value() == 1:
  gpio_state="ON"
else:
  gpio_state="OFF"

After that, the gpio_state variable is incorporated into the HTML text using “+” signs to concatenate strings.

html = """<html><head> <title>ESP Web Server</title> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,"> <style>html{font-family: Helvetica; display:inline-block; margin: 0px auto; text-align: center;}
h1{color: #0F3376; padding: 2vh;}p{font-size: 1.5rem;}.button{display: inline-block; background-color: #e7bd3b; border: none; 
border-radius: 4px; color: white; padding: 16px 40px; text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}
.button2{background-color: #4286f4;}</style></head><body> <h1>ESP Web Server</h1> 
<p>GPIO state: <strong>""" + gpio_state + """</strong></p><p><a href="/?led=on"><button class="button">ON</button></a></p>
<p><a href="/?led=off"><button class="button button2">OFF</button></a></p></body></html>"""

Creating a socket server

After creating the HTML to build the web page, we need to create a listening socket to listen for incoming requests and send the HTML text in response. For a better understanding, the following figure shows a diagram on how to create sockets for server-client interaction:

python socket server and client

Create a socket using socket.socket(), and specify the socket type. We create a new socket object called s with the given address family, and socket type. This is a STREAM TCP socket:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Next, bind the socket to an address (network interface and port number) using the bind() method. The bind() method accepts a tupple variable with the ip address, and port number:

s.bind(('', 80))

In our example, we are passing an empty string ‘ ‘ as an IP address and port 80. In this case, the empty string refers to the localhost IP address (this means the ESP32 or ESP8266 IP address).

The next line enables the server to accept connections; it makes a “listening” socket. The argument specifies the maximum number of queued connections. The maximum is 5.

s.listen(5)

In the while loop is where we listen for requests and send responses. When a client connects, the server calls the accept() method to accept the connection. When a client connects, it saves a new socket object to accept and send data on the conn variable, and saves the client address to connect to the server on the addr variable.

conn, addr = s.accept()

Then, print the address of the client saved on the addr variable.

print('Got a connection from %s' % str(addr))

The data is exchanged between the client and server using the send() and recv() methods.

The following line gets the request received on the newly created socket and saves it in the request variable.

request = conn.recv(1024)

The recv() method receives the data from the client socket (remember that we’ve created a new socket object on the conn variable). The argument of the recv() method specifies the maximum data that can be received at once.

The next line simply prints the content of the request:

print('Content = %s' % str(request))

Then, create a variable called response that contains the HTML text returned by the web_page() function:

response = web_page()

Finally, send the response to the socket client using the send() method:

conn.send(response)

In the end, close the created socket.

conn.close()

Testing the Web Server

Upload the main.py and boot.py files to the ESP32/ESP8266. Your device folder should contain two files: boot.py and main.py.

After uploading the files, press the ESP EN/RST on-board button.

esp32 enable button

After a few seconds, it should establish a connection with your router and print the IP address on the Shell.

Open your browser, and type your ESP IP address you’ve just found. You should see the web server page as shown below.

esp32 web server control outputs

When you press the ON button, you make a request on the ESP IP address followed by /?led=on. The ESP32/ESP8266 on-board LED turns on, and the GPIO state is updated on the page.

Note: some ESP8266 on-board LEDs turn on the LED with an OFF command, and turn off the LED with the ON command.

web server on smartphone and esp32

When you press the OFF button, you make a request on the ESP IP address followed by /?led=off. The LED turns off, and the GPIO state is updated.

Note: to keep this tutorial simple, we’re controlling the on-board LED that corresponds to GPIO 2. You can control any other GPIO with any other output (a relay, for example) using the same method. Also, you can modify the code to control multiple GPIOs or change the HTML text to create a different web page.

Wrapping Up

This tutorial showed you how to build a simple web server with MicroPython firmware to control the ESP32/ESP8266 GPIOs using sockets and the Python socket library. If you’re looking for a web server tutorial with Arduino IDE, you can check the following resources:

If you’re looking for more projects with the ESP32 and ESP8266 boards, you can take a look at the following:

We hope you’ve found this article about how to build a web server with MicroPython useful. We’ll be adding more tutorials about MicroPython very soon. So, stay tuned and subscribe the RNT blog to get access to our free resources!


Learn ESP32 with Arduino IDE

This our complete guide to program the ESP32 with Arduino IDE, including projects, tips, and tricks! The registrations are open, so SIGN UP NOW »

Leave a Comment:

Add Your Reply

⏰ Registrations are open ⏰
Sign up for "Learn ESP32 with Arduino IDE" Course