ESP32:Примеры/Веб-сервер на базе ESP32, считывающий температуру и влажность

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Веб-сервер на базе ESP32, считывающий температуру и влажность[1]

Эта статья рассказывает, как при помощи IDE Arduino создать автономный веб-сервер на базе модуля ESP32, считывающего данные о температуре и влажности с датчика DHT11 (или DHT22). Если вы первый раз работаете с модулем ESP32, то базовые знания о нем можно получить тут.

Также перед тем, как продолжить, советую полистать (а лучше – пройти) вот эти руководства:

Установка аддона для ESP32 в IDE Arduino

Для платы ESP32 существует аддон, благодаря которому ее можно программировать прямо в IDE Arduino. О том, как установить его, читайте ниже:

Установка библиотеки для датчика DHT

Библиотека «DHT» упрощает считывание данных о температуре и влажности с датчиков DHT при помощи плат ESP8266 или Arduino. Чтобы установить ее, проделайте следующее:

  • Кликните здесь, чтобы скачать ZIP-архив с библиотекой DHT. Он должен загрузиться в папку «Загрузки» на вашем компьютере.
  • Распакуйте ZIP-архив. В результате у вас должна получиться папка «DHT-sensor-library-master»
  • Переименуйте эту папку на «DHT»
  • Переместите папку «DHT» в папку «libraries» IDE Arduino (это папка для библиотек, устанавливаемых на IDE Arduino)

Загрузка кода

В этом примере мы подключим к модулю ESP32 датчик DHT22, чтобы затем управлять им через браузер. Скопируйте в IDE Arduino код, показанный ниже:

/*
 * Автор – Руи Сантос (Rui Santos )
 * Более подробно о проекте на http://randomnerdtutorials.com
*/

#include <WiFi.h>
#include "DHT.h"

// уберите знаки комментария у строчки с моделью датчика DHT, 
// которую вы используете в своем проекте (в моем случае это DHT22):
//#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT21   // DHT 21 (AM2301)
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

// впишите сюда данные о своей WiFi-сети:
const char* ssid     = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";

WiFiServer server(80);

// задаем контакт для датчика DHT:
const int DHTPin = 16;
// создаем экземпляр класса для датчика DHT:
DHT dht(DHTPin, DHTTYPE);

// временные переменные:
static char celsiusTemp[7];
static char fahrenheitTemp[7];
static char humidityTemp[7];

// клиентские переменные: 
char linebuf[80];
int charcount=0;

void setup() {
  // инициализируем датчик DHT:
  dht.begin();
  
  // запускаем последовательную коммуникацию и ждем открытия порта: 
  Serial.begin(115200);
  while(!Serial) {
    ; // ждем подключения последовательного порта 
      // (нужно только для штатного USB-порта) 
  }
  
  // начинаем с подключения к WiFI-сети:
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");  //  "Подключаемся к "
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  // пробуем подключиться к WiFi-сети:
  while(WiFi.status() != WL_CONNECTED) {
    // подключаемся к сети с шифрованием WPA/WPA2;
    // если это открытая сеть или сеть с шифрованием WEP,
    // то эту строчку нужно поменять:
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");  //  "Подключились к WiFi-сети"
  Serial.println("IP address: ");    //  "IP-адрес: "
  Serial.println(WiFi.localIP());
  
  server.begin();
}

void loop() {
  // прослушиваем входящих клиентов:
  WiFiClient client = server.available();
  if (client) {
    Serial.println("New client");  //  "Новый клиент"
    memset(linebuf,0,sizeof(linebuf));
    charcount=0;
    // HTTP-запрос заканчивается пустой строкой: 
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // считываем HTTP-запрос символ за символом: 
        linebuf[charcount]=c;
        if (charcount<sizeof(linebuf)-1) charcount++;
        // если добрались до конца строки (т.е. получили символ 
        // новой строки), и эта строка пуста, то это значит,
        // что мы достигли конца HTTP-запроса;
        // следовательно, можно отправлять ответ:
        if (c == '\n' && currentLineIsBlank) {
            // данные от датчика могут запаздывать на 2 секунды
            // (это очень медленный датчик)
            float h = dht.readHumidity();
            // считываем температуру в Цельсиях 
            // (вариант по умолчанию):
            float t = dht.readTemperature(); 
            // считываем температуру в Фаренгейтах:
            float f = dht.readTemperature(true);
            // проверяем, корректны ли данные, 
            // и если нет, то выходим и пробуем снова: 
            if (isnan(h) || isnan(t) || isnan(f)) {
              Serial.println("Failed to read from DHT sensor!");
                         //  "Не удалось прочесть данные 
                         //  с датчика DHT!"
              strcpy(celsiusTemp,"Failed");
              strcpy(fahrenheitTemp, "Failed");
              strcpy(humidityTemp, "Failed");         
            }
            else{
              // рассчитываем температуру (в Цельсиях и Фаренгейтах)
              // и влажность:
              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);
              // этот фрагмент кода, если хотите, можно удалить;
              // он для отладочных целей:
              /*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");*/
          }
          // отправляем стандартный заголовок HTTP-запроса: 
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          // после завершения запроса соединение будет отключено:
          client.println("Connection: close");
          client.println();
          client.println("<!DOCTYPE HTML><html><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
          client.println("<meta http-equiv=\"refresh\" content=\"30\"></head>");
          client.println("<body><div style=\"font-size: 3.5rem;\"><p>ESP32 - DHT</p><p>");
          if(atoi(celsiusTemp)>=25){
            client.println("<div style=\"color: #930000;\">");
          }
          else if(atoi(celsiusTemp)<25 && atoi(celsiusTemp)>=5){
            client.println("<div style=\"color: #006601;\">");
          }
          else if(atoi(celsiusTemp)<5){
            client.println("<div style=\"color: #009191;\">");
          }
          client.println(celsiusTemp);
          client.println("*C</p><p>");
          client.println(fahrenheitTemp);
          client.println("*F</p></div><p>");
          client.println(humidityTemp);
          client.println("%</p></div>");
          client.println("</body></html>");     
          break;
        }
        if (c == '\n') {
          // начинаем новую строку:
          currentLineIsBlank = true;
          memset(linebuf,0,sizeof(linebuf));
          charcount=0;
        } else if (c != '\r') {
          // если в текущей строчке есть какой-нибудь символ... 
          currentLineIsBlank = false;
        }
      }
    }
    // даем веб-браузеру время на получение данных: 
    delay(1);

    // закрываем соединение:
    client.stop();
    Serial.println("client disconnected");  //  "Клиент отключен: "
  }
}

Не забудьте в начале кода вписать данные о своей сети (SSID и пароль к SSID).

Теперь подключите модуль ESP32 к компьютеру и проделайте следующее:

  • Кликните в IDE Arduino на Инструменты > Плата > ESP32 Dev Module (Tools > Board > ESP32 Dev Module)
  • Выберите COM-порт
  • Переведите ESP32 в режим загрузки прошивки. Для этого зажмите кнопку «BOOT» и нажмите на кнопку «EN». В результате модуль ESP32 должен перезагрузиться.
  • Нажмите в IDE Arduino кнопку «Загрузка» («Upload») и подождите несколько секунд, пока код скомпилируется и загрузится на плату. Если все в порядке, вы должны увидеть следующее:
  • Перезапустите ESP32, чтобы запустить только что загруженный код

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

  • Один модуль ESP32
  • Один датчик температуры и влажности DHT22
  • Один резистор на 4700 Ом
  • Одна макетная плата
  • Провода-перемычки
Примечание

Этот скетч работает не только с DHT22, но и с другими моделями датчика DHT (подробнее смотрите в комментариях к коду).

Подключите компоненты друг к другу как показано на картинке ниже:

Важно

Датчику DHT для работы требуется напряжение в 5 вольт. Поэтому убедитесь, что используете контакт Vin на ESP32, который как раз выдает нужные 5 вольт.

Доступ к веб-серверу

Перезапустившись, ESP32 напечатает в мониторе порта IDE Arduino свой IP-адрес. Не забудьте выставить скорость передачи данных на 115200 бод.

В моем случае это «http://192.168.1.116».

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

Откройте браузер на любом устройстве подключенном к той же сети, что и ESP32. Вбейте в адресную строку найденный IP-адрес и нажмите  ↵ Enter .

Вы должны увидеть следующее:

Эта веб-страница будет автоматически обновляться каждые 30 секунд. Если температура поднимется выше 25 градусов Цельсия, надпись окрасится в красный цвет.

См.также

Внешние ссылки