Свой веб-сервер на ESP32: управление из браузера
Превращаем плату в маленький сайт, которым управляют с телефона.
Веб-сервер на ESP32 — программа, которая слушает входящие HTTP-запросы и отдаёт HTML-страницу, позволяя управлять устройством прямо из браузера.
Идея
Плата подключена к домашней сети и имеет IP-адрес. Если на ней запустить сервер, можно открыть этот адрес в браузере телефона и нажимать кнопки — включать свет, читать датчики. Не нужно отдельное приложение: интерфейс — обычная веб-страница.
Минимальный сервер на сокетах
import socket
from machine import Pin
led = Pin(2, Pin.OUT)
html = """<!DOCTYPE html>
<html><head><title>Умный дом</title></head>
<body><h1>Управление LED</h1>
<a href="/on">Включить</a> | <a href="/off">Выключить</a>
</body></html>"""
s = socket.socket()
s.bind(("0.0.0.0", 80))
s.listen(5)
print("Сервер запущен")
while True:
conn, addr = s.accept()
request = conn.recv(1024).decode()
if "/on" in request:
led.on()
elif "/off" in request:
led.off()
conn.send("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n")
conn.send(html)
conn.close()Открыв в браузере http://IP-платы/, вы увидите страницу со ссылками, а нажатия будут включать и выключать светодиод.
Разбор пути запроса — на чистом Python
Логику «какой путь запросили» можно проверить в браузере без железа:
def handle(request_line):
# request_line вида: GET /on HTTP/1.1
parts = request_line.split()
path = parts[1] if len(parts) > 1 else "/"
if path == "/on":
return "LED включён"
if path == "/off":
return "LED выключен"
return "Главная страница"
for line in ["GET /on HTTP/1.1", "GET /off HTTP/1.1", "GET / HTTP/1.1"]:
print(line, "->", handle(line))Вывод:
GET /on HTTP/1.1 -> LED включён GET /off HTTP/1.1 -> LED выключен GET / HTTP/1.1 -> Главная страница
Как работает под капотом
Сервер создаёт сокет, привязывает его к порту 80 и «слушает». Когда браузер открывает адрес, он шлёт текстовый HTTP-запрос (первая строка — метод и путь). accept() принимает соединение, recv() читает запрос, мы анализируем путь, выполняем действие и отправляем ответ: статусную строку, заголовки и тело-HTML. Браузер рисует страницу. Всё это синхронно — пока обрабатываем один запрос, другие ждут.
Частые ошибки
- Не закрывать соединение. Без
conn.close()новые клиенты зависнут. - Блокировка на одном клиенте. Простой сервер обслуживает по одному; для нескольких нужен асинхронный подход.
- Сырые
<в HTML-строке. Внутри Python-строки это нормально, но в учебных примерах теги экранируют для показа.
Итог
- ESP32 может сам отдавать веб-страницу — управление без отдельного приложения.
- Сервер слушает порт 80, принимает запрос, разбирает путь, отвечает HTML.
- Действие выбирают по пути запроса (
/on,/off). - Каждое соединение нужно закрывать; простой сервер однопоточный.