Веб-сервер ESP8266 с DHT11/DHT22 – Температура и влажность с использованием Arduino IDE
В этом проекте вы создадите автономный веб-сервер на ESP8266, который отображает температуру и влажность с датчика DHT11 или DHT22 с использованием Arduino IDE. Веб-сервер, который вы создадите, доступен с любого устройства с браузером в вашей локальной сети.
В этом руководстве мы покажем, как создать два разных веб-сервера:
Веб-сервер #1: Асинхронный веб-сервер, который автоматически обновляет температуру и влажность без необходимости обновлять веб-страницу, с пользовательским CSS для стилизации веб-страницы.
Веб-сервер #2: Простой HTTP-веб-сервер, который отображает последние показания датчика при обновлении страницы в виде простого HTML.
Рекомендуемые ресурсы:
Узнайте больше о ESP8266 в нашем курсе: Home Automation using ESP8266.
Необходимые компоненты
Для сборки этого проекта вам понадобятся следующие компоненты:
Вы можете использовать ссылки выше или перейти непосредственно на MakerAdvisor.com/tools, чтобы найти все компоненты для ваших проектов по лучшей цене!
Схема подключения ESP8266 и DHT11/DHT22
Перед тем как приступить к руководству, подключите датчик температуры и влажности DHT11 или DHT22 к ESP8266, как показано на следующей схеме.
В данном примере мы подключаем вывод данных DHT к GPIO5 (D1), но вы можете использовать любой другой подходящий GPIO. Прочитайте наше Руководство по GPIO ESP8266, чтобы узнать больше о GPIO ESP8266.
Если вы используете ESP-01, GPIO 2 — наиболее подходящий вывод для подключения к выводу данных DHT, как показано на следующей схеме.
Установка библиотеки DHT для ESP8266
Для считывания данных с датчика DHT мы будем использовать библиотеку DHT от Adafruit. Для работы этой библиотеки также необходимо установить библиотеку Adafruit Unified Sensor. Выполните следующие шаги для установки этих библиотек.
Откройте Arduino IDE и перейдите в Sketch > Include Library > Manage Libraries. Должен открыться менеджер библиотек.
Введите «DHT» в поле поиска и установите библиотеку DHT от Adafruit.
После установки библиотеки DHT от Adafruit введите «Adafruit Unified Sensor» в поле поиска. Прокрутите вниз до конца, чтобы найти библиотеку, и установите её.
После установки библиотек перезапустите Arduino IDE.
1. Асинхронный веб-сервер ESP8266
Для создания веб-сервера мы будем использовать библиотеку ESPAsyncWebServer, которая предоставляет простой способ создания асинхронного веб-сервера. Создание асинхронного веб-сервера имеет ряд преимуществ. Рекомендуем быстро ознакомиться с документацией библиотеки на странице GitHub.
Установка библиотек веб-сервера
Мы будем создавать веб-сервер с использованием следующих библиотек:
Вы можете установить эти библиотеки через менеджер библиотек Arduino IDE. Перейдите в Sketch > Include Library > Manage Libraries и найдите библиотеки по названию.
Код
Мы будем программировать ESP8266 с помощью Arduino IDE, поэтому у вас должно быть установлено дополнение ESP8266 в Arduino IDE. Если его нет, сначала следуйте этому руководству:
Откройте Arduino IDE и скопируйте следующий код.
/*********
Rui Santos
Complete project details at https://randomnerdtutorials.com/esp8266-dht11dht22-temperature-and-humidity-web-server-with-arduino-ide/
*********/
// Import required libraries
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Hash.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
#define DHTPIN 5 // Digital pin connected to the DHT sensor
// Uncomment the type of sensor in use:
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
DHT dht(DHTPIN, DHTTYPE);
// current temperature & humidity, updated in loop()
float t = 0.0;
float h = 0.0;
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time DHT was updated
// Updates DHT readings every 10 seconds
const long interval = 10000;
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<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">
<style>
html {
font-family: Arial;
display: inline-block;
margin: 0px auto;
text-align: center;
}
h2 { font-size: 3.0rem; }
p { font-size: 3.0rem; }
.units { font-size: 1.2rem; }
.dht-labels{
font-size: 1.5rem;
vertical-align:middle;
padding-bottom: 15px;
}
</style>
</head>
<body>
<h2>ESP8266 DHT Server</h2>
<p>
<i class="fas fa-thermometer-half" style="color:#059e8a;"></i>
<span class="dht-labels">Temperature</span>
<span id="temperature">%TEMPERATURE%</span>
<sup class="units">°C</sup>
</p>
<p>
<i class="fas fa-tint" style="color:#00add6;"></i>
<span class="dht-labels">Humidity</span>
<span id="humidity">%HUMIDITY%</span>
<sup class="units">%</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 ) ;
</script>
</html>)rawliteral";
// Replaces placeholder with DHT values
String processor(const String& var){
//Serial.println(var);
if(var == "TEMPERATURE"){
return String(t);
}
else if(var == "HUMIDITY"){
return String(h);
}
return String();
}
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
dht.begin();
// Connect to Wi-Fi
WiFi.begin(ssid, password);
Serial.println("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println(".");
}
// Print ESP8266 Local IP Address
Serial.println(WiFi.localIP());
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", String(t));
});
server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", String(h));
});
// Start server
server.begin();
}
void loop(){
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you updated the DHT values
previousMillis = currentMillis;
// Read temperature as Celsius (the default)
float newT = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
//float newT = dht.readTemperature(true);
// if temperature read failed, don't change t value
if (isnan(newT)) {
Serial.println("Failed to read from DHT sensor!");
}
else {
t = newT;
Serial.println(t);
}
// Read Humidity
float newH = dht.readHumidity();
// if humidity read failed, don't change h value
if (isnan(newH)) {
Serial.println("Failed to read from DHT sensor!");
}
else {
h = newH;
Serial.println(h);
}
}
}
Вставьте ваши сетевые учётные данные в следующие переменные, и код будет работать сразу.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Как работает код
В следующих параграфах мы объясним, как работает код. Продолжайте чтение, если хотите узнать больше, или перейдите к разделу «Демонстрация», чтобы увидеть конечный результат.
Импорт библиотек
Сначала импортируем необходимые библиотеки.
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Hash.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
Настройка сетевых учётных данных
Вставьте ваши сетевые учётные данные в следующие переменные, чтобы ESP8266 мог подключиться к вашей локальной сети.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Определение переменных
Определите GPIO, к которому подключен вывод данных DHT. В данном случае он подключен к GPIO5 (D1).
#define DHTPIN 5 // Digital pin connected to the DHT sensor
Затем выберите тип используемого датчика DHT. В нашем примере мы используем DHT22. Если вы используете другой тип, вам просто нужно раскомментировать свой датчик и закомментировать все остальные.
#define DHTTYPE DHT22 // DHT 22 (AM2302)
Создайте объект DHT с типом и выводом, определёнными ранее.
DHT dht(DHTPIN, DHTTYPE);
Создайте объект AsyncWebServer на порту 80.
AsyncWebServer server(80);
Создайте переменные типа float для хранения текущих значений температуры и влажности. Температура и влажность обновляются в функции loop().
float t = 0.0;
float h = 0.0;
Создайте переменные таймера, необходимые для обновления показаний температуры каждые 10 секунд.
unsigned long previousMillis = 0; // will store last time DHT was updated
// Updates DHT readings every 10 seconds
const long interval = 10000;
Создание веб-страницы
Перейдём к веб-странице сервера.
Как видно на рисунке выше, веб-страница отображает один заголовок и два абзаца. Один абзац для отображения температуры, а другой — для отображения влажности. Также есть два значка для стилизации страницы.
Давайте посмотрим, как создаётся эта веб-страница.
Весь HTML-текст со стилями хранится в переменной index_html. Теперь мы рассмотрим HTML-текст и узнаем, что делает каждая часть.
Следующий тег <meta> делает вашу веб-страницу адаптивной в любом браузере.
<meta name="viewport" content="width=device-width, initial-scale=1">
Тег <link> необходим для загрузки значков с сайта fontawesome.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
Стили
Между тегами <style></style> мы добавляем CSS для стилизации веб-страницы.
<style>
html {
font-family: Arial;
display: inline-block;
margin: 0px auto;
text-align: center;
}
h2 { font-size: 3.0rem; }
p { font-size: 3.0rem; }
.units { font-size: 1.2rem; }
.dht-labels{
font-size: 1.5rem;
vertical-align:middle;
padding-bottom: 15px;
}
</style>
По сути, мы настраиваем HTML-страницу для отображения текста шрифтом Arial в блочном режиме без отступов, выровненного по центру.
html {
font-family: Arial;
display: inline-block;
margin: 0px auto;
text-align: center;
}
Мы устанавливаем размер шрифта для заголовка (h2), абзаца (p) и единиц измерения (.units) показаний.
h2 { font-size: 3.0rem; }
p { font-size: 3.0rem; }
.units { font-size: 1.2rem; }
Стили для меток показаний выглядят следующим образом:
dht-labels{
font-size: 1.5rem;
vertical-align:middle;
padding-bottom: 15px;
}
Все предыдущие теги должны находиться между тегами <head> и </head>. Эти теги используются для включения содержимого, которое не отображается напрямую пользователю, например, теги <meta>, <link> и стили.
Тело HTML
Внутри тегов <body></body> мы добавляем содержимое веб-страницы.
Теги <h2></h2> добавляют заголовок на веб-страницу. В данном случае это текст «ESP8266 DHT server», но вы можете добавить любой другой текст.
<h2>ESP8266 DHT Server</h2>
Далее идут два абзаца. Один для отображения температуры, другой — для отображения влажности. Абзацы ограничиваются тегами <p> и </p>. Абзац для температуры выглядит следующим образом:
<p>
<i class="fas fa-thermometer-half" style="color:#059e8a;"</i>
<span class="dht-labels">Temperature</span>
<span id="temperature">%TEMPERATURE%</span>
<sup class="units">°C</sup>
</p>
А абзац для влажности — в следующем фрагменте:
<p>
<i class="fas fa-tint" style="color:#00add6;"></i>
<span class="dht-labels">Humidity</span>
<span id="humidity">%HUMIDITY%</span>
<sup class="units">%</sup>
</p>
Теги <i> отображают значки fontawesome.
Как отображать значки
Чтобы выбрать значки, перейдите на сайт Font Awesome Icons.
Найдите нужный значок. Например, «thermometer».
Нажмите на нужный значок. Затем просто скопируйте предоставленный HTML-текст.
<i class="fas fa-thermometer-half">
Чтобы выбрать цвет, вам просто нужно передать параметр style с цветом в шестнадцатеричном формате, как показано ниже:
<i class="fas fa-tint" style="color:#00add6;"></i>
Продолжим с HTML-текстом…
Следующая строка записывает слово «Temperature» на веб-страницу.
<span class="dht-labels">Temperature</span>
Текст TEMPERATURE между знаками % является заполнителем для значения температуры.
<span id="temperature">%TEMPERATURE%</span>
Это означает, что текст %TEMPERATURE% является своеобразной переменной, которая будет заменена фактическим значением температуры с датчика DHT. Заполнители в HTML-тексте должны находиться между знаками %.
Наконец, мы добавляем символ градуса.
<sup class="units">°C</sup>
Теги <sup></sup> делают текст надстрочным.
Мы используем тот же подход для абзаца влажности, но он использует другой значок и заполнитель %HUMIDITY%.
<p>
<i class="fas fa-tint" style="color:#00add6;"></i>
<span class="dht-labels">Humidity</span>
<span id="humidity">%HUMIDITY%</span>
<sup class="units">%</sup>
</p>
Автоматическое обновление
Наконец, в нашей веб-странице есть JavaScript-код, который автоматически обновляет температуру и влажность каждые 10 секунд.
Скрипты в HTML-тексте должны находиться между тегами <script></script>.
<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 ) ;
</script>
Для обновления температуры в фоновом режиме у нас есть функция setInterval(), которая выполняется каждые 10 секунд.
По сути, она отправляет запрос по URL /temperature для получения последнего значения температуры.
xhttp.open("GET", "/temperature", true);
xhttp.send();
}, 10000 ) ;
Когда значение получено, оно обновляет HTML-элемент с id «temperature».
if (this.readyState == 4 && this.status == 200) {
document.getElementById("temperature").textContent = this.responseText;
}
Таким образом, предыдущий раздел отвечает за асинхронное обновление температуры. Тот же процесс повторяется для показаний влажности.
Важно: поскольку датчик DHT довольно медленно получает показания, если вы планируете подключать несколько клиентов к ESP8266 одновременно, мы рекомендуем увеличить интервал запросов или убрать автоматическое обновление.
Процессор
Теперь нам нужно создать функцию processor(), которая будет заменять заполнители в нашем HTML-тексте фактическими значениями температуры и влажности.
String processor(const String& var){
//Serial.println(var);
if(var == "TEMPERATURE"){
return String(t);
}
else if(var == "HUMIDITY"){
return String(h);
}
return String();
}
Когда запрашивается веб-страница, мы проверяем, содержит ли HTML какие-либо заполнители. Если найден заполнитель %TEMPERATURE%, мы возвращаем температуру, хранящуюся в переменной t.
if(var == "TEMPERATURE"){
return String(t);
}
Если заполнитель — %HUMIDITY%, мы возвращаем значение влажности.
else if(var == "HUMIDITY"){
return String(h);
}
setup()
В функции setup() инициализируем Serial Monitor для целей отладки.
Serial.begin(115200);
Инициализируем датчик DHT.
dht.begin();
Подключаемся к локальной сети и выводим IP-адрес ESP8266.
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
Наконец, добавляем следующие строки кода для обработки запросов веб-сервера.
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", String(t));
});
server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", String(h));
});
Когда мы делаем запрос по корневому URL, мы отправляем HTML-текст, хранящийся в переменной index_html (эта переменная хранится во flash-памяти — PROGMEM, поэтому нам нужно использовать функцию send_P()). Нам также нужно передать функцию processor, которая заменит все заполнители правильными значениями.
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
Нам нужно добавить два дополнительных обработчика для обновления показаний температуры и влажности. Когда мы получаем запрос по URL /temperature, нам просто нужно отправить обновлённое значение температуры.
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", String(t));
});
Тот же процесс повторяется для влажности.
server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", String(h));
});
Наконец, мы запускаем сервер.
server.begin();
В функции loop() мы получаем новые показания температуры от датчика каждые 10 секунд.
По сути, мы проверяем, пришло ли время получить новые показания датчика:
if (currentMillis - previousMillis >= interval) {
Если да, мы сохраняем новое значение температуры в переменной newT:
float newT = dht.readTemperature();
Если переменная newT содержит допустимое значение температуры, мы обновляем переменную t.
else {
t = newT;
Serial.println(t);
}
Тот же процесс повторяется для влажности.
// Read Humidity
float newH = dht.readHumidity();
// if humidity read failed, don't change h value
if (isnan(newH)) {
Serial.println("Failed to read from DHT sensor!");
}
else {
h = newH;
Serial.println(h);
}
Вот, в общих чертах, как работает код.
Загрузка кода
После внесения необходимых изменений в скетч, загрузите код на ESP8266 (если вы не можете загрузить код на ESP8266, прочитайте это руководство по устранению неполадок).
Убедитесь, что выбраны правильная плата и COM-порт. Перейдите в Tools > Board и выберите модель ESP8266, которую вы используете. В нашем случае мы используем ESP8266 12-E NodeMCU Kit.
Перейдите в Tools > Port и выберите COM-порт, к которому подключен ESP8266.
Нажмите кнопку загрузки в Arduino IDE.
Примечание: если вы используете ESP-01, вам понадобится последовательный адаптер или FTDI программатор для загрузки кода.
IP-адрес ESP8266
После загрузки кода откройте Serial Monitor на скорости 115200 бод. Нажмите кнопку сброса ESP8266. IP-адрес ESP8266 будет напечатан в Serial Monitor, как показано на следующем рисунке.
Демонстрация
В вашей локальной сети откройте браузер на любом устройстве и введите IP-адрес ESP8266. Должна отобразиться следующая веб-страница с последними показаниями датчика.
Показания температуры и влажности обновляются автоматически каждые 10 секунд без необходимости обновлять веб-страницу.
2. Простой HTTP-веб-сервер ESP8266
В этом разделе мы покажем, как создать простой HTTP-веб-сервер, который отображает температуру и влажность в виде простой HTML-страницы. Этот веб-сервер отправляет HTTP-ответ, когда ваш браузер делает запрос по IP-адресу ESP8266.
Видеодемонстрация
Сначала вы можете посмотреть видеодемонстрацию проекта веб-сервера ESP8266 ниже.
Код
Мы будем программировать ESP8266 с помощью Arduino IDE, поэтому у вас должно быть установлено дополнение ESP8266 в Arduino IDE. Если его нет, сначала следуйте этому руководству.
Откройте Arduino IDE и скопируйте следующий код.
/*********
Rui Santos
Complete project details at https://randomnerdtutorials.com
*********/
// Including the ESP8266 WiFi library
#include <ESP8266WiFi.h>
#include "DHT.h"
// Uncomment one of the lines below for whatever DHT sensor type you're using!
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
//#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
// Replace with your network details
const char* ssid = "YOUR_NETWORK_NAME";
const char* password = "YOUR_NETWORK_PASSWORD";
// Web Server on port 80
WiFiServer server(80);
// DHT Sensor
const int DHTPin = 5;
// Initialize DHT sensor.
DHT dht(DHTPin, DHTTYPE);
// Temporary variables
static char celsiusTemp[7];
static char fahrenheitTemp[7];
static char humidityTemp[7];
// only runs once on boot
void setup() {
// Initializing serial port for debugging purposes
Serial.begin(115200);
delay(10);
dht.begin();
// Connecting to WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Starting the web server
server.begin();
Serial.println("Web server running. Waiting for the ESP IP...");
delay(10000);
// Printing the ESP IP address
Serial.println(WiFi.localIP());
}
// runs over and over again
void loop() {
// Listenning for new clients
WiFiClient client = server.available();
if (client) {
Serial.println("New client");
// bolean to locate when the http request ends
boolean blank_line = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n' && blank_line) {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
float f = dht.readTemperature(true);
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println("Failed to read from DHT sensor!");
strcpy(celsiusTemp,"Failed");
strcpy(fahrenheitTemp, "Failed");
strcpy(humidityTemp, "Failed");
}
else{
// Computes temperature values in Celsius + Fahrenheit and Humidity
float hic = dht.computeHeatIndex(t, h, false);
dtostrf(hic, 6, 2, celsiusTemp);
float hif = dht.computeHeatIndex(f, h);
dtostrf(hif, 6, 2, fahrenheitTemp);
dtostrf(h, 6, 2, humidityTemp);
// You can delete the following Serial.print's, it's just for debugging purposes
Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" %\t Temperature: ");
Serial.print(t);
Serial.print(" *C ");
Serial.print(f);
Serial.print(" *F\t Heat index: ");
Serial.print(hic);
Serial.print(" *C ");
Serial.print(hif);
Serial.print(" *F");
Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" %\t Temperature: ");
Serial.print(t);
Serial.print(" *C ");
Serial.print(f);
Serial.print(" *F\t Heat index: ");
Serial.print(hic);
Serial.print(" *C ");
Serial.print(hif);
Serial.println(" *F");
}
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
// your actual web page that displays temperature and humidity
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("<head></head><body><h1>ESP8266 - Temperature and Humidity</h1><h3>Temperature in Celsius: ");
client.println(celsiusTemp);
client.println("*C</h3><h3>Temperature in Fahrenheit: ");
client.println(fahrenheitTemp);
client.println("*F</h3><h3>Humidity: ");
client.println(humidityTemp);
client.println("%</h3><h3>");
client.println("</body></html>");
break;
}
if (c == '\n') {
// when starts reading a new line
blank_line = true;
}
else if (c != '\r') {
// when finds a character on the current line
blank_line = false;
}
}
}
// closing the client connection
delay(1);
client.stop();
Serial.println("Client disconnected.");
}
}
Вставьте ваши сетевые учётные данные в следующие переменные, и код будет работать сразу.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Как работает код
Мы подробно объяснили работу очень похожего веб-сервера в предыдущем руководстве. Ознакомьтесь со следующим руководством для подробного объяснения каждой строки кода: Создание веб-сервера ESP8266.
В этом разделе мы рассмотрим только соответствующие части для данного примера.
Импорт библиотек
Импортируйте библиотеки DHT для чтения данных с датчика DHT и библиотеку ESP8266WiFi для создания веб-сервера:
#include <Adafruit_Sensor.h>
#include <DHT.h>
Тип датчика DHT
Раскомментируйте одну из следующих строк для типа датчика, который вы используете. Если вы используете датчик DHT22, вам не нужно ничего менять.
//#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
Настройка сетевых учётных данных
Вставьте ваши сетевые учётные данные в следующие переменные, чтобы ESP8266 мог подключиться к вашей локальной сети.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Инициализация датчика DHT
Определите GPIO, к которому подключен вывод данных DHT. В данном случае он подключен к GPIO5 (D1).
#define DHTPIN 5 // Digital pin connected to the DHT sensor
Создайте объект DHT с типом и выводом, определёнными ранее.
DHT dht(DHTPIN, DHTTYPE);
setup()
В функции setup() инициализируем датчик DHT.
dht.begin();
loop()
В функции loop() мы проверяем, есть ли новый клиент, делающий запрос:
if (client) {
Serial.println("New client");
// bolean to locate when the http request ends
boolean blank_line = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Когда новый клиент делает запрос, мы считываем влажность, температуру в градусах Цельсия и Фаренгейта и сохраняем их в переменных h, t и f:
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
float f = dht.readTemperature(true);
Наконец, мы отправляем ответ клиенту с HTML-текстом для построения страницы, а также значениями температуры и влажности:
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("<head></head><body><h1>ESP8266 - Temperature and Humidity</h1><h3>Temperature in Celsius: ");
client.println(celsiusTemp);
client.println("*C</h3><h3>Temperature in Fahrenheit: ");
client.println(fahrenheitTemp);
client.println("*F</h3><h3>Humidity: ");
client.println(humidityTemp);
client.println("%</h3><h3>");
client.println("</body></html>");
Температура и влажность отправляются клиенту в следующих переменных: celsiusTemp, fahrenheitTemp и humidityTemp.
Демонстрация
После внесения необходимых изменений загрузите код на ESP8266, как описано в предыдущем разделе.
Откройте Serial Monitor Arduino IDE на скорости 115200 бод. Через несколько секунд должен появиться ваш IP-адрес. В нашем случае это 192.168.1.95.
Откройте любой браузер с устройства, подключённого к тому же роутеру, что и ваш ESP. Затем введите IP-адрес и нажмите Enter!
Теперь вы должны увидеть последние показания температуры и влажности. Для обновления показаний вам просто нужно обновить веб-страницу.
Устранение неполадок
Если ваш датчик DHT не может получить показания, прочитайте наше Руководство по устранению неполадок DHT, чтобы помочь решить проблему.
Заключение
В этом проекте мы показали, как отображать показания датчика DHT на веб-странице. Мы предоставили два примера: простой веб-сервер и асинхронный веб-сервер с автоматическим обновлением.
Теперь вы можете легко модифицировать предоставленные примеры для отображения показаний с других датчиков. Если вам нравятся ESP8266 и IoT-проекты, ознакомьтесь с некоторыми из наших ресурсов:
Вам также могут понравиться некоторые из наших самых популярных проектов с ESP8266: