ESP32 Веб-сервер с использованием Server-Sent Events (автоматическое обновление показаний датчиков)
В этом руководстве показано, как использовать Server-Sent Events (SSE) в веб-сервере ESP32, запрограммированном в Arduino IDE. SSE позволяет браузеру получать автоматические обновления от сервера через HTTP-соединение. Это полезно для отправки обновленных показаний датчиков в браузер, например. Каждый раз, когда доступно новое показание, ESP32 отправляет его клиенту, и веб-страница может обновляться автоматически без необходимости выполнения дополнительных запросов.
В качестве примера мы создадим веб-сервер, который отображает показания датчика BME280 – температуру, влажность и давление. Чтобы узнать больше о BME280, прочитайте наше руководство:
У нас также есть аналогичное руководство по Server-Sent Events для ESP8266.
Введение в Server-Sent Events (SSE)
Server-Sent Events (SSE) позволяют клиенту получать автоматические обновления от сервера через HTTP-соединение.
Клиент инициирует SSE-соединение, и сервер использует протокол event source для отправки обновлений клиенту. Клиент будет получать обновления от сервера, но не может отправлять какие-либо данные на сервер после первоначального рукопожатия (handshake).
Это полезно для отправки обновленных показаний датчиков в браузер. Каждый раз, когда доступно новое показание, ESP32 отправляет его клиенту, и веб-страница может обновляться автоматически без необходимости выполнения дополнительных запросов. Вместо показаний датчиков вы можете отправлять любые данные, которые могут быть полезны для вашего проекта, например состояния GPIO, уведомления при обнаружении движения и т.д.
Важно: Server-Sent Events (SSE) не поддерживаются в Internet Explorer.
Обзор проекта
Вот веб-страница, которую мы создадим для этого проекта.
Веб-сервер ESP32 отображает три карточки с показаниями температуры, влажности и давления от датчика BME280;
ESP32 получает новые показания от датчика каждые 30 секунд;
Каждый раз, когда доступно новое показание, плата (сервер) отправляет его клиенту с помощью server-sent events;
Клиент получает данные и соответствующим образом обновляет веб-страницу;
Это позволяет веб-странице обновляться автоматически при появлении новых показаний.
Как это работает?
Следующая диаграмма обобщает работу Server-Sent Events для обновления веб-страницы.
Клиент инициирует SSE-соединение, и сервер использует протокол event source по URL /events для отправки обновлений клиенту;
ESP32 получает новые показания датчиков;
Он отправляет показания в виде событий с именами: „temperature“, „humidity“ и „pressure“ клиенту;
У клиента есть обработчики событий для событий, отправляемых сервером, и он получает обновленные показания датчиков по этим событиям;
Он обновляет веб-страницу с новейшими показаниями.
Подготовка Arduino IDE
Мы будем программировать плату ESP32 с помощью Arduino IDE, поэтому убедитесь, что она установлена в вашей Arduino IDE.
Установка библиотек – Async Web Server
Для создания веб-сервера мы будем использовать библиотеку ESPAsyncWebServer (от ESP32Async). Эта библиотека требует AsyncTCP (от ESP32Async).
Вы можете установить эти библиотеки в менеджере библиотек Arduino. Откройте менеджер библиотек, нажав на значок библиотеки на левой боковой панели.
Найдите ESPAsyncWebServer и установите ESPAsyncWebServer от ESP32Async.
Затем установите библиотеку AsyncTCP. Найдите AsyncTCP и установите AsyncTCP от ESP32Async.
Установка библиотек – датчик BME280
Для получения показаний от модуля датчика BME280 мы будем использовать библиотеку Adafruit_BME280. Вам также необходимо установить библиотеку Adafruit_Sensor.
Вы также можете установить эти библиотеки через менеджер библиотек Arduino IDE.
Чтобы узнать больше о датчике BME280, прочитайте наше руководство: ESP32 with BME280 Sensor using Arduino IDE (Pressure, Temperature, Humidity).
Сборка схемы
Чтобы продемонстрировать использование server-sent events с ESP32, мы будем отправлять показания датчика BME280 в браузер. Поэтому вам нужно подключить датчик BME280 к вашему ESP32.
Необходимые компоненты
Для выполнения этого руководства вам понадобятся следующие компоненты:
Схема подключения
Мы будем использовать I2C-связь с модулем датчика BME280. Для этого подключите датчик к стандартным выводам ESP32 SCL (GPIO 22) и SDA (GPIO 21), как показано на следующей схеме.
Рекомендуемое чтение: ESP32 Pinout Reference: Which GPIO pins should you use?
Код для веб-сервера ESP32 с использованием Server-Sent Events (SSE)
Скопируйте следующий код в вашу Arduino IDE.
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-web-server-sent-events-sse/
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.
*********/
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
// Create an Event Source on /events
AsyncEventSource events("/events");
// Timer variables
unsigned long lastTime = 0;
unsigned long timerDelay = 30000;
// Create a sensor object
Adafruit_BME280 bme; // BME280 connect to ESP32 I2C (GPIO 21 = SDA, GPIO 22 = SCL)
float temperature;
float humidity;
float pressure;
// Init BME280
void initBME(){
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
}
void getSensorReadings(){
temperature = bme.readTemperature();
// Convert temperature to Fahrenheit
//temperature = 1.8 * bme.readTemperature() + 32;
humidity = bme.readHumidity();
pressure = bme.readPressure()/ 100.0F;
}
// Initialize WiFi
void initWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
Serial.println(WiFi.localIP());
}
String processor(const String& var){
getSensorReadings();
//Serial.println(var);
if(var == "TEMPERATURE"){
return String(temperature);
}
else if(var == "HUMIDITY"){
return String(humidity);
}
else if(var == "PRESSURE"){
return String(pressure);
}
return String();
}
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<title>ESP Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<link rel="icon" href="data:,">
<style>
html {font-family: Arial; display: inline-block; text-align: center;}
p { font-size: 1.2rem;}
body { margin: 0;}
.topnav { overflow: hidden; background-color: #50B8B4; color: white; font-size: 1rem; }
.content { padding: 20px; }
.card { background-color: white; box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5); }
.cards { max-width: 800px; margin: 0 auto; display: grid; grid-gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.reading { font-size: 1.4rem; }
</style>
</head>
<body>
<div class="topnav">
<h1>BME280 WEB SERVER (SSE)</h1>
</div>
<div class="content">
<div class="cards">
<div class="card">
<p><i class="fas fa-thermometer-half" style="color:#059e8a;"></i> TEMPERATURE</p><p><span class="reading"><span id="temp">%TEMPERATURE%</span> °C</span></p>
</div>
<div class="card">
<p><i class="fas fa-tint" style="color:#00add6;"></i> HUMIDITY</p><p><span class="reading"><span id="hum">%HUMIDITY%</span> %</span></p>
</div>
<div class="card">
<p><i class="fas fa-angle-double-down" style="color:#e1e437;"></i> PRESSURE</p><p><span class="reading"><span id="pres">%PRESSURE%</span> hPa</span></p>
</div>
</div>
</div>
<script>
if (!!window.EventSource) {
var source = new EventSource('/events');
source.addEventListener('open', function(e) {
console.log("Events Connected");
}, false);
source.addEventListener('error', function(e) {
if (e.target.readyState != EventSource.OPEN) {
console.log("Events Disconnected");
}
}, false);
source.addEventListener('message', function(e) {
console.log("message", e.data);
}, false);
source.addEventListener('temperature', function(e) {
console.log("temperature", e.data);
document.getElementById("temp").textContent = e.data;
}, false);
source.addEventListener('humidity', function(e) {
console.log("humidity", e.data);
document.getElementById("hum").textContent = e.data;
}, false);
source.addEventListener('pressure', function(e) {
console.log("pressure", e.data);
document.getElementById("pres").textContent = e.data;
}, false);
}
</script>
</body>
</html>)rawliteral";
void setup() {
Serial.begin(115200);
initWiFi();
initBME();
// Handle Web Server
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/html", index_html, processor);
});
// Handle Web Server Events
events.onConnect([](AsyncEventSourceClient *client){
if(client->lastId()){
Serial.printf("Client reconnected! Last message ID that it got is: %u\n", client->lastId());
}
// send event with message "hello!", id current millis
// and set reconnect delay to 1 second
client->send("hello!", NULL, millis(), 10000);
});
server.addHandler(&events);
server.begin();
}
void loop() {
if ((millis() - lastTime) > timerDelay) {
getSensorReadings();
Serial.printf("Temperature = %.2f ºC \n", temperature);
Serial.printf("Humidity = %.2f \n", humidity);
Serial.printf("Pressure = %.2f hPa \n", pressure);
Serial.println();
// Send Events to the Web Client with the Sensor Readings
events.send("ping",NULL,millis());
events.send(String(temperature).c_str(),"temperature",millis());
events.send(String(humidity).c_str(),"humidity",millis());
events.send(String(pressure).c_str(),"pressure",millis());
lastTime = millis();
}
}
Вставьте ваши сетевые учетные данные в следующие переменные, и код будет работать сразу.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Как работает код
Продолжайте чтение, чтобы узнать, как работает код, или перейдите к разделу Демонстрация.
Подключение библиотек
Библиотеки Adafruit_Sensor и Adafruit_BME280 необходимы для работы с датчиком BME280.
#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>
Библиотеки WiFi, ESPAsyncWebServer и AsyncTCP используются для создания веб-сервера.
#include <WiFi.h>
#include "ESPAsyncWebServer.h"
Сетевые учетные данные
Вставьте ваши сетевые учетные данные в следующие переменные, чтобы ESP32 мог подключиться к вашей локальной сети по Wi-Fi.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
AsyncWebServer и AsyncEventSource
Создайте объект AsyncWebServer на порту 80.
AsyncWebServer server(80);
Следующая строка создает новый источник событий (event source) по адресу /events.
AsyncEventSource events("/events");
Объявление переменных
Переменные lastTime и timerDelay будут использоваться для обновления показаний датчиков каждые X секунд. В качестве примера мы будем получать новые показания каждые 30 секунд (30000 миллисекунд). Вы можете изменить это время задержки в переменной timerDelay.
unsigned long lastTime = 0;
unsigned long timerDelay = 30000;
Создайте объект Adafruit_BME280 с именем bme на стандартных выводах I2C ESP32.
Adafruit_BME280 bme;
Переменные типа float – temperature, humidity и pressure – будут использоваться для хранения показаний датчика BME280.
float temperature;
float humidity;
float pressure;
Инициализация BME280
Следующая функция может быть вызвана для инициализации датчика BME280.
void initBME(){
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
}
Получение показаний BME280
Функция getSensorReadings() получает показания температуры, влажности и давления от датчика BME280 и сохраняет их в переменных temperature, humidity и pressure.
void getSensorReadings(){
temperature = bme.readTemperature();
// Convert temperature to Fahrenheit
//temperature = 1.8 * bme.readTemperature() + 32;
humidity = bme.readHumidity();
pressure = bme.readPressure()/ 100.0F;
}
Инициализация Wi-Fi
Следующая функция устанавливает ESP32 в режим Wi-Fi станции и подключается к вашему маршрутизатору, используя ssid и password, определенные ранее.
void initWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
Serial.println(WiFi.localIP());
}
Обработчик (Processor)
Функция processor() заменяет все заполнители (placeholders) в HTML-тексте, используемом для создания веб-страницы, текущими показаниями датчиков перед отправкой в браузер.
String processor(const String& var){
getSensorReadings();
//Serial.println(var);
if(var == "TEMPERATURE"){
return String(temperature);
}
else if(var == "HUMIDITY"){
return String(humidity);
}
else if(var == "PRESSURE"){
return String(pressure);
}
}
Это позволяет отображать текущие показания датчиков на веб-странице при первом обращении к ней. В противном случае вы увидите пустое место до тех пор, пока не появятся новые показания (что может занять некоторое время в зависимости от времени задержки, определенного в коде).
Создание веб-страницы
Переменная index_html содержит весь HTML, CSS и JavaScript для создания веб-страницы.
Примечание: для простоты данного руководства мы размещаем все необходимое для создания веб-страницы в переменной index_html, которую используем в скетче Arduino. Обратите внимание, что на практике может быть удобнее иметь отдельные файлы HTML, CSS и JavaScript, которые затем загружаются в файловую систему ESP32 и на них ссылаются в коде.
Вот содержимое переменной index_html:
<!DOCTYPE HTML>
<html>
<head>
<title>ESP Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<link rel="icon" href="data:,">
<style>
html {
font-family: Arial;
display: inline-block;
text-align: center;
}
p {
font-size: 1.2rem;
}
body {
margin: 0;
}
.topnav {
overflow: hidden;
background-color: #50B8B4;
color: white;
font-size: 1rem;
}
.content {
padding: 20px;
}
.card {
background-color: white;
box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);
}
.cards {
max-width: 800px;
margin: 0 auto;
display: grid;
grid-gap: 2rem;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.reading {
font-size: 1.4rem;
}
</style>
</head>
<body>
<div class="topnav">
<h1>BME280 WEB SERVER (SSE)</h1>
</div>
<div class="content">
<div class="cards">
<div class="card">
<p><i class="fas fa-thermometer-half" style="color:#059e8a;"></i> TEMPERATURE</p>
<p><span class="reading"><span id="temp">%TEMPERATURE%</span> °C</span></p>
</div>
<div class="card">
<p><i class="fas fa-tint" style="color:#00add6;"></i> HUMIDITY</p>
<p><span class="reading"><span id="hum">%HUMIDITY%</span> %</span></p>
</div>
<div class="card">
<p><i class="fas fa-angle-double-down" style="color:#e1e437;"></i> PRESSURE</p><p><span class="reading"><span id="pres">%PRESSURE%</span> hPa</span></p>
</div>
</div>
</div>
<script>
if (!!window.EventSource) {
var source = new EventSource('/events');
source.addEventListener('open', function(e) {
console.log("Events Connected");
}, false);
source.addEventListener('error', function(e) {
if (e.target.readyState != EventSource.OPEN) {
console.log("Events Disconnected");
}
}, false);
source.addEventListener('message', function(e) {
console.log("message", e.data);
}, false);
source.addEventListener('temperature', function(e) {
console.log("temperature", e.data);
document.getElementById("temp").textContent = e.data;
}, false);
source.addEventListener('humidity', function(e) {
console.log("humidity", e.data);
document.getElementById("hum").textContent = e.data;
}, false);
source.addEventListener('pressure', function(e) {
console.log("pressure", e.data);
document.getElementById("pres").textContent = e.data;
}, false);
}
</script>
</body>
</html>
Мы не будем подробно рассматривать, как работают HTML и CSS. Мы просто рассмотрим, как обрабатывать события, отправляемые сервером.
CSS
Между тегами <style></style> мы включаем стили для оформления веб-страницы с помощью CSS. Не стесняйтесь изменять их, чтобы веб-страница выглядела так, как вы хотите. Мы не будем объяснять, как работает CSS для этой веб-страницы, так как это не относится к теме данного руководства.
<style>
html {
font-family: Arial;
display: inline-block;
text-align: center;
}
p {
font-size: 1.2rem;
}
body {
margin: 0;
}
.topnav {
overflow: hidden;
background-color: #50B8B4;
color: white;
font-size: 1rem;
}
.content {
padding: 20px;
}
.card {
background-color: white;
box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);
}
.cards {
max-width: 800px;
margin: 0 auto;
display: grid;
grid-gap: 2rem;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.reading {
font-size: 1.4rem;
}
</style>
HTML
Между тегами <body></body> мы добавляем содержимое веб-страницы, видимое пользователю.
<body>
<div class="topnav">
<h1>BME280 WEB SERVER (SSE)</h1>
</div>
<div class="content">
<div class="cards">
<div class="card">
<p><i class="fas fa-thermometer-half" style="color:#059e8a;"></i> TEMPERATURE</p>
<p><span class="reading"><span id="temp">%TEMPERATURE%</span> °C</span></p>
</div>
<div class="card">
<p><i class="fas fa-tint" style="color:#00add6;"></i> HUMIDITY</p>
<p><span class="reading"><span id="hum">%HUMIDITY%</span> %</span></p>
</div>
<div class="card">
<p><i class="fas fa-angle-double-down" style="color:#e1e437;"></i> PRESSURE</p><p><span class="reading"><span id="pres">%PRESSURE%</span> hPa</span></p>
</div>
</div>
</div>
Есть заголовок первого уровня с содержимым «BME280 WEB SERVER (SSE)». Это текст, который отображается на верхней панели. Вы можете изменить этот текст.
<h1>BME280 WEB SERVER (SSE)</h1>
Затем мы отображаем показания датчиков в отдельных тегах div. Давайте кратко рассмотрим параграфы, отображающие температуру:
<p><i class="fas fa-thermometer-half" style="color:#059e8a;"></i> TEMPERATURE</p>
<p><span class="reading"><span id="temp">%TEMPERATURE%</span> °C</span></p>
Первый параграф просто отображает текст «TEMPERATURE». Мы определяем цвет и иконку.
Во втором параграфе вы можете видеть, что заполнитель %TEMPERATURE% обернут тегами <span id=»temp»></span>. HTML-атрибут id используется для указания уникального идентификатора HTML-элемента.
Он используется для указания на определенный стиль или может быть использован JavaScript для доступа к элементу с определенным id и манипуляции им. Именно это мы и будем делать. Например, когда клиент получает новое событие с последним показанием температуры, он обновляет HTML-элемент с id «temp» новым значением.
Аналогичный процесс выполняется для обновления остальных показаний.
JavaScript – EventSource
JavaScript находится между тегами <script></script>. Он отвечает за инициализацию соединения EventSource с сервером и обработку событий, полученных от сервера.
<script>
if (!!window.EventSource) {
var source = new EventSource('/events');
source.addEventListener('open', function(e) {
console.log("Events Connected");
}, false);
source.addEventListener('error', function(e) {
if (e.target.readyState != EventSource.OPEN) {
console.log("Events Disconnected");
}
}, false);
source.addEventListener('message', function(e) {
console.log("message", e.data);
}, false);
source.addEventListener('temperature', function(e) {
console.log("temperature", e.data);
document.getElementById("temp").textContent = e.data;
}, false);
source.addEventListener('humidity', function(e) {
console.log("humidity", e.data);
document.getElementById("hum").textContent = e.data;
}, false);
source.addEventListener('pressure', function(e) {
console.log("pressure", e.data);
document.getElementById("pres").textContent = e.data;
}, false);
}
</script>
Давайте рассмотрим, как это работает.
Обработка событий
Создайте новый объект EventSource и укажите URL страницы, отправляющей обновления. В нашем случае это /events.
if (!!window.EventSource) {
var source = new EventSource('/events');
После создания экземпляра event source вы можете начать прослушивание сообщений от сервера с помощью addEventListener().
Это обработчики событий по умолчанию, как показано в документации AsyncWebServer.
source.addEventListener('open', function(e) {
console.log("Events Connected");
}, false);
source.addEventListener('error', function(e) {
if (e.target.readyState != EventSource.OPEN) {
console.log("Events Disconnected");
}
}, false);
source.addEventListener('message', function(e) {
console.log("message", e.data);
}, false);
Затем добавьте обработчик события для «temperature».
source.addEventListener('temperature', function(e) {
Когда доступно новое показание температуры, ESP32 отправляет событие («temperature») клиенту. Следующие строки определяют, что происходит, когда браузер получает это событие.
console.log("temperature", e.data);
document.getElementById("temp").textContent = e.data;
По сути, новые показания выводятся в консоль браузера, а полученные данные помещаются в элемент с соответствующим id («temp») на веб-странице.
Аналогичный обработчик используется для влажности и давления.
source.addEventListener('humidity', function(e) {
console.log("humidity", e.data);
document.getElementById("hum").textContent = e.data;
}, false);
source.addEventListener('pressure', function(e) {
console.log("pressure", e.data);
document.getElementById("pres").textContent = e.data;
}, false);
source.addEventListener('gas', function(e) {
console.log("gas", e.data);
document.getElementById("gas").textContent = e.data;
}, false);
setup()
В функции setup() инициализируйте монитор последовательного порта, Wi-Fi и датчик BME280.
Serial.begin(115200);
initWiFi();
initBME();
Обработка запросов
Когда вы обращаетесь к IP-адресу ESP32 по корневому URL /, отправляется текст, хранящийся в переменной index_html, для создания веб-страницы, а функция processor передается в качестве аргумента, чтобы все заполнители были заменены последними показаниями датчиков.
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/html", index_html, processor);
});
Источник событий сервера
Настройте источник событий на сервере.
// Handle Web Server Events
events.onConnect([](AsyncEventSourceClient *client){
if(client->lastId()){
Serial.printf("Client reconnected! Last message ID that it got is: %u\n", client->lastId());
}
// send event with message "hello!", id current millis
// and set reconnect delay to 1 second
client->send("hello!", NULL, millis(), 10000);
});
server.addHandler(&events);
Наконец, запустите сервер.
server.begin();
loop()
В функции loop() получаем новые показания датчиков:
getSensorReadings();
Выводим новые показания в монитор последовательного порта.
Serial.printf("Temperature = %.2f ºC \n", temperature);
Serial.printf("Humidity = %.2f % \n", humidity);
Serial.printf("Pressure = %.2f hPa \n", pressure);
Serial.println();
Наконец, отправляем события в браузер с новейшими показаниями датчиков для обновления веб-страницы.
// Send Events to the Web Server with the Sensor Readings
events.send("ping",NULL,millis());
events.send(String(temperature).c_str(),"temperature",millis());
events.send(String(humidity).c_str(),"humidity",millis());
events.send(String(pressure).c_str(),"pressure",millis());
Демонстрация
После ввода ваших сетевых учетных данных в переменные ssid и password вы можете загрузить код на вашу плату. Не забудьте проверить, что выбрана правильная плата и COM-порт.
После загрузки кода откройте монитор последовательного порта на скорости 115200 бод и нажмите встроенную кнопку EN/RST. Должен отобразиться IP-адрес ESP.
Откройте браузер в вашей локальной сети и введите IP-адрес ESP32. Вы должны получить доступ к веб-странице для мониторинга показаний датчиков.
Показания обновляются автоматически каждые 30 секунд.
В то же время вы должны получать новые показания датчиков в мониторе последовательного порта, как показано на предыдущем снимке экрана. Кроме того, вы можете проверить, получает ли клиент события. В вашем браузере откройте консоль, нажав Ctrl + Shift + J.
Заключение
В этом руководстве вы узнали, как использовать Server-Sent Events с ESP32. Server-Sent Events позволяют веб-странице (клиенту) получать обновления от сервера. Это может использоваться для автоматического отображения новых показаний датчиков на странице веб-сервера, когда они доступны.
У нас есть аналогичное руководство, но с использованием датчика окружающей среды BME680. Вы можете ознакомиться с ним по следующей ссылке:
Вместо Server-Sent Events вы также можете использовать протокол WebSocket для поддержания веб-страницы в актуальном состоянии. Ознакомьтесь со следующим руководством, чтобы узнать, как настроить WebSocket-сервер с ESP32:
Узнайте больше о ESP32 с помощью наших ресурсов:
Источник: ESP32 Web Server using Server-Sent Events (Update Sensor Readings Automatically)