MicroPython: ESP32/ESP8266 Relay Module Web Server (AC Appliances)

This tutorial is a step-by-step guide that covers how to build a standalone ESP32 or ESP8266 NodeMCU Web Server that controls any relay module using MicroPython firmware. We’ll create an ESP32/ESP8266 Web Server that is mobile responsive and it can be accessed with any device with a browser in your local network.

MicroPython ESP32 ESP8266 NodeMCU Relay Module Web Server AC Appliances

If you want to learn how a relay module works, read our MicroPython Guide: Relay Module with ESP32/ESP8266.

We have similar guides using Arduino IDE:

Prerequisites

To follow this tutorial you need MicroPython firmware installed in your ESP32 or ESP8266 boards. You also need an IDE to write and upload the code to your board. We suggest using Thonny IDE or uPyCraft IDE:

Learn more about MicroPython: MicroPython Programming with ESP32 and ESP8266 eBook.

Introducing Relays

A relay is an electrically operated switch and like any other switch, it that can be turned on or off, letting the current go through or not. It can be controlled with low voltages, like the 3.3V provided by the ESP32/ESP8266 GPIOs and allows us to control high voltages like 12V, 24V or mains voltage (230V in Europe and 120V in the US).

There are different relay modules with a different number of channels. You can find relay modules with one, two, four, eight and even sixteen channels. The number of channels determines the number of outputs you can control.

Relay modules with different number of channels 1, 2, 4, 8, 16 Channels

Get a relay module:

Wiring a Relay Module to the ESP32/ESP8266

Warning: in this example, we’re dealing with mains voltage. Misuse can result in serious injuries. If you’re not familiar with mains voltage ask someone who is to help you out. While programming the ESP or wiring your circuit make sure everything is disconnected from mains voltage.

Alternatively, you can use a 12V power source to control 12V appliances.

ESP32 Schematic Diagram

Connect the relay module to the ESP32 as shown in the following diagram. The diagram shows wiring for a 2-channel relay module, wiring a different number of channels is similar.

Wiring a Relay Module to the ESP32 Schematic Circuit

In this example, we’re controlling a lamp. We just want to light up the lamp occasionally, so it is better to use a normally open configuration.

We’re connecting the IN1 pin to GPIO 26, you can use any other suitable GPIO. See ESP32 GPIO Reference Guide.

ESP8266 NodeMCU Schematic Diagram

Follow the next schematic diagram if you’re using an ESP8266 NodeMCU.

Wiring a Relay Module to the ESP8266 Schematic Circuit

We’re connecting the IN1 pin to GPIO 5, you can use any other suitable GPIO. See ESP8266 NodeMCU GPIO Reference Guide.

The best ESP8266 pins to use with relays are: GPIO 5, GPIO 4, GPIO 14, GPIO 12 and GPIO 13.

MicroPython Relay Web Server Code (Script)

The code to control a relay with the ESP32 or ESP8266 is as simple as controlling an LED or any other output. In this example, as we’re using a normally open configuration, we need to send a LOW signal to let the current flow, and a HIGH signal to stop the current flow.

Control a Lamp with the ESP32 or ESP8266 NodeMCU using a Relay Module

Copy the following code to the main.py file and upload it to your board. It lights up your lamp for 10 seconds and turn it off for another 10 seconds.

# Complete project details at https://RandomNerdTutorials.com

from machine import Pin
from time import sleep

# ESP32 GPIO 26
relay = Pin(26, Pin.OUT)

# ESP8266 GPIO 5
#relay = Pin(5, Pin.OUT)

while True:
  # RELAY ON
  relay.value(0)
  sleep(10)
  # RELAY OFF
  relay.value(1)
  sleep(10)

View raw code

How the code works

Import the Pin class from the machine module to interact with the GPIOs. We also import the sleep() method from the time module to add delays.

from machine import Pin
from time import sleep

Then, we define a Pin object called relay on 26 (if you’re using an ESP32) and define it as an output.

# ESP32 GPIO 26
relay = Pin(26, Pin.OUT)

In case you’re using an ESP8266, use GPIO 5 instead. Comment the previous line and uncomment the following.

# ESP8266 GPIO 5
#relay = Pin(5, Pin.OUT)

In the while loop, send a LOW signal to light up the lamp for 10 seconds.

# RELAY ON
relay.value(0)
sleep(10)

If you’re using a normally closed configuration, send a HIGH signal to light up the lamp.

Stop the current flow by sending a HIGH signal to the relay pin. If you’re using a normally closed configuration, send a LOW signal to stop the current flow.

# RELAY OFF
relay.value(1)
sleep(10)

Control Relay Module with MicroPython Web Server

Control Relay with Web Server - MicroPython ESP32 and ESP8266

In this section, we’ve created a web server example that allows you to control a relay remotely via web server.

boot.py

Copy the following code to your boot.py file.

# Complete project details at https://RandomNerdTutorials.com

try:
  import usocket as socket
except:
  import socket

from machine import Pin
import network

import esp
esp.osdebug(None)

import gc
gc.collect()

ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'

station = network.WLAN(network.STA_IF)

station.active(True)
station.connect(ssid, password)

while station.isconnected() == False:
  pass

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

# ESP32 GPIO 26
relay = Pin(26, Pin.OUT)

# ESP8266 GPIO 5
#relay = Pin(5, Pin.OUT)

View raw code

Insert your network credentials in the following variables:

ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'

Uncomment one of the following lines accordingly to the board you’re using. By default, it’s set to use the ESP32 GPIO.

# ESP32 GPIO 26
relay = Pin(26, Pin.OUT)

# ESP8266 GPIO 5
#relay = Pin(5, Pin.OUT)

main.py

Copy the following to your main.py file.

# Complete project details at https://RandomNerdTutorials.com

def web_page():
  if relay.value() == 1:
    relay_state = ''
  else:
    relay_state = 'checked'
  html = """<html><head><meta name="viewport" content="width=device-width, initial-scale=1"><style>
  body{font-family:Arial; text-align: center; margin: 0px auto; padding-top:30px;}
  .switch{position:relative;display:inline-block;width:120px;height:68px}.switch input{display:none}
  .slider{position:absolute;top:0;left:0;right:0;bottom:0;background-color:#ccc;border-radius:34px}
  .slider:before{position:absolute;content:"";height:52px;width:52px;left:8px;bottom:8px;background-color:#fff;-webkit-transition:.4s;transition:.4s;border-radius:68px}
  input:checked+.slider{background-color:#2196F3}
  input:checked+.slider:before{-webkit-transform:translateX(52px);-ms-transform:translateX(52px);transform:translateX(52px)}
  </style><script>function toggleCheckbox(element) { var xhr = new XMLHttpRequest(); if(element.checked){ xhr.open("GET", "/?relay=on", true); }
  else { xhr.open("GET", "/?relay=off", true); } xhr.send(); }</script></head><body>
  <h1>ESP Relay Web Server</h1><label class="switch"><input type="checkbox" onchange="toggleCheckbox(this)" %s><span class="slider">
  </span></label></body></html>""" % (relay_state)
  return html

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)

while True:
  try:
    if gc.mem_free() < 102000:
      gc.collect()
    conn, addr = s.accept()
    conn.settimeout(3.0)
    print('Got a connection from %s' % str(addr))
    request = conn.recv(1024)
    conn.settimeout(None)
    request = str(request)
    print('Content = %s' % request)
    relay_on = request.find('/?relay=on')
    relay_off = request.find('/?relay=off')
    if relay_on == 6:
      print('RELAY ON')
      relay.value(0)
    if relay_off == 6:
      print('RELAY OFF')
      relay.value(1)
    response = web_page()
    conn.send('HTTP/1.1 200 OK\n')
    conn.send('Content-Type: text/html\n')
    conn.send('Connection: close\n\n')
    conn.sendall(response)
    conn.close()
  except OSError as e:
    conn.close()
    print('Connection closed')

View raw code

We won’t explain how this code works because we already have a very similar tutorial with detailed explanation of each line of code. Read the next project:

Demonstration

After making the necessary changes, upload the boot.py and main.py files to your board. Press the EN/RST button and in the Shell you should get the ESP IP address.

ESP32 ESP8266 Relay Web Server IP Address

Then, open a browser in your local network and type the ESP IP address to get access to the web server.

You should get a web page with a toggle button that allows you to control your relay remotely using your smartphone or your computer.

Control a relay with web server using ESP32 or ESP8266 NodeMCU using MicroPython firmware

Enclosure for Safety

For a final project, make sure you place your relay module and ESP inside an enclosure to avoid any AC pins exposed.

Plastic Enclosure for Safety and hide exposed AC pins of the relay module

Wrapping Up

Using relays with the ESP is a great way to control AC household appliances remotely. You can also read our complete guides about relay modules:

Learn more about MicroPython with the ESP32 and ESP8266 with our resources:

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Recommended Resources

Build a Home Automation System from Scratch » With Raspberry Pi, ESP8266, Arduino, and Node-RED.

Home Automation using ESP8266 eBook and video course » Build IoT and home automation projects.

Arduino Step-by-Step Projects » Build 25 Arduino projects with our course, even with no prior experience!

What to Read Next…


Enjoyed this project? Stay updated by subscribing our newsletter!

6 thoughts on “MicroPython: ESP32/ESP8266 Relay Module Web Server (AC Appliances)”

  1. Hello

    I try this tutorial but have problem
    Traceback (most recent call last):
    File “main.py”, line 19, in
    NameError: name ‘socket’ isn’t defined

    MicroPython v1.12 on 2019-12-20; ESP module with ESP8266
    Type “help()” for more information.

    is the same in your code:

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((”, 80))
    s.listen(5)

    Reply
  2. When I push EN button, in terminal (console) display that.
    <<
    ets Jun 8 2016 00:22:57

    rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
    configsip: 0, SPIWP:0xee
    clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    mode:DIO, clock div:2
    load:0x3fff0030,len:4540
    ho 0 tail 12 room 4
    load:0x40078000,len:12344
    ho 0 tail 12 room 4
    load:0x40080400,len:4124
    entry 0x40080680

    >
    pdt: Im on thonny IDE

    Reply
  3. Hello, I am stuck and I need help
    I am trying to add to the html code another check box but I am having an error and I don’t understand what it means
    added code:

    Type Error:
    format string needs more arguments

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.