ESP32 Веб-сервер с использованием SPIFFS (файловая система SPI Flash)
В этом руководстве мы покажем вам, как создать веб-сервер, который обслуживает HTML и CSS файлы, хранящиеся в файловой системе ESP32. Вместо того чтобы писать HTML и CSS текст непосредственно в скетче Arduino, мы создадим отдельные HTML и CSS файлы.
В демонстрационных целях веб-сервер, который мы создадим, управляет выходом ESP32, но его можно легко адаптировать для других целей, например, для отображения показаний датчиков.
Рекомендуемое чтение: ESP8266 Web Server using SPIFFS
Плагин загрузки файловой системы ESP32
Для выполнения этого руководства у вас должен быть установлен плагин ESP32 Filesystem Uploader в вашей Arduino IDE. Если у вас его нет, сначала следуйте следующему руководству для его установки:
Примечание: убедитесь, что у вас установлена последняя версия Arduino IDE, а также дополнение ESP32 для Arduino IDE. Если нет, следуйте одному из следующих руководств для установки:
Обзор проекта
Прежде чем переходить непосредственно к проекту, важно описать, что будет делать наш веб-сервер, чтобы было легче понять.
Веб-сервер, который вы создадите, управляет светодиодом, подключённым к GPIO 2 ESP32. Это встроенный светодиод ESP32. Вы можете управлять любым другим GPIO;
Страница веб-сервера отображает две кнопки: ON и OFF – для включения и выключения GPIO 2;
Страница веб-сервера также показывает текущее состояние GPIO.
На следующем рисунке показана упрощённая диаграмма, демонстрирующая, как всё работает.
ESP32 запускает код веб-сервера на основе библиотеки ESPAsyncWebServer;
HTML и CSS файлы хранятся в SPIFFS (Serial Peripheral Interface Flash File System) ESP32;
Когда вы делаете запрос на определённый URL с помощью браузера, ESP32 отвечает запрошенными файлами;
Когда вы нажимаете кнопку ON, вы перенаправляетесь на корневой URL с добавлением /on, и светодиод включается;
Когда вы нажимаете кнопку OFF, вы перенаправляетесь на корневой URL с добавлением /off, и светодиод выключается;
На веб-странице есть заполнитель (placeholder) для состояния GPIO. Заполнитель для состояния GPIO записывается непосредственно в HTML-файле между знаками %, например %STATE%.
Установка библиотек
В большинстве наших проектов мы создавали HTML и CSS файлы для веб-сервера как строку (String) непосредственно в скетче Arduino. С SPIFFS вы можете написать HTML и CSS в отдельных файлах и сохранить их в файловой системе ESP32.
Один из самых простых способов создать веб-сервер, используя файлы из файловой системы, – это использование библиотеки ESPAsyncWebServer. Библиотека ESPAsyncWebServer хорошо документирована на её странице GitHub. Для получения дополнительной информации об этой библиотеке перейдите по следующей ссылке:
Установка библиотеки ESPAsyncWebServer
Выполните следующие шаги для установки библиотеки ESPAsyncWebServer:
Нажмите здесь для загрузки библиотеки ESPAsyncWebServer. У вас должен появиться .zip файл в папке Загрузки
Распакуйте .zip файл, и вы должны получить папку ESPAsyncWebServer-master
Переименуйте папку из ESPAsyncWebServer-master в ESPAsyncWebServer
Переместите папку ESPAsyncWebServer в папку библиотек вашей Arduino IDE
Установка библиотеки Async TCP для ESP32
Библиотека ESPAsyncWebServer требует библиотеку AsyncTCP для работы. Выполните следующие шаги для установки этой библиотеки:
Нажмите здесь для загрузки библиотеки AsyncTCP. У вас должен появиться .zip файл в папке Загрузки
Распакуйте .zip файл, и вы должны получить папку AsyncTCP-master
Переименуйте папку из AsyncTCP-master в AsyncTCP
Переместите папку AsyncTCP в папку библиотек вашей Arduino IDE
Наконец, перезапустите Arduino IDE
Организация файлов
Для создания веб-сервера вам нужны три различных файла. Скетч Arduino, HTML-файл и CSS-файл. HTML и CSS файлы должны быть сохранены внутри папки с именем data внутри папки скетча Arduino, как показано ниже:
Создание HTML-файла
HTML для этого проекта очень простой. Нам просто нужно создать заголовок для веб-страницы, параграф для отображения состояния GPIO и две кнопки.
Создайте файл index.html со следующим содержимым или скачайте все файлы проекта здесь:
<!DOCTYPE html>
<html>
<head>
<title>ESP32 Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<h1>ESP32 Web Server</h1>
<p>GPIO state: <strong> %STATE%</strong></p>
<p><a href="/on"><button class="button">ON</button></a></p>
<p><a href="/off"><button class="button button2">OFF</button></a></p>
</body>
</html>
Поскольку мы используем CSS и HTML в разных файлах, нам нужно сослаться на CSS-файл в HTML-тексте. Следующая строка должна быть добавлена между тегами <head> </head>:
<link rel="stylesheet" type="text/css" href="style.css">
Тег <link> сообщает HTML-файлу, что вы используете внешнюю таблицу стилей для форматирования внешнего вида страницы. Атрибут rel указывает природу внешнего файла, в данном случае это stylesheet – CSS-файл, который будет использоваться для изменения внешнего вида страницы.
Атрибут type установлен в «text/css», чтобы указать, что вы используете CSS-файл для стилей. Атрибут href указывает расположение файла; поскольку оба файла CSS и HTML будут в одной папке, вам нужно только указать имя файла: style.css.
В следующей строке мы записываем первый заголовок нашей веб-страницы. В данном случае у нас «ESP32 Web Server». Вы можете изменить заголовок на любой желаемый текст:
<h1>ESP32 Web Server</h1>
Затем мы добавляем параграф с текстом «GPIO state: «, за которым следует состояние GPIO. Поскольку состояние GPIO изменяется в соответствии с состоянием GPIO, мы можем добавить заполнитель, который затем будет заменён на любое значение, которое мы установим в скетче Arduino.
Для добавления заполнителя мы используем знаки %. Чтобы создать заполнитель для состояния, мы можем использовать %STATE%, например.
<p>GPIO state: <strong>%STATE%</strong></p>
Присвоение значения заполнителю STATE выполняется в скетче Arduino.
Затем мы создаём кнопки ON и OFF. Когда вы нажимаете кнопку on, мы перенаправляем веб-страницу на корневой URL с добавлением /on. Когда вы нажимаете кнопку off, вы перенаправляетесь на URL /off.
<p><a href="/on"><button class="button">ON</button></a></p>
<p><a href="/off"><button class="button button2">OFF</button></a></p>
Создание CSS-файла
Создайте файл style.css со следующим содержимым или скачайте все файлы проекта здесь:
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: #008CBA;
border: none;
border-radius: 4px;
color: white;
padding: 16px 40px;
text-decoration: none;
font-size: 30px;
margin: 2px;
cursor: pointer;
}
.button2 {
background-color: #f44336;
}
Это просто базовый CSS-файл для установки размера шрифта, стиля и цвета кнопок и выравнивания страницы. Мы не будем объяснять, как работает CSS. Хорошее место для изучения CSS – это сайт W3Schools.
Скетч Arduino
Скопируйте следующий код в Arduino IDE или скачайте все файлы проекта здесь. Затем вам нужно ввести ваши сетевые учётные данные (SSID и пароль), чтобы он заработал.
/*********
Rui Santos
Complete project details at https://randomnerdtutorials.com
*********/
// Import required libraries
#include "WiFi.h"
#include "ESPAsyncWebServer.h"
#include "SPIFFS.h"
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Set LED GPIO
const int ledPin = 2;
// Stores LED state
String ledState;
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
// Replaces placeholder with LED state value
String processor(const String& var){
Serial.println(var);
if(var == "STATE"){
if(digitalRead(ledPin)){
ledState = "ON";
}
else{
ledState = "OFF";
}
Serial.print(ledState);
return ledState;
}
return String();
}
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
pinMode(ledPin, OUTPUT);
// Initialize SPIFFS
if(!SPIFFS.begin(true)){
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
// Print ESP32 Local IP Address
Serial.println(WiFi.localIP());
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/index.html", String(), false, processor);
});
// Route to load style.css file
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/style.css", "text/css");
});
// Route to set GPIO to HIGH
server.on("/on", HTTP_GET, [](AsyncWebServerRequest *request){
digitalWrite(ledPin, HIGH);
request->send(SPIFFS, "/index.html", String(), false, processor);
});
// Route to set GPIO to LOW
server.on("/off", HTTP_GET, [](AsyncWebServerRequest *request){
digitalWrite(ledPin, LOW);
request->send(SPIFFS, "/index.html", String(), false, processor);
});
// Start server
server.begin();
}
void loop(){
}
Как работает код
Сначала подключите необходимые библиотеки:
#include "WiFi.h"
#include "ESPAsyncWebServer.h"
#include "SPIFFS.h"
Вам нужно ввести ваши сетевые учётные данные в следующие переменные:
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Далее создайте переменную, которая ссылается на GPIO 2, с именем ledPin, и строковую переменную для хранения состояния светодиода: ledState.
const int ledPin = 2;
String ledState;
Создайте объект AsyncWebServer с именем server, который прослушивает порт 80.
AsyncWebServer server(80);
Функция processor()
Функция processor() – это то, что присваивает значение заполнителю, который мы создали в HTML-файле. Она принимает в качестве аргумента заполнитель и должна возвращать строку (String), которая заменит заполнитель. Функция processor() должна иметь следующую структуру:
String processor(const String& var){
Serial.println(var);
if(var == "STATE"){
if(digitalRead(ledPin)){
ledState = "ON";
}
else{
ledState = "OFF";
}
Serial.print(ledState);
return ledState;
}
return String();
}
Эта функция сначала проверяет, является ли заполнитель тем самым STATE, который мы создали в HTML-файле.
if(var == "STATE"){
Если это так, то в зависимости от состояния светодиода мы устанавливаем переменную ledState в значение ON или OFF.
if(digitalRead(ledPin)){
ledState = "ON";
}
else{
ledState = "OFF";
}
Наконец, мы возвращаем переменную ledState. Это заменяет заполнитель строковым значением ledState.
return ledState;
Функция setup()
В функции setup() начните с инициализации монитора порта и установки GPIO как выхода.
Serial.begin(115200);
pinMode(ledPin, OUTPUT);
Инициализация SPIFFS:
if(!SPIFFS.begin(true)){
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
Подключение к Wi-Fi
Подключитесь к Wi-Fi и выведите IP-адрес ESP32:
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println(WiFi.localIP());
Асинхронный веб-сервер
Библиотека ESPAsyncWebServer позволяет нам настроить маршруты, по которым сервер будет прослушивать входящие HTTP-запросы и выполнять функции при получении запроса на этом маршруте. Для этого используйте метод on() объекта server следующим образом:
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/index.html", String(), false, processor);
});
Когда сервер получает запрос на корневой URL « / «, он отправляет файл index.html клиенту. Последний аргумент функции send() – это процессор (processor), чтобы мы могли заменить заполнитель на нужное значение – в данном случае на ledState.
Поскольку мы сослались на CSS-файл в HTML-файле, клиент сделает запрос на CSS-файл. Когда это происходит, CSS-файл отправляется клиенту:
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/style.css","text/css");
});
Наконец, вам нужно определить, что происходит на маршрутах /on и /off. Когда запрос делается на эти маршруты, светодиод включается или выключается, и ESP32 обслуживает HTML-файл.
server.on("/on", HTTP_GET, [](AsyncWebServerRequest *request){
digitalWrite(ledPin, HIGH);
request->send(SPIFFS, "/index.html", String(),false, processor);
});
server.on("/off", HTTP_GET, [](AsyncWebServerRequest *request){
digitalWrite(ledPin, LOW);
request->send(SPIFFS, "/index.html", String(),false, processor);
});
В конце мы используем метод begin() объекта server, чтобы сервер начал прослушивать входящих клиентов.
server.begin();
Поскольку это асинхронный веб-сервер, вы можете определить все запросы в функции setup(). Затем вы можете добавить другой код в loop(), пока сервер прослушивает входящих клиентов.
Загрузка кода и файлов
Сохраните код как Async_ESP32_Web_Server или скачайте все файлы проекта здесь. Перейдите в Sketch > Show Sketch Folder и создайте папку с именем data. Внутри этой папки вы должны сохранить файлы HTML и CSS.
Затем загрузите код на вашу плату ESP32. Убедитесь, что вы выбрали правильную плату и COM-порт. Также убедитесь, что вы добавили ваши сетевые учётные данные в код.
После загрузки кода вам нужно загрузить файлы. Перейдите в Tools > ESP32 Data Sketch Upload и дождитесь загрузки файлов.
Когда всё успешно загружено, откройте монитор порта на скорости 115200 бод. Нажмите кнопку « ENABLE « на ESP32, и он должен вывести IP-адрес ESP32.
Демонстрация
Откройте ваш браузер и введите IP-адрес ESP32. Нажмите кнопки ON и OFF для управления встроенным светодиодом ESP32. Также проверьте, что состояние GPIO обновляется правильно.
Заключение
Использование файловой системы SPI Flash (SPIFFS) особенно полезно для хранения HTML и CSS файлов, которые обслуживаются клиенту – вместо того, чтобы писать весь код внутри скетча Arduino.
Библиотека ESPAsyncWebServer позволяет создать веб-сервер, запуская определённую функцию в ответ на определённый запрос. Вы также можете добавить заполнители в HTML-файл, которые могут быть заменены переменными – например, показаниями датчиков или состояниями GPIO.
Если вам понравился этот проект, вам также могут понравиться:
Это отрывок из нашего курса: Learn ESP32 with Arduino IDE . Если вам нравится ESP32 и вы хотите узнать больше, мы рекомендуем записаться на курс Learn ESP32 with Arduino IDE .
Источник: ESP32 Web Server using SPIFFS (SPI Flash File System)