Categories
ESP32 Python

ESP32, MicroPython, and controlling a relay

Now that we have an ESP32 connected to our network and running python, the next task is to connect a two switch relay and be able to control it. Eventually we will do this via MQTT, but for now a web server will be enabled on the board to allow manual control of the relay switches.

2 Switch Solid State Relay
2 Switch Solid State Relay

In advance of this I have moved the wireless connection code into a functions.py file and will import this. This functions.py is as follows -:

import network

def connect_to_wifi(ssid, password):
    print("Connecting to wifi...")
    # Activate the station interface
    sta_if = network.WLAN(network.STA_IF)
    sta_if.active(True)
    # Connect to your wifi network
    sta_if.connect(ssid, password)
    # Wait until the wireless is connected
    while not sta_if.isconnected():
        pass
    return sta_if

The function is called in main.py as follows :

import config
import functions

wifi = functions.connect_to_wifi(config.ssid, config.password)
# Print out the network configuration received from DHCP
print('network config:', wifi.ifconfig())

This script will, so far, connect the ESP32 to the wireless network with the settings defined in config.py.

Upload functions.py to the ESP32 board.

ampy --delay 1 --port /dev/cu.usbserial-0001 put functions.py 

Wiring

In the case of my two switch relay I have connected the relay to 3.3v and ground pins, along with switch one and two connected to GPIOs 22 and 23.

ESP32 Relay Wired
ESP32 Relay Wired

Web Server

We will create a very simple web server that will display the state of the two relays along with on and off buttons for each switch.

Relay Switch One Active
Relay Switch One Active

First I will create a function that will display the webpage and add that to my functions.py (remembering to upload this to the board again).

The two pins are passed to this function and it generates the HTML based upon the state of the two relay switches.

def web_page(relay1, relay2):
    # Set relay_state variable based on state returned from output pins
    if relay1.value() == 1:
        relay1_state = "ON"
    else:
        relay1_state = "OFF"
    if relay2.value() == 1:
        relay2_state = "ON"
    else:
        relay2_state = "OFF"

    # Create a variable containing the HTML to be sent
    # The state of the relays are contained in the variables we have just set
    html = """<html>
      <head> 
        <title>MicroPython 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: #006400; border: none; border-radius: 4px; color: white; padding: 16px 40px; text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}.button2{background-color: #dc143c;}</style>
      </head>
      <body> 
        <h1>MicroPython Web Server</h1> 
        <p>Relay 1 state: <strong>""" + relay1_state + """</strong></p>
        <p>
          <a href="/?relay1=on"><button class="button">ON</button></a>
          <a href="/?relay1=off"><button class="button button2">OFF</button></a>
        </p>
        <p>Relay 2 state: <strong>""" + relay2_state + """</strong></p>
        <p>
          <a href="/?relay2=on"><button class="button">ON</button></a>
          <a href="/?relay2=off"><button class="button button2">OFF</button></a>
        </p>
      </body>
    </html>"""
    # Return the HTML
    return html

This HTML will produce the following web page -:

MicroPython Web Server
MicroPython Web Server

Main Script

The main script essentially connects to the wireless networks, starts listening on port 80 and returns the HTML we generate.

import config
import functions
from machine import Pin
try:
  import usocket as socket
except:
  import socket

wifi = functions.connect_to_wifi(config.ssid, config.password)
# Print out the network configuration received from DHCP
print('network config:', wifi.ifconfig())
# Create an output pin on GPIO 22
relay1 = Pin(22, Pin.OUT)
# Create an output pin on GPIO 23
relay2 = Pin(23, Pin.OUT)
# Create a socket we will use for webserver
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind this socket to port 80
s.bind(('', 80))
# Listen on the socket
s.listen(5)

while True:
    # Accept a connection on port 80
    conn, addr = s.accept()
    print('Got a connection from %s' % str(addr))
    # Recieve a request from the client
    request = conn.recv(1024)
    request = str(request)
    print('Content = %s' % request)
    relay1_on = request.find('/?relay1=on')
    relay1_off = request.find('/?relay1=off')
    if relay1_on == 6:
        print('Relay 1 ON')
        relay1.value(1)
    if relay1_off == 6:
        print('Relay 1 OFF')
        relay1.value(0)
    relay2_on = request.find('/?relay2=on')
    relay2_off = request.find('/?relay2=off')
    if relay2_on == 6:
        print('Relay 2 ON')
        relay2.value(1)
    if relay2_off == 6:
        print('Relay 2 OFF')
        relay2.value(0)
    response = functions.web_page(relay1, relay2)
    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()

Code

The full code can be found at -:

webserver.py

functions.py

config.py.example

Leave a Reply

Your email address will not be published. Required fields are marked *