Веб-сервер ESP8266 с использованием SPIFFS (SPI Flash File System) – NodeMCU

В этом руководстве показано, как создать веб-сервер, который обслуживает HTML и CSS файлы, хранящиеся в файловой системе ESP8266 NodeMCU (SPIFFS), с использованием Arduino IDE. Вместо того чтобы записывать HTML и CSS текст прямо в скетч Arduino, мы создадим отдельные HTML и CSS файлы.

Веб-сервер ESP8266 с использованием SPIFFS (SPI Flash File System) HTML CSS файлы

Веб-сервер, который мы создадим, показывает, как управлять выходами ESP8266 и как отображать показания датчиков. В качестве примера мы будем управлять светодиодом и отображать показания датчика BME280.

Вы можете использовать концепции, изученные в этом руководстве, для управления любым выходом или отображения показаний других датчиков.

Рекомендуемое чтение: Веб-сервер ESP32 с использованием SPIFFS

Обзор проекта

Прежде чем перейти непосредственно к проекту, важно описать, что будет делать наш веб-сервер, чтобы потом было легче понять.

Веб-сервер ESP8266 с SPIFFS демонстрация на смартфоне HTML CSS
  • Веб-сервер управляет светодиодом, подключённым к GPIO 2 ESP8266. Это встроенный светодиод ESP8266. Вы можете управлять любым другим GPIO;

  • На странице веб-сервера отображаются две кнопки: ON и OFF – для включения и выключения GPIO 2;

  • На странице веб-сервера также отображается текущее состояние GPIO;

  • Вы также будете использовать датчик BME280 для отображения показаний датчиков (температура, влажность и давление).

На следующем рисунке показана упрощённая схема, демонстрирующая, как всё работает.

Обзор проекта веб-сервера ESP8266 NodeMCU SPIFFS

Предварительные требования

Перед тем как приступить к этому проекту, убедитесь, что вы выполнили все следующие предварительные требования.

1. Установка платы ESP8266 в Arduino IDE

Мы будем программировать ESP8266 с помощью Arduino IDE, поэтому у вас должно быть установлено дополнение ESP8266. Следуйте следующему руководству для его установки:

2. Плагин загрузчика файловой системы

Для загрузки файлов в файловую систему SPI Flash (SPIFFS) ESP8266 мы будем использовать плагин Filesystem Uploader. Установите плагин в вашу Arduino IDE:

3. Установка библиотек

Один из самых простых способов создать веб-сервер с использованием файлов из файловой системы – это использование библиотеки ESPAsyncWebServer.

Установка библиотеки ESPAsyncWebServer

Эта библиотека недоступна для загрузки через менеджер библиотек Arduino IDE. Поэтому вам нужно выполнить следующие шаги для установки библиотеки:

  1. Нажмите здесь, чтобы скачать библиотеку ESPAsyncWebServer. В папке Загрузки у вас должен появиться .zip файл

  2. Разархивируйте .zip файл, и вы должны получить папку ESPAsyncWebServer-master

  3. Переименуйте папку из ESPAsyncWebServer-master в ESPAsyncWebServer

  4. Переместите папку ESPAsyncWebServer в папку библиотек вашей Arduino IDE

Альтернативно, вы можете перейти в Sketch > Include Library > .zip Library и выбрать ранее загруженную библиотеку.

Установка ESPAsyncTCP

Библиотека ESPAsyncWebServer также нуждается в библиотеке ESPAsyncTCP для правильной работы. Выполните следующие шаги для установки библиотеки ESPAsyncTCP:

  1. Нажмите здесь, чтобы скачать библиотеку ESPAsyncTCP. В папке Загрузки у вас должен появиться .zip файл

  2. Разархивируйте .zip файл, и вы должны получить папку ESPAsyncTCP-master

  3. Переименуйте папку из ESPAsyncTCP-master в ESPAsyncTCP

  4. Переместите папку ESPAsyncTCP в папку библиотек вашей Arduino IDE

  5. Наконец, перезапустите вашу Arduino IDE

Альтернативно, вы можете перейти в Sketch > Include Library > .zip Library и выбрать ранее загруженную библиотеку.

Установка библиотек BME280

В этом руководстве мы будем отображать показания датчика BME280 (Руководство по ESP8266). Вам нужно установить следующие библиотеки:

Вы можете установить эти библиотеки через менеджер библиотек Arduino IDE. Перейдите в Sketch > Include Libraries > Manage Libraries. Затем найдите название библиотеки для её установки.

Необходимые компоненты

ESP8266 NodeMCU BME280 датчик температуры влажности давления светодиод схема

Для выполнения этого проекта вам потребуются следующие компоненты:

Вы можете воспользоваться приведёнными ссылками или перейти непосредственно на MakerAdvisor.com/tools, чтобы найти все компоненты для ваших проектов по лучшей цене!

Схема подключения

Подключите все компоненты, следуя схеме ниже.

Схема подключения ESP8266 NodeMCU BME280 LED

BME280

ESP8266

Vin

3.3V

GND

GND

SCL

GPIO 5

SDA

GPIO 4

Организация файлов

Для создания веб-сервера вам потребуются три разных файла. Скетч Arduino, HTML файл и CSS файл. HTML и CSS файлы должны быть сохранены внутри папки с именем data внутри папки скетча Arduino, как показано ниже:

Организация файлов веб-сервера ESP8266 NodeMCU SPIFFS

Создание HTML файла

Создайте файл index.html со следующим содержимым или скачайте все файлы проекта здесь:

<!DOCTYPE html>
<!--
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com
-->
<html>
<head>
  <title>ESP8266 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>ESP8266 Web Server</h1>
  <p>GPIO state<strong> %STATE%</strong></p>
  <p>
    <a href="/on"><button class="button">ON</button></a>
    <a href="/off"><button class="button button2">OFF</button></a>
  </p>
  <p>
    <span class="sensor-labels">Temperature</span>
    <span id="temperature">%TEMPERATURE%</span>
    <sup class="units">&deg;C</sup>
  </p>
  <p>
    <span class="sensor-labels">Humidity</span>
    <span id="humidity">%HUMIDITY%</span>
    <sup class="units">&#37;</sup>
  </p>
  <p>
    <span class="sensor-labels">Pressure</span>
    <span id="pressure">%PRESSURE%</span>
    <sup class="units">hPa</sup>
  </p>
</body>
<script>
  setInterval(function ( ) {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        document.getElementById("temperature").textContent = this.responseText;
      }
    };
    xhttp.open("GET", "/temperature", true);
    xhttp.send();
  }, 10000 ) ;

  setInterval(function ( ) {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        document.getElementById("humidity").textContent = this.responseText;
      }
    };
    xhttp.open("GET", "/humidity", true);
    xhttp.send();
  }, 10000 ) ;

  setInterval(function ( ) {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        document.getElementById("pressure").textContent = this.responseText;
      }
    };
    xhttp.open("GET", "/pressure", true);
    xhttp.send();
  }, 10000 ) ;
</script>
</html>

Посмотреть исходный код

Поскольку мы используем CSS и HTML в разных файлах, нам нужно указать ссылку на CSS файл в HTML тексте.

<link rel="stylesheet" type="text/css" href="style.css">

Тег <link> сообщает HTML файлу, что вы используете внешнюю таблицу стилей для форматирования внешнего вида страницы. Атрибут rel указывает характер внешнего файла, в данном случае это stylesheet – CSS файл, который будет использоваться для изменения внешнего вида страницы.

Атрибут type установлен в «text/css», чтобы указать, что вы используете CSS файл для стилей. Атрибут href указывает расположение файла; поскольку оба файла CSS и HTML будут находиться в одной папке, вам нужно просто указать имя файла: style.css.

В следующей строке мы пишем первый заголовок нашей веб-страницы. В данном случае это «ESP8266 Web Server». Вы можете изменить заголовок на любой текст:

<h1>ESP8266 Web Server</h1>

Затем добавляем абзац с текстом «GPIO state: «, за которым следует состояние GPIO. Поскольку состояние GPIO изменяется в соответствии с состоянием вывода, мы можем добавить заполнитель (placeholder), который затем будет заменён на любое значение, которое мы зададим в скетче Arduino.

Чтобы добавить заполнитель, используйте знаки %. Для создания заполнителя состояния вы можете использовать %STATE%, например.

<p>GPIO state<strong> %STATE%</strong></p>

Вы присваиваете значение заполнителю STATE в скетче Arduino.

Затем создаём кнопки ON и OFF. Когда вы нажимаете кнопку ON, мы перенаправляем веб-страницу на корневой URL, за которым следует /on. Когда вы нажимаете кнопку OFF, вы перенаправляетесь на URL /off.

<a href="/on"><button class="button">ON</button></a>
<a href="/off"><button class="button button2">OFF</button></a>

Наконец, создаём три абзаца для отображения температуры, влажности и давления.

<p>
  <span class="sensor-labels">Temperature</span>
  <span id="temperature">%TEMPERATURE%</span>
  <sup class="units">&deg;C</sup>
</p>
<p>
  <span class="sensor-labels">Pressure</span>
  <span id="pressure">%PRESSURE%</span>
  <sup class="units">hPa</sup>
</p>
<p>
  <span class="sensor-labels">Humidity</span>
  <span id="humidity">%HUMIDITY%</span>
  <sup class="units">%</sup>
</p>

Мы используем заполнители %TEMPERATURE%, %HUMIDITY% и %PRESSURE%. Они затем будут заменены фактическими показаниями температуры в скетче Arduino.

Автоматическое обновление

Мы также добавляем немного JavaScript в наш HTML файл, который отвечает за обновление показаний температуры без необходимости обновлять веб-страницу.

Следующий фрагмент кода отвечает за температуру.

setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperature").textContent = this.responseText;
    }
  };
  xhttp.open("GET", "/temperature", true);
  xhttp.send();
}, 10000 ) ;

Для обновления температуры у нас есть функция setInterval(), которая выполняется каждые 10 секунд.

По сути, она делает запрос на URL /temperature для получения последнего показания температуры.

  xhttp.open("GET", "/temperature", true);
  xhttp.send();
}, 10000 ) ;

Когда значение получено, оно обновляет HTML элемент с идентификатором temperature.

if (this.readyState == 4 && this.status == 200) {
  document.getElementById("temperature").textContent = this.responseText;
}

Подводя итог, предыдущий раздел отвечает за асинхронное обновление температуры. Тот же процесс повторяется для показаний влажности и давления.

Создание CSS файла

Создайте файл style.css со следующим содержимым или скачайте все файлы проекта здесь:

/***
   Rui Santos
   Complete project details at https://RandomNerdTutorials.com
***/

html {
  font-family: Arial;
  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;
}
.units {
  font-size: 1.2rem;
 }
.sensor-labels {
  font-size: 1.5rem;
  vertical-align:middle;
  padding-bottom: 15px;
}

Посмотреть исходный код

Это просто базовый CSS файл для настройки размера шрифта, стиля и цвета кнопок, а также для выравнивания страницы. Мы не будем объяснять, как работает CSS. Хорошее место для изучения CSS – это сайт W3Schools.

Скетч асинхронного веб-сервера ESP8266

Скопируйте следующий код в Arduino IDE или скачайте все файлы проекта здесь. Затем вам нужно ввести учётные данные вашей сети (SSID и пароль) для подключения ESP8266 к вашей локальной сети.

/*
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/

// Import required libraries
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <FS.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

// 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);

String getTemperature() {
  float temperature = bme.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  //float temperature = 1.8 * bme.readTemperature() + 32;
  Serial.println(temperature);
  return String(temperature);
}

String getHumidity() {
  float humidity = bme.readHumidity();
  Serial.println(humidity);
  return String(humidity);
}

String getPressure() {
  float pressure = bme.readPressure()/ 100.0F;
  Serial.println(pressure);
  return String(pressure);
}

// 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;
  }
  else if (var == "TEMPERATURE"){
    return getTemperature();
  }
  else if (var == "HUMIDITY"){
    return getHumidity();
  }
  else if (var == "PRESSURE"){
    return getPressure();
  }
  return String();
}

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);

  // Initialize the sensor
  if (!bme.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }

  // Initialize SPIFFS
  if(!SPIFFS.begin()){
    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);
  });

  server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(200, "text/plain", getTemperature().c_str());
  });

  server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(200, "text/plain", getHumidity().c_str());
  });

  server.on("/pressure", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(200, "text/plain", getPressure().c_str());
  });

  // Start server
  server.begin();
}

void loop(){

}

Посмотреть исходный код

Как работает код

Продолжайте чтение, чтобы узнать, как работает код, или перейдите к следующему разделу.

Сначала подключаем необходимые библиотеки:

#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <FS.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

Вам нужно ввести учётные данные вашей сети в следующие переменные:

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Создаём экземпляр, ссылающийся на датчик BME280, под именем bme:

Adafruit_BME280 bme; // I2C

Далее создаём переменную, ссылающуюся на GPIO 2, с именем ledPin, и строковую переменную для хранения состояния светодиода: ledState.

const int ledPin = 2;
String ledState;

Создаём объект AsyncWebServer с именем server, который слушает порт 80.

AsyncWebServer server(80);

Получение показаний датчиков

Мы создаём три функции для возврата показаний датчиков в виде строк: функции getTemperature(), getHumidity() и getPressure().

Вот как выглядит функция getTemperature() (остальные функции аналогичны).

String getTemperature() {
  float temperature = bme.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  //float temperature = 1.8 * bme.readTemperature() + 32;
  Serial.println(temperature);
  return String(temperature);
}

Если вы хотите отображать температуру в градусах Фаренгейта, вам просто нужно раскомментировать соответствующую строку в функции getTemperature():

float temperature = 1.8 * bme.readTemperature() + 32;

Чтобы узнать больше о работе с датчиком BME280 и ESP8266, вы можете прочитать следующее руководство:

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;
  }
  else if (var == "TEMPERATURE"){
    return getTemperature();
  }
  else if (var == "HUMIDITY"){
    return getHumidity();
  }
  else if (var == "PRESSURE"){
    return getPressure();
  }
}

Эта функция сначала проверяет, является ли заполнитель тем STATE, который мы создали в HTML файле.

if(var == "STATE"){

Если да, то в зависимости от состояния светодиода мы устанавливаем переменную ledState в значение ON или OFF.

if(digitalRead(ledPin)){
  ledState = "ON";
}
else{
  ledState = "OFF";
}

Наконец, мы возвращаем переменную ledState. Это заменяет заполнитель STATE строковым значением ledState.

return ledState;

Если функция находит заполнитель %TEMPERATURE%, мы возвращаем температуру, вызывая созданную ранее функцию getTemperature().

else if (var == "TEMPERATURE"){
  return getTemperature();
}

То же самое происходит для заполнителей %HUMIDITY% и %PRESSURE% при вызове соответствующих функций:

else if (var == "TEMPERATURE"){
  return getTemperature();
}
else if (var == "HUMIDITY"){
  return getHumidity();
}
else if (var == "PRESSURE"){
  return getPressure();
}

setup()

В функции setup() начинаем с инициализации Serial Monitor и установки GPIO в качестве выхода.

Serial.begin(115200);
pinMode(ledPin, OUTPUT);

Инициализируем датчик BME280:

if (!bme.begin(0x76)) {
  Serial.println("Could not find a valid BME280 sensor, check wiring!");
  while (1);
}

Инициализируем SPIFFS:

if(!SPIFFS.begin()){
  Serial.println("An Error has occurred while mounting SPIFFS");
  return;
}

Подключение к Wi-Fi

Подключаемся к Wi-Fi и выводим адрес ESP8266:

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);
});

В HTML файле мы написали JavaScript код, который запрашивает температуру, влажность и давление по маршрутам /temperature, /humidity, /pressure соответственно, каждые 10 секунд. Поэтому нам также нужно определить, что происходит при получении запроса на эти маршруты.

Нам просто нужно отправить обновлённые показания датчиков. Обновлённые показания возвращаются функциями getTemperature(), getHumidity() и getPressure(), которые мы создали ранее.

Показания являются простым текстом и должны быть отправлены как char, поэтому мы используем метод c_str().

server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send_P(200, "text/plain", getTemperature().c_str());
});

server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send_P(200, "text/plain", getHumidity().c_str());
});

server.on("/pressure", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send_P(200, "text/plain", getPressure().c_str());
});

В конце мы используем метод begin() объекта server, чтобы сервер начал прослушивать входящих клиентов.

server.begin();

Поскольку это асинхронный веб-сервер, вы можете определить все запросы в функции setup(). Затем вы можете добавить другой код в loop(), пока сервер прослушивает входящих клиентов.

Загрузка кода и файлов

Сохраните скетч Arduino как ESP8266_SPIFFS_Web_Server или скачайте все файлы проекта здесь.

  • Перейдите в Sketch > Show Sketch folder и создайте папку с именем data. Сохраните HTML и CSS файлы внутри этой папки;

  • В Tools > Board выберите используемую плату ESP8266;

  • Затем перейдите в Tools > Flash size и выберите 4M (1M SPIFFS).

Выбор платы ESP8266 NodeMCU с SPIFFS в Arduino IDE

Наконец, загрузите файлы на вашу плату. Перейдите в Tools > ESP8266 Data Sketch Upload и дождитесь загрузки файлов.

Загрузка файлов в ESP8266 NodeMCU SPIFFS ESP8266 Sketch Data Upload

Затем нажмите кнопку загрузки в Arduino IDE, чтобы загрузить код на ESP8266.

Загрузка кода Arduino IDE в ESP8266 NodeMCU

Когда всё успешно загружено, откройте Serial Monitor на скорости 115200 бод. Нажмите встроенную кнопку RST на ESP8266, и он должен вывести IP-адрес ESP8266.

IP-адрес ESP8266 NodeMCU Serial Monitor Arduino IDE

Демонстрация

Откройте браузер и введите IP-адрес вашего ESP8266. Должна загрузиться следующая веб-страница.

Веб-сервер ESP8266 с использованием SPIFFS демонстрация HTML CSS

Нажмите кнопки ON и OFF для управления встроенным светодиодом ESP8266. Вы также можете видеть последние показания датчиков. Показания датчиков обновляются автоматически без необходимости обновлять веб-страницу.

Заключение

Использование файловой системы SPI Flash (SPIFFS) ESP8266 особенно полезно для хранения HTML и CSS файлов для обслуживания клиенту – вместо того чтобы записывать весь код прямо в скетч Arduino.

У нас есть другие связанные проекты, которые могут вам понравиться:

Узнайте больше об ESP8266:

Спасибо за чтение.