ICT 360: Introduction to IoT
Mr. Seng Theara
Display sensor data on an I2C LCD
Explain how a web server works on an ESP32
Create a basic HTTP web server
Control ESP32 behavior via web buttons
Display real-time sensor data on a webpage
Expansion Board or External Shield
Ultrasonic refers to sound waves with frequencies that exceed the range of what human ears can hear.
An ultrasonic sensor is an electronic device used to measure distance by sending out high-frequency sound waves (ultrasound) and calculating how long it takes for the sound to bounce back from an object.
Distance Formula
Where
Divide by 2 because the sound travels to the object and back
Signal
Signal
Vcc/5V
Vcc/5V
GND
GND
Signal
Signal
Vcc/5V
Vcc/5V
GND
GND
from machine import Pin, time_pulse_us
import time
# Pin configuration
TRIG = Pin(27, Pin.OUT)
ECHO = Pin(26, Pin.IN)
def get_distance_cm():
# Ensure trigger is LOW
TRIG.value(0)
time.sleep_us(2)
# Send 10µs pulse
TRIG.value(1)
time.sleep_us(10)
TRIG.value(0)
# Measure echo pulse duration
duration = time_pulse_us(ECHO, 1, 30000) # timeout = 30ms
# Check for timeout
if duration < 0:
return None
# Distance calculation (cm)
distance = (duration * 0.0343) / 2
return distance
# Main loop
while True:
dist = get_distance_cm()
if dist is not None:
print("Distance: {:.2f} cm".format(dist))
else:
print("Out of range")
time.sleep(1)
An I²C LCD is a character display (16×2 or 20×4) that communicates with the ESP32 using only two wires:
SDA → Data
SCL → Clock
LCD 16×2 can display 16 column and 2 row
LCD 20x4 can display 20 column and 4 row
DC-
DC+
Signal Trigger
GND
Vcc
If HIGH
-> Common connect to
Normally Open
First, you create two files and save them in the microPython device
You can find the library code in the link below
from machine import Pin, SoftI2C
from machine_i2c_lcd import I2cLcd
from time import sleep
I2C_ADDR = 0x27
i2c = SoftI2C(sda=Pin(21), scl=Pin(22), freq=400000)
lcd = I2cLcd(i2c, I2C_ADDR, 2, 16)
lcd.clear()
lcd.move_to(0, 0) # first row
lcd.putstr("IoT course")
lcd.move_to(0, 1) # second row
lcd.putstr("Welcome to AUPP")We set the column and row of index 0 to display the text "IoT course"
We set the column of index 0 and row of index 1 to display the text "Welcome to AUPP"
Read the distance using the ultrasonic sensor and display it on the LCD I2C
from machine import Pin
import time
# Initialize relay pin (GPIO15 / D15)
relay = Pin(15, Pin.OUT)
print("Relay control started...")
while True:
# Turn relay ON
relay.value(1)
print("Relay ON")
time.sleep(2)
# Turn relay OFF
relay.value(0)
print("Relay OFF")
time.sleep(2)
from machine import Pin
import time
# Initialize relay pin (GPIO15 / D15)
relay = Pin(15, Pin.OUT)
print("Relay control started...")
while True:
# Turn relay ON
relay.value(1)
print("Relay ON")
time.sleep(2)
# Turn relay OFF
relay.value(0)
print("Relay OFF")
time.sleep(2)
A web server is essentially a specialized computer with one main job: storing websites and delivering them to users who request them. When you type a website address into your browser or click on a link, you’re essentially placing an order with a webserver.
When the web server receives your request, it quickly searches through its stored files to find the webpage you asked for (like HTML documents, images, videos, and other content that makes up the website).
If it finds them, the web server gathers all these components together, packages them into an HTTP response, and sends them back to your browser.
For the ESP32 to function as a web server and serve a webpage, it must first establish a network connection using one of its three Wi-Fi modes: Station (STA) mode, Access Point (AP) mode, and Dual (AP+STA) mode.
When your ESP32 is in STA mode, it acts like any other device, such as your laptop or smartphone, that wants to connect to an existing Wi-Fi network. It searches for a Wi-Fi network, connects to it using the network name (SSID) and password, and then becomes part of that network.
When your ESP32 is in AP mode, it creates its own Wi-Fi network, assigning it an SSID (the network’s name), a password, and an IP address. Other devices, like your smartphone or computer, can then search for this network and connect to it using a password you’ve set. With the IP address it assigns itself, your ESP32 can serve web pages directly to all the devices that have connected to its newly created network.
What makes the ESP32 particularly versatile is that it can actually operate in both modes simultaneously, which is called AP+STA mode or dual mode. In this configuration, your ESP32 can connect to an existing Wi-Fi network as a station while also creating its own access point for other devices to join. This creates interesting possibilities, such as building a device that can extend Wi-Fi coverage or create a bridge between different networks.
import network
import socket
from machine import Pin
import time
# ==============================
# LED SETUP
# ==============================
led = Pin(12, Pin.OUT)
led.off()
# ==============================
# WIFI SETUP (Station Mode)
# ==============================
ssid = "project"
password = "1234567890"
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.connect(ssid, password)
print("Connecting to WiFi...")
while not wifi.isconnected():
time.sleep(1)
ip = wifi.ifconfig()[0]
print("Connected!")
print("ESP32 IP address:", ip)
# ==============================
# WEB SERVER SETUP
# ==============================
addr = socket.getaddrinfo("0.0.0.0", 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print("Web server running...")
# ==============================
# HTML PAGE
# ==============================
def web_page():
html = """
<html>
<head>
<title>ESP32 LED Control</title>
<style>
body { font-family: Arial; text-align: center; }
button { width: 120px; height: 50px; font-size: 20px; }
</style>
</head>
<body>
<h1>ESP32 LED Control</h1>
<p><a href="/on"><button>ON</button></a></p>
<p><a href="/off"><button>OFF</button></a></p>
</body>
</html>
"""
return html
# ==============================
# MAIN LOOP
# ==============================
while True:
conn, addr = s.accept()
request = conn.recv(1024).decode()
print("Request:", request)
if "/on" in request:
led.on()
print("LED ON")
if "/off" in request:
led.off()
print("LED OFF")
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()
import network
import socket
from machine import Pin
import time
# ==============================
# LED SETUP
# ==============================
led = Pin(2, Pin.OUT)
led.off()
led_state = False # False = OFF, True = ON
# ==============================
# WIFI SETUP (Station Mode)
# ==============================
ssid = "project"
password = "1234567890"
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.connect(ssid, password)
print("Connecting to WiFi...")
while not wifi.isconnected():
time.sleep(1)
ip = wifi.ifconfig()[0]
print("Connected!")
print("ESP32 IP address:", ip)
# ==============================
# WEB SERVER SETUP
# ==============================
addr = socket.getaddrinfo("0.0.0.0", 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print("Web server running...")
# ==============================
# HTML PAGE WITH LED STATUS
# ==============================
def web_page(state):
if state:
color = "green"
status = "LED is ON"
else:
color = "red"
status = "LED is OFF"
html = f"""
<html>
<head>
<title>ESP32 LED Control</title>
<style>
body {{
font-family: Arial;
text-align: center;
}}
.circle {{
width: 80px;
height: 80px;
background-color: {color};
border-radius: 50%;
margin: 20px auto;
}}
button {{
width: 120px;
height: 50px;
font-size: 20px;
}}
</style>
</head>
<body>
<h1>ESP32 LED Control</h1>
<div class="circle"></div>
<h2>{status}</h2>
<p><a href="/on"><button>ON</button></a></p>
<p><a href="/off"><button>OFF</button></a></p>
</body>
</html>
"""
return html
# ==============================
# MAIN LOOP
# ==============================
while True:
conn, addr = s.accept()
request = conn.recv(1024).decode()
print("Request:", request)
if "/on" in request:
led.on()
led_state = True
print("LED ON")
if "/off" in request:
led.off()
led_state = False
print("LED OFF")
response = web_page(led_state)
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()
Turn Green when ON
Turn Red
when OFF