
Подключение DHT11/DHT22 к ESP8266 NodeMCU с веб-сервером
Вы когда-нибудь хотели использовать свой мобильный телефон, планшет или ПК для мониторинга температуры и влажности в вашем доме, холодильной камере или винном погребе в любое время? Тогда этот IoT-проект может стать отличной отправной точкой!
В этом проекте ESP8266 NodeMCU используется в качестве управляющего устройства, которое подключается к существующей WiFi-сети и создаёт веб-сервер. Когда устройство подключается к этому веб-серверу, ESP8266 считывает температуру и относительную влажность с датчика DHT11/DHT22 и отправляет их в веб-браузер устройства с красивым интерфейсом. Интересно? Давайте начнём!
Есть несколько концепций, с которыми вам следует ознакомиться, прежде чем продолжить это руководство. Если какие-либо из приведённых ниже руководств вам незнакомы, рекомендуем сначала прочитать их:
Примечание
Рекомендуемые материалы
Подключение датчиков DHT11 и DHT22 к Arduino
Установка платы ESP8266 в Arduino IDE
Подключение датчика DHT11/DHT22 к ESP8266
Подключение датчика DHT11/DHT22 к ESP8266 довольно простое. Начните с размещения ESP8266 на макетной плате, убедившись, что каждая сторона платы находится на разных сторонах макетной платы.
Разместите датчик на макетной плате рядом с ESP8266. Подключите вывод VCC датчика к выводу 3.3V на ESP8266, а землю — к земле. Подключите вывод данных датчика к выводу D8 на ESP8266. Наконец, добавьте подтягивающий резистор 10 кОм между VCC и линией данных, чтобы поддерживать её в состоянии HIGH для правильной связи между датчиком и ESP8266.
На изображении ниже показана схема подключения.
Подключение датчика температуры и влажности DHT11 к ESP8266 NodeMCU
Подключение датчика температуры и влажности DHT22 к ESP8266 NodeMCU
Установка библиотеки датчика DHT
Чтобы начать считывание данных с датчика, вам необходимо установить библиотеку DHT sensor. Она доступна через менеджер библиотек Arduino.
Для установки библиотеки перейдите в Sketch > Include Library > Manage Libraries… Дождитесь, пока менеджер библиотек загрузит индекс библиотек и обновит список установленных библиотек.
Отфильтруйте результаты поиска, введя „DHT sensor“. Найдите DHT sensor library от Adafruit. Нажмите на эту запись и затем выберите Install.
Библиотека DHT sensor использует бэкенд поддержки Adafruit Sensor. Поэтому найдите Adafruit Unified Sensor в менеджере библиотек и установите её тоже.
Создание веб-сервера ESP8266 в режиме WiFi Station (STA)
Давайте перейдём к самому интересному!
Как следует из заголовка, мы настроим веб-сервер ESP8266 в режиме станции (STA) для обслуживания веб-страниц любому подключённому клиенту в существующей сети.
Прежде чем начать загрузку скетча, вы должны заменить следующие две переменные вашими сетевыми учётными данными, чтобы ESP8266 мог подключиться к существующей сети.
const char* ssid = "YourNetworkName"; // Enter SSID here
const char* password = "YourPassword"; //Enter Password here
Когда закончите, попробуйте загрузить скетч, а затем мы подробно его разберём.
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.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
/*Put your SSID & Password*/
const char* ssid = "YourNetworkName"; // Enter SSID here
const char* password = "YourPassword"; //Enter Password here
ESP8266WebServer server(80);
// DHT Sensor
uint8_t DHTPin = D8;
// Initialize DHT sensor.
DHT dht(DHTPin, DHTTYPE);
float Temperature;
float Humidity;
void setup() {
Serial.begin(115200);
delay(100);
pinMode(DHTPin, INPUT);
dht.begin();
Serial.println("Connecting to ");
Serial.println(ssid);
//connect to your local wi-fi network
WiFi.begin(ssid, password);
//check wi-fi is connected to wi-fi network
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected..!");
Serial.print("Got IP: "); Serial.println(WiFi.localIP());
server.on("/", handle_OnConnect);
server.onNotFound(handle_NotFound);
server.begin();
Serial.println("HTTP server started");
}
void loop() {
server.handleClient();
}
void handle_OnConnect() {
Temperature = dht.readTemperature(); // Gets the values of the temperature
Humidity = dht.readHumidity(); // Gets the values of the humidity
server.send(200, "text/html", SendHTML(Temperature,Humidity));
}
void handle_NotFound(){
server.send(404, "text/plain", "Not found");
}
String SendHTML(float Temperaturestat,float Humiditystat){
String ptr = "<!DOCTYPE html> <html>\n";
ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<title>ESP8266 Weather Report</title>\n";
ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;}\n";
ptr +="p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n";
ptr +="</style>\n";
ptr +="</head>\n";
ptr +="<body>\n";
ptr +="<div id=\"webpage\">\n";
ptr +="<h1>ESP8266 NodeMCU Weather Report</h1>\n";
ptr +="<p>Temperature: ";
ptr +=(int)Temperaturestat;
ptr +="°C</p>";
ptr +="<p>Humidity: ";
ptr +=(int)Humiditystat;
ptr +="%</p>";
ptr +="</div>\n";
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}
Доступ к веб-серверу
После загрузки скетча откройте монитор порта на скорости 115200 бод и нажмите кнопку RESET на NodeMCU. Если всё в порядке, он отобразит динамический IP-адрес, полученный от вашего роутера, а также сообщение «HTTP server started».
Далее откройте браузер и перейдите по IP-адресу, отображённому в мониторе порта. ESP8266 должен отобразить веб-страницу с текущей температурой и относительной влажностью.
Подробное объяснение кода
Скетч начинается с подключения библиотеки ESP8266WiFi.h. Эта библиотека содержит специфичные для ESP8266 методы, которые мы используем для подключения к сети. Далее мы подключаем библиотеку ESP8266WebServer.h, которая содержит методы, помогающие настроить сервер и обрабатывать входящие HTTP-запросы без необходимости беспокоиться о низкоуровневых деталях реализации. Наконец, мы подключаем библиотеку DHT.h.
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include "DHT.h"
Далее мы указываем тип используемого датчика DHT. Раскомментируйте соответствующую строку ниже!
//#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
Поскольку мы настраиваем веб-сервер ESP8266 в режиме станции (STA), он будет подключаться к существующей WiFi-сети. Поэтому нам нужно указать SSID и пароль.
/*Put your SSID & Password*/
const char* ssid = "YourNetworkName"; // Enter SSID here
const char* password = "YourPassword"; //Enter Password here
После этого мы создаём объект библиотеки ESP8266WebServer, чтобы получить доступ к её функциям. Конструктор этого объекта принимает в качестве параметра порт, на котором сервер будет прослушивать запросы. Поскольку HTTP по умолчанию использует порт 80, мы используем это значение. Это позволяет подключаться к серверу без указания порта в URL.
// declare an object of WebServer library
ESP8266WebServer server(80);
Далее мы определяем номер GPIO-вывода на ESP8266 NodeMCU, к которому подключён вывод данных нашего датчика, и создаём объект DHT. Таким образом, мы можем использовать функции, специфичные для библиотеки DHT.
// DHT Sensor
uint8_t DHTPin = D8;
// Initialize DHT sensor.
DHT dht(DHTPin, DHTTYPE);
Объявлены две переменные типа float: Temperature и Humidity.
float Temperature;
float Humidity;
Функция Setup()
В функции setup мы настраиваем наш веб-сервер. Сначала мы устанавливаем последовательное соединение для целей отладки и настраиваем GPIO-вывод на работу в режиме INPUT. Также мы инициализируем объект DHT.
Serial.begin(115200);
delay(100);
pinMode(DHTPin, INPUT);
dht.begin();
Затем мы используем функцию WiFi.begin() для подключения к WiFi-сети. Функция принимает SSID (имя сети) и пароль в качестве параметров.
Serial.println("Connecting to ");
Serial.println(ssid);
//connect to your local wi-fi network
WiFi.begin(ssid, password);
Пока ESP8266 пытается подключиться к сети, мы можем использовать функцию WiFi.status() для проверки состояния подключения.
//check wi-fi is connected to wi-fi network
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
После подключения к сети используется функция WiFi.localIP() для вывода IP-адреса, назначенного ESP8266.
Serial.println("");
Serial.println("WiFi connected..!");
Serial.print("Got IP: "); Serial.println(WiFi.localIP());
Для обработки входящих HTTP-запросов мы должны указать, какой код должен выполняться при обращении к определённому URL. Для этого мы используем метод .on(). Этот метод принимает два параметра: относительный URL-путь и имя функции, которая должна быть вызвана при посещении этого URL.
Код ниже указывает, что когда сервер получает HTTP-запрос по корневому пути (/), он вызовет функцию handle_OnConnect(). Важно отметить, что указанный URL является относительным путём.
server.on("/", handle_OnConnect);
Мы не указали, что сервер должен отдавать, если клиент запрашивает URL, не указанный в server.on(). Он должен вернуть ошибку 404 (Page Not Found) в качестве ответа. Для этого мы используем метод server.onNotFound().
server.onNotFound(handle_NotFound);
Теперь, чтобы запустить сервер, мы вызываем метод begin() объекта server.
server.begin();
Serial.println("HTTP server started");
Функция Loop()
Фактическая обработка входящих HTTP-запросов происходит в функции loop. Для этого мы используем метод handleClient() объекта server.
server.handleClient();
Теперь нам нужно написать функцию handle_OnConnect(), которую мы ранее привязали к корневому URL (/) с помощью server.on. Мы начинаем эту функцию с чтения значений температуры и влажности с датчика.
Мы используем метод send для ответа на HTTP-запрос. Хотя этот метод можно вызвать с различными аргументами, в простейшей форме он требует код HTTP-ответа, тип содержимого и само содержимое.
Первый параметр, который мы передаём методу send — это код 200 (один из кодов состояния HTTP), который соответствует ответу OK. Затем мы указываем тип содержимого как «text/html», и, наконец, передаём пользовательскую функцию SendHTML(), которая генерирует динамическую HTML-страницу с показаниями температуры и влажности.
void handle_OnConnect() {
Temperature = dht.readTemperature(); // Gets the values of the temperature
Humidity = dht.readHumidity(); // Gets the values of the humidity
server.send(200, "text/html", SendHTML(Temperature,Humidity));
}
Аналогично мы пишем функцию для обработки страницы ошибки 404.
void handle_NotFound(){
server.send(404, "text/plain", "Not found");
}
Отображение HTML веб-страницы
Каждый раз, когда веб-сервер ESP8266 получает запрос от веб-клиента, функция sendHTML() генерирует веб-страницу. Она просто конкатенирует HTML-код в длинную строку и возвращает её функции server.send(), которую мы обсуждали ранее. Функция использует показания температуры и влажности в качестве параметров для динамической генерации HTML-содержимого.
Первый текст, который вы всегда должны отправлять — это объявление <!DOCTYPE>, которое указывает, что мы отправляем HTML-код.
String SendHTML(float Temperaturestat,float Humiditystat){
String ptr = "<!DOCTYPE html> <html>\n";
Элемент <meta> viewport делает веб-страницу адаптивной, обеспечивая хороший внешний вид на всех устройствах. Тег title определяет заголовок страницы.
ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<title>ESP8266 Weather Report</title>\n";
Стилизация веб-страницы
Далее у нас есть CSS для стилизации общего внешнего вида веб-страницы. Мы выбираем шрифт Helvetica и определяем, что содержимое должно отображаться как inline-block с выравниванием по центру.
ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
Следующий код устанавливает цвет, шрифт и отступы для тегов body, H1 и p.
ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;}\n";
ptr +="p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n";
ptr +="</style>\n";
ptr +="</head>\n";
ptr +="<body>\n";
Установка заголовка веб-страницы
Далее устанавливается заголовок веб-страницы. Вы можете изменить этот текст на любой, подходящий для вашего приложения.
ptr +="<div id=\"webpage\">\n";
ptr +="<h1>ESP8266 Weather Report</h1>\n";
Отображение температуры и влажности на веб-странице
Мы использовали тег абзаца для отображения значений температуры и влажности. Обратите внимание, что эти значения преобразуются в целые числа с помощью приведения типов.
ptr +="<p>Temperature: ";
ptr +=(int)Temperaturestat;
ptr +="°C</p>";
ptr +="<p>Humidity: ";
ptr +=(int)Humiditystat;
ptr +="%</p>";
ptr +="</div>\n";
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}
Стилизация веб-страницы для более привлекательного вида
Программисты склонны упускать из виду эстетику, но приложив немного усилий, наша веб-страница может выглядеть гораздо привлекательнее. Скриншот ниже даст вам представление о том, что мы собираемся сделать.
Впечатляет, не правда ли? Давайте теперь добавим стили к нашей предыдущей HTML-странице. Для начала замените функцию SendHTML() в скетче выше на код ниже. Попробуйте загрузить новый скетч, а затем мы подробно его разберём.
String SendHTML(float TempCstat,float TempFstat,float Humiditystat){
String ptr = "<!DOCTYPE html> <html>\n";
ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<link href=\"https://fonts.googleapis.com/css?family=Open+Sans:300,400,600\" rel=\"stylesheet\">\n";
ptr +="<title>ESP8266 Weather Report</title>\n";
ptr +="<style>html { font-family: 'Open Sans', sans-serif; display: block; margin: 0px auto; text-align: center;color: #333333;}\n";
ptr +="body{margin-top: 50px;}\n";
ptr +="h1 {margin: 50px auto 30px;}\n";
ptr +=".side-by-side{display: inline-block;vertical-align: middle;position: relative;}\n";
ptr +=".humidity-icon{background-color: #3498db;width: 30px;height: 30px;border-radius: 50%;line-height: 36px;}\n";
ptr +=".humidity-text{font-weight: 600;padding-left: 15px;font-size: 19px;width: 160px;text-align: left;}\n";
ptr +=".humidity{font-weight: 300;font-size: 60px;color: #3498db;}\n";
ptr +=".temperature-icon{background-color: #f39c12;width: 30px;height: 30px;border-radius: 50%;line-height: 40px;}\n";
ptr +=".temperature-text{font-weight: 600;padding-left: 15px;font-size: 19px;width: 160px;text-align: left;}\n";
ptr +=".temperature{font-weight: 300;font-size: 60px;color: #f39c12;}\n";
ptr +=".superscript{font-size: 17px;font-weight: 600;position: absolute;right: -20px;top: 15px;}\n";
ptr +=".data{padding: 10px;}\n";
ptr +="</style>\n";
ptr +="</head>\n";
ptr +="<body>\n";
ptr +="<div id=\"webpage\">\n";
ptr +="<h1>ESP8266 Weather Report</h1>\n";
ptr +="<div class=\"data\">\n";
ptr +="<div class=\"side-by-side temperature-icon\">\n";
ptr +="<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n";
ptr +="width=\"9.915px\" height=\"22px\" viewBox=\"0 0 9.915 22\" enable-background=\"new 0 0 9.915 22\" xml:space=\"preserve\">\n";
ptr +="<path fill=\"#FFFFFF\" d=\"M3.498,0.53c0.377-0.331,0.877-0.501,1.374-0.527C5.697-0.04,6.522,0.421,6.924,1.142\n";
ptr +="c0.237,0.399,0.315,0.871,0.311,1.33C7.229,5.856,7.245,9.24,7.227,12.625c1.019,0.539,1.855,1.424,2.301,2.491\n";
ptr +="c0.491,1.163,0.518,2.514,0.062,3.693c-0.414,1.102-1.24,2.038-2.276,2.594c-1.056,0.583-2.331,0.743-3.501,0.463\n";
ptr +="c-1.417-0.323-2.659-1.314-3.3-2.617C0.014,18.26-0.115,17.104,0.1,16.022c0.296-1.443,1.274-2.717,2.58-3.394\n";
ptr +="c0.013-3.44,0-6.881,0.007-10.322C2.674,1.634,2.974,0.955,3.498,0.53z\"/>\n";
ptr +="</svg>\n";
ptr +="</div>\n";
ptr +="<div class=\"side-by-side temperature-text\">Temperature</div>\n";
ptr +="<div class=\"side-by-side temperature\">";
ptr +=(int)TempCstat;
ptr +="<span class=\"superscript\">°C</span></div>\n";
ptr +="</div>\n";
ptr +="<div class=\"data\">\n";
ptr +="<div class=\"side-by-side humidity-icon\">\n";
ptr +="<svg version=\"1.1\" id=\"Layer_2\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n\"; width=\"12px\" height=\"17.955px\" viewBox=\"0 0 13 17.955\" enable-background=\"new 0 0 13 17.955\" xml:space=\"preserve\">\n";
ptr +="<path fill=\"#FFFFFF\" d=\"M1.819,6.217C3.139,4.064,6.5,0,6.5,0s3.363,4.064,4.681,6.217c1.793,2.926,2.133,5.05,1.571,7.057\n";
ptr +="c-0.438,1.574-2.264,4.681-6.252,4.681c-3.988,0-5.813-3.107-6.252-4.681C-0.313,11.267,0.026,9.143,1.819,6.217\"></path>\n";
ptr +="</svg>\n";
ptr +="</div>\n";
ptr +="<div class=\"side-by-side humidity-text\">Humidity</div>\n";
ptr +="<div class=\"side-by-side humidity\">";
ptr +=(int)Humiditystat;
ptr +="<span class=\"superscript\">%</span></div>\n";
ptr +="</div>\n";
ptr +="</div>\n";
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}
Объяснение кода
Мы уже знаем, что объявление <!DOCTYPE> сообщает браузеру, что мы отправляем HTML-код, а элемент <meta> viewport делает веб-страницу адаптивной. Единственное отличие здесь в том, что мы будем использовать Google Fonts. Google предлагает сотни бесплатных веб-шрифтов для коммерческого и личного использования.
Для нашего веб-сайта мы будем использовать веб-шрифт Open Sans, разработанный по заказу Google. Шрифт Google встраивается в заголовок вашего HTML-документа с помощью тега <link>.
Для нашей страницы мы выбрали начертания шрифта 300 (Light), 400 (Regular) и 600 (Bold). Вы можете выбрать сколько угодно, но имейте в виду, что чрезмерное количество начертаний шрифтов замедляет загрузку страницы.
Вы также можете добавить курсивный стиль, просто добавив символ i в конец начертания шрифта, например, 400i встроит обычный курсивный шрифт.
Важно отметить, что шрифты Google загружаются динамически; вы не сможете увидеть шрифт Google, если на устройстве, с которого вы заходите на эту страницу, нет активного интернет-соединения.
String SendHTML(float TempCstat,float TempFstat,float Humiditystat){
String ptr = "<!DOCTYPE html> <html>\n";
ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<link href=\"https://fonts.googleapis.com/css?family=Open+Sans:300,400,600\" rel=\"stylesheet\">\n";
Далее мы применяем шрифт Open Sans ко всему HTML-документу. Мы также должны указать sans-serif в качестве запасного шрифта. Если первый указанный шрифт не загрузится, браузер попытается загрузить запасной шрифт.
ptr +="<title>ESP8266 Weather Report</title>\n";
ptr +="<style>html { font-family: 'Open Sans', sans-serif; display: block; margin: 0px auto; text-align: center;color: #333333;}\n";
ptr +="body{margin-top: 50px;}\n";
ptr +="h1 {margin: 50px auto 30px;}\n";
Далее мы применяем CSS для влажности и температуры — иконок, заголовков и значений. Все три этих элемента отображаются inline и выравниваются по вертикали. Фон иконки делается круглым с помощью border radius 50% и высоты и ширины 30px.
ptr +=".side-by-side{display: inline-block;vertical-align: middle;position: relative;}\n";
ptr +=".humidity-icon{background-color: #3498db;width: 30px;height: 30px;border-radius: 50%;line-height: 36px;}\n";
ptr +=".humidity-text{font-weight: 600;padding-left: 15px;font-size: 19px;width: 160px;text-align: left;}\n";
ptr +=".humidity{font-weight: 300;font-size: 60px;color: #3498db;}\n";
ptr +=".temperature-icon{background-color: #f39c12;width: 30px;height: 30px;border-radius: 50%;line-height: 40px;}\n";
ptr +=".temperature-text{font-weight: 600;padding-left: 15px;font-size: 19px;width: 160px;text-align: left;}\n";
ptr +=".temperature{font-weight: 300;font-size: 60px;color: #f39c12;}\n";
ptr +=".superscript{font-size: 17px;font-weight: 600;position: absolute;right: -20px;top: 15px;}\n";
ptr +=".data{padding: 10px;}\n";
ptr +="</style>\n";
ptr +="</head>\n";
ptr +="<body>\n";
После этого мы отображаем показания температуры с симпатичной маленькой иконкой.
Иконка температуры — это изображение в формате масштабируемой векторной графики (SVG), определённое в теге <svg>. Создание SVG не требует специальных навыков программирования. Вы можете создавать графику для вашей страницы с помощью Google SVG Editor. После иконки мы отображаем фактическое показание температуры с датчика.
ptr +="<div id=\"webpage\">\n";
ptr +="<h1>ESP8266 NodeMCU Weather Report</h1>\n";
ptr +="<div class=\"data\">\n";
ptr +="<div class=\"side-by-side temperature-icon\">\n";
ptr +="<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n";
ptr +="width=\"9.915px\" height=\"22px\" viewBox=\"0 0 9.915 22\" enable-background=\"new 0 0 9.915 22\" xml:space=\"preserve\">\n";
ptr +="<path fill=\"#FFFFFF\" d=\"M3.498,0.53c0.377-0.331,0.877-0.501,1.374-0.527C5.697-0.04,6.522,0.421,6.924,1.142\n";
ptr +="c0.237,0.399,0.315,0.871,0.311,1.33C7.229,5.856,7.245,9.24,7.227,12.625c1.019,0.539,1.855,1.424,2.301,2.491\n";
ptr +="c0.491,1.163,0.518,2.514,0.062,3.693c-0.414,1.102-1.24,2.038-2.276,2.594c-1.056,0.583-2.331,0.743-3.501,0.463\n";
ptr +="c-1.417-0.323-2.659-1.314-3.3-2.617C0.014,18.26-0.115,17.104,0.1,16.022c0.296-1.443,1.274-2.717,2.58-3.394\n";
ptr +="c0.013-3.44,0-6.881,0.007-10.322C2.674,1.634,2.974,0.955,3.498,0.53z\"/>\n";
ptr +="</svg>\n";
ptr +="</div>\n";
ptr +="<div class=\"side-by-side temperature-text\">Temperature</div>\n";
ptr +="<div class=\"side-by-side temperature\">";
ptr +=(int)TempCstat;
ptr +="<span class=\"superscript\">°C</span></div>\n";
ptr +="</div>\n";
С помощью этой иконки мы отображаем показания влажности. Это ещё одно SVG-изображение.
После вывода значений влажности мы закрываем все открытые теги, такие как body и html.
ptr +="<div class=\"data\">\n";
ptr +="<div class=\"side-by-side humidity-icon\">\n";
ptr +="<svg version=\"1.1\" id=\"Layer_2\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n\"; width=\"12px\" height=\"17.955px\" viewBox=\"0 0 13 17.955\" enable-background=\"new 0 0 13 17.955\" xml:space=\"preserve\">\n";
ptr +="<path fill=\"#FFFFFF\" d=\"M1.819,6.217C3.139,4.064,6.5,0,6.5,0s3.363,4.064,4.681,6.217c1.793,2.926,2.133,5.05,1.571,7.057\n";
ptr +="c-0.438,1.574-2.264,4.681-6.252,4.681c-3.988,0-5.813-3.107-6.252-4.681C-0.313,11.267,0.026,9.143,1.819,6.217\"></path>\n";
ptr +="</svg>\n";
ptr +="</div>\n";
ptr +="<div class=\"side-by-side humidity-text\">Humidity</div>\n";
ptr +="<div class=\"side-by-side humidity\">";
ptr +=(int)Humiditystat;
ptr +="<span class=\"superscript\">%</span></div>\n";
ptr +="</div>\n";
ptr +="</div>\n";
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}
Улучшение 1 — Автоматическое обновление страницы
Одно из улучшений, которое вы можете сделать — это автоматическое обновление страницы для обновления значений датчика.
Вы можете указать браузеру автоматически перезагружать страницу через заданный интервал, вставив один тег <meta> в ваш HTML-документ.
<meta http-equiv="refresh" content="2" >
Вставьте этот код в тег <head> вашего документа; этот мета-тег укажет браузеру обновляться каждые две секунды.
Улучшение 2 — Динамическая загрузка данных датчика с помощью AJAX
Обновление всей веб-страницы непрактично, если страница большая. Асинхронный Javascript и XML (AJAX) — это лучший метод, поскольку он позволяет нам запрашивать данные с сервера асинхронно (в фоновом режиме) без обновления страницы.
Объект XMLHttpRequest в JavaScript обычно используется для выполнения AJAX на веб-страницах. Он отправляет тихий GET-запрос серверу и обновляет элемент страницы. AJAX — это не новая технология и не другой язык программирования; это просто существующая технология, используемая иным способом. Она позволяет вам:
Запрашивать данные с сервера после загрузки страницы
Получать данные от сервера после загрузки страницы
Отправлять данные на сервер в фоновом режиме
Вот AJAX-скрипт, который мы будем использовать. Поместите этот скрипт перед закрывающим тегом <head>.
ptr +="<script>\n";
ptr +="setInterval(loadDoc,200);\n";
ptr +="function loadDoc() {\n";
ptr +="var xhttp = new XMLHttpRequest();\n";
ptr +="xhttp.onreadystatechange = function() {\n";
ptr +="if (this.readyState == 4 && this.status == 200) {\n";
ptr +="document.getElementById(\"webpage\").innerHTML =this.responseText}\n";
ptr +="};\n";
ptr +="xhttp.open(\"GET\", \"/\", true);\n";
ptr +="xhttp.send();\n";
ptr +="}\n";
ptr +="</script>\n";
Объяснение кода
Поскольку AJAX-скрипт — это просто javascript, он должен быть заключён в тег <script>. Мы будем использовать функцию javascript setInterval(), чтобы эта функция вызывала сама себя повторно. Она требует два параметра: функцию для выполнения и временной интервал (в миллисекундах).
ptr +="<script>\n";
ptr +="setInterval(loadDoc,200);\n";
Функция loadDoc() — это самая важная часть этого скрипта. В этой функции создаётся объект XMLHttpRequest(). Этот объект используется для запроса данных у веб-сервера.
ptr +="function loadDoc() {\n";
ptr +="var xhttp = new XMLHttpRequest();\n";
Метод xhttp.onreadystatechange() вызывается каждый раз при изменении readyState. Свойство readyState представляет состояние XMLHttpRequest. Оно имеет одно из следующих значений:
0: запрос не инициализирован
1: соединение с сервером установлено
2: запрос получен
3: обработка запроса
4: запрос завершён, ответ готов
Свойство status содержит статус объекта XMLHttpRequest. Оно имеет одно из следующих значений:
200: «OK»
403: «Forbidden» (Запрещено)
404: «Page not found» (Страница не найдена)
Когда readyState равен 4 и status равен 200, ответ завершён, и содержимое элемента с id „webpage“ (div, содержащий значения температуры и влажности) обновляется.
ptr +="xhttp.onreadystatechange = function() {\n";
ptr +="if (this.readyState == 4 && this.status == 200) {\n";
ptr +="document.getElementById(\"webpage\").innerHTML =this.responseText}\n";
ptr +="};\n";
Затем функции open() и send() используются для инициирования HTTP-запроса.
ptr +="xhttp.open(\"GET\", \"/\", true);\n";
ptr +="xhttp.send();\n";
ptr +="}\n";