6.2. WiFi LED control

By utilizing the WiFi capability of the NULA Mini board we can create use it to create a web server. The web server can be used for controling devices, displaying sensor data and managing various settings, all which can be accessed through a web browser from your device connected on the same network as the NULA Mini. In this example we'll be making a simple web interface for controlling the state of an LED.
At the end of this example you will learn:
- How to use NULA Mini to host a local web server
- How to build a HTML website from your NULA Mini
- How to handle incoming requests and sending HTML as a response
- How to control the state of GPIO over web interface
Parts required:
- Soldered NULA Mini Board
- Breadboard
- 1 x LED
- 1 x 330 Ohm resistor
- Some jumper wires
- WiFi connection

Putting the components together
- Place the LED on the breadboard so that each leg is in a different row.
- Connect one end of resistor to the short leg of the LED and the other to the GND on your board.
- Connect a jumper wire from the long leg of the LED to pin 5 on your board, or any available digital output pin.

Code Example
By importing socket library we can create the web server using Python socket API, to connect to WiFi network use network library and for LED control import Pin module.
import socket
import network
from machine import Pin
Set the ssid and password variables to hold the SSID and password of the existing WiFi network you want to connect to.
ssid = ''
password = ''
After setting the ssid and password, create a WLAN network object and set the board to act as a WiFi station. Activate the network interface and connect to the network using ssid and password variables.
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect(ssid, password)
Ensure that the NULA Mini is connected to WiFi before proceeding further.
while station.isconnected() == False:
pass
After successful connection print the IP network parameters (IP address, subnet mask, gateway and DNS server) and create a Pin object for LED.
print('Connection successful')
print(station.ifconfig())
led = Pin(5, Pin.OUT)
Function web_page() generates the website layout with basic HTML code that displays 2 simple buttons for turning the LED on/off and an LED status indicator based on the current LED pin value.
def web_page():
if led.value() == 1:
gpio_state="ON"
else:
gpio_state="OFF"
# Basic HTML code, generates document with buttons to control LED state
html = """
<html>
<head>
<title>ESP LED Control</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
<style>
html { display:inline-block; margin: 0px auto; text-align: center; }
h1 { color: #0F3376; padding: 2vh; }
p { font-size: 1.5rem; }
.button { background-color: green; border: none; color: white; padding: 16px 40px; text-decoration: none; font-size: 30px; margin: 2px; }
.button2 { background-color: red; }
</style>
</head>
<body>
<h1>ESP Web Server</h1>
<p>LED 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>"""
# Return 'html' string to display web content
return html
Create a new socket object s which acts as a communication channel object and will be used to listen for incoming requests.
s = socket.socket()
This method allows a socket to bind to a port even if it was used recently.
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
Bind the socket to an address using the bind() method which accepts a tupple containing the IP address and port number. In this case, empty string is passed for an address which means it will accept all connections on port 80.
s.bind(('', 80))
Enable the server to accept connections and setting the maximum number of queued connections.
s.listen(2)
In the main loop, when a client connects, server accepts the connection and saves a new socket object to accept and send data in conn variable and saves the client address to addr variable. We then retrieve the data from the socket and search inside the request for a specific string, if the string was found: toggle LED on or off and call the web_page() function to generate and send the HTML page to the client.
try:
# Infinite loop
while True:
# Wait for a client (browser) to connect, save new socket object 'conn' to send and receive data
# on connection, 'addr' is the ip address of the client
conn, addr = s.accept()
print('Got a connection from %s' % str(addr))
# Receive data from the socket by reading up to 1024 bytes of HTTP request
request = conn.recv(1024)
# Convert it to string
request = str(request)
# Search inside the request for '/?led=on' or '/?led=off'
led_on = request.find('/?led=on')
led_off = request.find('/?led=off')
# If the string is found at position 6 in the request -> toggle LED
if led_on == 6:
print('LED ON')
led.value(1)
if led_off == 6:
print('LED OFF')
led.value(0)
# Call the function to generate and send the HTML page along with HTTP headers
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)
# Close the created socket (IMPORTANT)
conn.close()
# Press CTRL + C (or Thonny Stop) to close the listening socket (Shutdown the server)
except KeyboardInterrupt:
print("Server stopped")
s.close()