DHT11 Web Server using ESP32 & MicroPython is a runnable microcontroller simulation example on SensBench — open the wired circuit, inspect the code, and compile real firmware in your browser, no install needed. Last updated Aug 14, 2026.

FREE SIMULATOR EXAMPLE · INTERMEDIATE

DHT11 Web Server using ESP32 & MicroPython

This example serves live DHT11 readings from the ESP32 over HTTP — open the page in any browser and see the current temperature and humidity. The ESP32 as sensor, server and dashboard in one MicroPython script.

Board ESP32 DevKit (Xtensa LX6, 240 MHz)
Difficulty intermediate
Category communication
Libraries None — just the Arduino core
Runs in Sensbench browser simulator — free, no account
ESP32 serving DHT11 temperature and humidity readings on a web page in the Sensbench simulator

The exact circuit you get when you open this example — already wired, ready to run.

The sketch

# main.py
import machine
import network
import time
import socket
import dht

# DHT11 sensor setup
sensor = dht.DHT11(machine.Pin(4)) # GPIO4 connected

# Wi-Fi credentials
SSID = "kritish"
PASSWORD = "@Krrs2069"

# Wi-Fi connection
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
if not wifi.isconnected():
    print("Connecting to WiFi...", end="")
    wifi.connect(SSID, PASSWORD)
    while not wifi.isconnected():
        time.sleep(1)
        print(".", end="")
    print("\nConnected to WiFi:", wifi.ifconfig()[0])
else:
    print("Already connected to WiFi:", wifi.ifconfig()[0])
    
def web_page(temp, hum):
    # Corrected HTML with proper humidity unit and a cleaner f-string format.
    html = f"""<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ESP32 DHT11 SERVER</title>
    <meta http-equiv="refresh" content="3">
    <style>
        body {{
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            text-align: center;
            background: linear-gradient(to right, #f6ff00, #a600ff);
            color: white;
            margin: 0;
            padding: 0;
        }}
        h1 {{
            margin-top: 20px;
            font-size: 2.5em;
            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
        }}
        .container {{
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 20px;
            margin-top: 50px;
        }}
        .card {{
            background: rgba(255, 255, 255, 0.15);
            padding: 30px;
            border-radius: 20px;
            box-shadow: 0 8px 16px rgba(0,0,0,0.3);
            width: 250px;
            transition: transform 0.2s;
        }}
        .card:hover {{
            transform: scale(1.05);
        }}
        .value {{
            font-size: 2em;
            margin-top: 10px;
            font-weight: bold;
        }}
    </style>
</head>
<body>
    <h1>ESP32 DHT11 WEBSERVER</h1>
    <div class="container">
        <div class="card">
            <h2>🌡 Temperature</h2>
            <div class="value">{temp} °C</div>
        </div>
        <div class="card">
            <h2>💧 Humidity</h2>
            <div class="value">{hum} %</div>
        </div>
    </div>
    <p style="margin-top:40px;">Auto-refreshing every 3 seconds ⏳</p>
    <p class="footer">© 2025 Kritish. Powered by MicroPython.</p>
</body>
</html>"""
    return html

# Start web server
addr = socket.getaddrinfo("0.0.0.0", 80)[0][-1]
server = socket.socket()
server.bind(addr)
server.listen(1)
print("Web server running on:", wifi.ifconfig()[0])

while True:
    try:
        # Read sensor
        sensor.measure()
        temp = sensor.temperature()
        hum = sensor.humidity()
        
        # Handle client
        client, addr = server.accept()
        print("Client connected from", addr)
        request = client.recv(1024)
        
        # Check for valid sensor readings before serving the page
        if isinstance(temp, (int, float)) and isinstance(hum, (int, float)):
            response = web_page(temp, hum)
        else:
            # Handle cases where sensor reading fails
            response = "<h1>Sensor reading failed. Please try again.</h1>"

        client.send("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n")
        client.sendall(response)
        client.close()
        
    except OSError as e:
        print("Failed to read sensor or a socket error occurred:", e)
        time.sleep(10) # Wait a bit before trying again
    except Exception as e:
        print("An unexpected error occurred:", e)
        time.sleep(10)

How it works

The script reads the DHT11 on a GPIO and serves a small web page that displays the temperature and humidity, refreshed on each request. The HTTP handler does the sensor read inline, so every page load shows a fresh measurement.

The DHT11’s one-wire protocol is handled by the MicroPython dht module — the script only calls measure() and reads the values. The 1-second minimum between reads is enforced by the request rate in practice, but the module’s internal timing guards against faster polling.

Before you build it for real

The DHT11’s 1-second minimum interval is a hard limit — poll faster and the readings go stale or the sensor returns errors; the module enforces it, but a busy server can still serve the same reading to ten clients. The sensor wants the pull-up resistor that breakout boards include and bare parts do not. And the web server has no authentication: anyone on the network reads the values — fine for a room thermometer, wrong for anything sensitive.

Get the parts

Related examples

FAQ

Why DHT11 instead of DHT22?

The DHT11 is the cheaper sibling: integer-only readings, ±2 °C accuracy, and a 1-second minimum interval. For a web demo the lower cost and simpler protocol win. The DHT22 examples elsewhere in the collection show the upgrade path when decimal precision matters.

Why serve the readings over HTTP?

A web server is the zero-install dashboard: any browser on the same network opens the page and sees the numbers. No app, no cloud account — the ESP32 is the sensor, the server and the display endpoint in one.