ESP32/ESP8266 MicroPython веб-сервер – управление выходами
Узнайте, как создать веб-сервер для управления выходами ESP32 или ESP8266 с помощью фреймворка MicroPython. В качестве примера мы создадим веб-сервер с кнопками ON и OFF для управления встроенным светодиодом ESP32/ESP8266. Мы будем использовать сокеты и Python socket API.
Предварительные требования
Для программирования ESP32 и ESP8266 на MicroPython мы используем uPyCraft IDE в качестве среды разработки. Следуйте следующим руководствам для установки uPyCraft IDE и прошивки MicroPython на вашу плату:
Установка uPyCraft IDE: Windows PC, MacOS X, или Linux Ubuntu
Если это ваш первый опыт работы с MicroPython, рекомендуем ознакомиться со следующими руководствами:
Необходимые компоненты
Для этого руководства вам понадобится плата ESP32 или ESP8266:
ESP32 DEVKIT DOIT board – рекомендуем ознакомиться с обзором ESP32 Development Boards Review and Comparison
ESP8266-12E NodeMCU Kit – рекомендуем ознакомиться с обзором Best ESP8266 Wi-Fi Development Board
Подготовка файлов
Подключите плату ESP32 или ESP8266 к компьютеру. Откройте uPyCraft IDE, перейдите в Tools > Serial и выберите последовательный порт.
Вы должны увидеть файлы на плате ESP32/ESP8266 в папке устройства. По умолчанию при прошивке MicroPython создаётся файл boot.py.
Для этого проекта вам понадобятся файлы boot.py и main.py. Файл boot.py содержит код, который выполняется только один раз при загрузке. Это включает импорт библиотек, сетевые учётные данные, настройку пинов, подключение к сети и другие конфигурации.
Файл main.py будет содержать код, запускающий веб-сервер для обслуживания файлов и выполнения задач на основе запросов, полученных от клиента.
Создание файла main.py на вашей плате
1. Нажмите кнопку «New file», чтобы создать новый файл.
2. Нажмите кнопку «Save file», чтобы сохранить файл на вашем компьютере.
3. Откроется новое окно, назовите файл main.py и сохраните его на компьютере:
4. После этого вы должны увидеть следующее в вашей uPyCraft IDE (файл boot.py на устройстве и новую вкладку с файлом main.py):
5. Нажмите кнопку «Download and run», чтобы загрузить файл на плату ESP:
6. В директории устройства теперь должен появиться файл main.py. На вашей ESP хранится файл main.py.
boot.py
Скопируйте следующий код в файл boot.py на ESP32/ESP8266.
# Подробности проекта на https://RandomNerdTutorials.com
try:
import usocket as socket
except:
import socket
from machine import Pin
import network
import esp
esp.osdebug(None)
import gc
gc.collect()
ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect(ssid, password)
while station.isconnected() == False:
pass
print('Connection successful')
print(station.ifconfig())
led = Pin(2, Pin.OUT)
Просмотреть исходный код boot.py
Как упоминалось ранее, мы создаём наш веб-сервер с помощью сокетов и Python socket API. Официальная документация импортирует библиотеку socket следующим образом:
try:
import usocket as socket
except:
import socket
Нам нужно импортировать класс Pin из модуля machine, чтобы иметь возможность взаимодействовать с GPIO.
from machine import Pin
После импорта библиотеки socket нам нужно импортировать библиотеку network. Библиотека network позволяет подключить ESP32 или ESP8266 к сети Wi-Fi.
import network
Следующие строки отключают отладочные сообщения ОС:
import esp
esp.osdebug(None)
Затем мы запускаем сборщик мусора:
import gc
gc.collect()
Сборщик мусора (garbage collector) – это форма автоматического управления памятью. Это способ освободить память, занятую объектами, которые больше не используются программой. Это полезно для экономии места во flash-памяти.
Следующие переменные содержат ваши сетевые учётные данные:
ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'replace_with_your_password'
Вы должны заменить выделенные красным слова на ваш SSID сети и пароль, чтобы ESP могла подключиться к вашему роутеру.
Затем установите ESP32 или ESP8266 в режим Wi-Fi станции:
station = network.WLAN(network.STA_IF)
После этого активируйте станцию:
station.active(True)
Наконец, ESP32/ESP8266 подключается к вашему роутеру, используя SSID и пароль, определённые ранее:
station.connect(ssid, password)
Следующая инструкция гарантирует, что код не продолжит выполнение, пока ESP не подключится к вашей сети.
while station.isconnected() == False:
pass
После успешного подключения выведите параметры сетевого интерфейса, такие как IP-адрес ESP32/ESP8266 – используйте метод ifconfig() на объекте station.
print('Connection successful')
print(station.ifconfig())
Создайте объект Pin с именем led, который является выходом и ссылается на GPIO2 ESP32/ESP8266:
led = Pin(2, Pin.OUT)
main.py
Скопируйте следующий код в файл main.py на ESP32/ESP8266.
# Подробности проекта на https://RandomNerdTutorials.com
def web_page():
if led.value() == 1:
gpio_state="ON"
else:
gpio_state="OFF"
html = """<html><head> <title>ESP 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: #e7bd3b; border: none;
border-radius: 4px; color: white; padding: 16px 40px; text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}
.button2{background-color: #4286f4;}</style></head><body> <h1>ESP Web Server</h1>
<p>GPIO 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
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)
while True:
conn, addr = s.accept()
print('Got a connection from %s' % str(addr))
request = conn.recv(1024)
request = str(request)
print('Content = %s' % request)
led_on = request.find('/?led=on')
led_off = request.find('/?led=off')
if led_on == 6:
print('LED ON')
led.value(1)
if led_off == 6:
print('LED OFF')
led.value(0)
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()
Просмотреть исходный код main.py
Скрипт начинается с создания функции web_page(). Эта функция возвращает переменную html, содержащую HTML-текст для построения веб-страницы.
def web_page():
Веб-страница отображает текущее состояние GPIO. Поэтому перед генерацией HTML-текста нам нужно проверить состояние светодиода. Мы сохраняем его состояние в переменной gpio_state:
if led.value() == 1:
gpio_state="ON"
else:
gpio_state="OFF"
После этого переменная gpio_state включается в HTML-текст с помощью знаков "+" для конкатенации строк.
html = """<html><head> <title>ESP 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: #e7bd3b; border: none;
border-radius: 4px; color: white; padding: 16px 40px; text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}
.button2{background-color: #4286f4;}</style></head><body> <h1>ESP Web Server</h1>
<p>GPIO 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>"""
Создание сокет-сервера
После создания HTML для построения веб-страницы нам нужно создать слушающий сокет для приёма входящих запросов и отправки HTML-текста в ответ. Для лучшего понимания на следующей схеме показана диаграмма создания сокетов для взаимодействия сервер-клиент:
Создайте сокет с помощью socket.socket() и укажите тип сокета. Мы создаём новый объект сокета с именем s с заданным семейством адресов и типом сокета. Это STREAM TCP сокет:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Далее привяжите сокет к адресу (сетевой интерфейс и номер порта) с помощью метода bind(). Метод bind() принимает кортеж с IP-адресом и номером порта:
s.bind(('', 80))
В нашем примере мы передаём пустую строку '' в качестве IP-адреса и порт 80. В этом случае пустая строка ссылается на IP-адрес localhost (то есть IP-адрес ESP32 или ESP8266).
Следующая строка позволяет серверу принимать соединения; она создаёт «слушающий» сокет. Аргумент указывает максимальное количество соединений в очереди. Максимум – 5.
s.listen(5)
В цикле while мы слушаем запросы и отправляем ответы. Когда клиент подключается, сервер вызывает метод accept() для принятия соединения. Когда клиент подключается, сервер сохраняет новый объект сокета для приёма и отправки данных в переменной conn, а адрес клиента – в переменной addr.
conn, addr = s.accept()
Затем выведите адрес клиента, сохранённый в переменной addr.
print('Got a connection from %s' % str(addr))
Данные обмениваются между клиентом и сервером с помощью методов send() и recv().
Следующая строка получает запрос, принятый на вновь созданном сокете, и сохраняет его в переменной request.
request = conn.recv(1024)
Метод recv() принимает данные от клиентского сокета (помните, что мы создали новый объект сокета в переменной conn). Аргумент метода recv() задаёт максимальный объём данных, который может быть получен за один раз.
Следующая строка просто выводит содержимое запроса:
print('Content = %s' % str(request))
Затем создайте переменную response, которая содержит HTML-текст, возвращённый функцией web_page():
response = web_page()
Наконец, отправьте ответ клиентскому сокету с помощью методов send() и sendall():
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()
Тестирование веб-сервера
Загрузите файлы main.py и boot.py на ESP32/ESP8266. В папке device должны быть два файла: boot.py и main.py.
После загрузки файлов нажмите кнопку EN/RST на плате ESP.
Через несколько секунд устройство должно установить соединение с вашим роутером и вывести IP-адрес в Shell.
Откройте браузер и введите только что найденный IP-адрес вашего ESP. Вы должны увидеть страницу веб-сервера, как показано ниже.
Когда вы нажимаете кнопку ON, вы отправляете запрос на IP-адрес ESP, дополненный /?led=on. Встроенный светодиод ESP32/ESP8266 загорается, и состояние GPIO обновляется на странице.
Примечание
Некоторые встроенные светодиоды ESP8266 включаются по команде OFF и выключаются по команде ON.
Когда вы нажимаете кнопку OFF, вы отправляете запрос на IP-адрес ESP, дополненный /?led=off. Светодиод выключается, и состояние GPIO обновляется.
Примечание
Для простоты в этом руководстве мы управляем встроенным светодиодом, соответствующим GPIO 2. Вы можете управлять любым другим GPIO с любым другим выходом (например, реле) тем же методом. Также вы можете модифицировать код для управления несколькими GPIO или изменить HTML-текст для создания другой веб-страницы.
Итоги
В этом руководстве показано, как создать простой веб-сервер с прошивкой MicroPython для управления GPIO ESP32/ESP8266 с помощью сокетов и библиотеки Python socket. Если вы ищете руководство по веб-серверу с Arduino IDE, ознакомьтесь со следующими ресурсами:
Если вы ищете больше проектов с платами ESP32 и ESP8266, ознакомьтесь со следующими ресурсами:
Надеемся, что эта статья о создании веб-сервера с MicroPython была полезна. Чтобы узнать больше о MicroPython, ознакомьтесь с нашей электронной книгой: MicroPython Programming with ESP32 and ESP8266.