ESP32

ESP32 DHT11/DHT22 Web Server

기하 2022. 2. 21. 23:36

이 프로젝트에서는 Arduino IDE를 사용하여

온도와 습도를 표시하는 DHT11 또는 DHT22로

비동기 ESP32 웹 서버를 구축하는 방법을 배웁니다.

우리가 구축할 웹 서버는

웹 페이지를 새로 고칠 필요 없이 판독값을 자동으로 업데이트합니다.

이 프로젝트를 통해 다음을 배우게 됩니다.

  • DHT 센서에서 온도와 습도를 읽는 방법
  • ESPAsyncWebServer 라이브러리 를 사용하여 비동기식 웹 서버를 구축합니다 .
  • 웹 페이지를 새로 고칠 필요 없이 센서 판독값을 자동으로 업데이트합니다.

ESP32와 함께 DHT22 및 DHT11 온도 및 습도 센서를 사용하는 방법에 대한

자세한 설명은 전체 가이드를 읽으십시오:

 Arduino IDE를 사용하는 DHT11/DHT22 온도 및 습도 센서가 있는 ESP32 

 

비동기식 웹 서버

웹 서버 를 구축하기 위해

비동기 웹 서버를 구축하는 쉬운 방법을 제공하는 

ESPAsyncWebServer 라이브러리 를 사용할 것 입니다. 

 

비동기식 웹 서버를 구축하면

라이브러리 GitHub 페이지에서 언급한 것처럼 다음과 같은 몇 가지 이점이 있습니다.

  • "동시에 둘 이상의 연결을 처리";
  • "응답을 보내면 서버가 백그라운드에서 응답을 보내는 동안 다른 연결을 즉시 처리할 수 있습니다."
  • "템플릿을 처리하는 간단한 템플릿 처리 엔진";
  • much more

GitHub 페이지 에서 라이브러리 문서를 살펴보십시오 .

 

필요한 부품

개략도

(이 회로도는 36개의 GPIO가 있는 ESP32 DEVKIT V1 모듈 버전을 사용합니다.

다른 모델을 사용하는 경우 사용 중인 보드의 핀아웃을 확인하십시오.)

 

참고: DHT 센서가 있는 모듈을 사용하는 경우 일반적으로 핀이 3개만 제공됩니다. 

핀에는 배선 방법을 알 수 있도록 레이블이 지정되어야 합니다. 

또한 이러한 모듈 중 상당수는 이미 내부 풀업 저항과 함께 제공되므로 회로에 추가할 필요가 없습니다.

 

라이브러리 설치

다음 지침에 따라 해당 라이브러리를 설치합니다.

 

DHT 센서 라이브러리 설치

Arduino IDE를 사용하여 DHT 센서를 읽으려면 
DHT 센서 라이브러리 를 설치해야 합니다 . 라이브러리를 설치하려면 다음 단계를 따르십시오.

  1. DHT 센서 라이브러리를 다운로드하려면 여기를 클릭하십시오 . 다운로드 폴더 에 .zip 폴더가 있어야 합니다.
  2. .zip 폴더의 압축을  풀면 DHT-sensor-library-master  폴더 가 생깁니다.
  3. DHT-sensor-library-master 폴더를 DHT_sensor 폴더로 바꾸세요
  4. DHT_sensor  폴더를 Arduino IDE 설치 라이브러리 폴더에 복사 합니다.
  5. 마지막으로 Arduino IDE를 다시 엽니다.

Adafruit 통합 센서 드라이버 설치

DHT 센서를 사용하려면 Adafruit Unified Sensor Driver library 도 설치해야합니다

  1. Adafruit Unified Sensor Driver library 를 다운로드하려면 여기를 클릭하세요
    .zip 폴더의 압축을  풀면 Adafruit_sensor-master  폴더 가 생깁니다.
  2. 폴더 이름을 Adafruit_sensor 로 바꾸세요
  3. Adafruit_sensor 폴더를 Arduino IDE 설치 라이브러리 폴더에 복사 합니다.
  4. 마지막으로 Arduino IDE를 다시 엽니다.

ESPAsyncWebServer 라이브러리 설치

ESPAsyncWebServer  라이브러리 를 설치하려면 다음 단계를 따르세요  .

  1. ESPAsyncWebServer 라이브러리를 다운로드하려면 여기를 클릭하십시오 . 
  2. .zip 폴더의 압축을 풀면 ESPAsyncWebServer-master 폴더 가 있어야 합니다.
  3. 폴더 이름을 ESPAsyncWebServer로 바꾸세요
  4. ESPAsyncWebServer  폴더를 Arduino IDE 설치 라이브러리 폴더로 이동 합니다.

ESP32용 비동기 TCP 라이브러리 설치

ESPAsyncWebServer  라이브러리가 작동  하려면  AsyncTCP 라이브러리가 필요합니다  . 

다음 단계에 따라 해당 라이브러리를 설치합니다.

  1. AsyncTCP 라이브러리를 다운로드하려면 여기를 클릭하십시오 . 
  2. .zip 폴더의 압축을 풀면 AsyncTCP-master 폴더 가 나타납니다.
  3. 폴더 이름을 다음처럼  바꾸세요 TCP 
  4. AsyncTCP 폴더를 Arduino IDE 설치 라이브러리 폴더로 이동 합니다.
  5. 마지막으로 Arduino IDE를 다시 엽니다.

 

Code

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

// Import required libraries
#include "WiFi.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 27     // 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);

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

String readDHTTemperature() {
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  //float t = dht.readTemperature(true);
  // Check if any reads failed and exit early (to try again).
  if (isnan(t)) {    
    Serial.println("Failed to read from DHT sensor!");
    return "--";
  }
  else {
    Serial.println(t);
    return String(t);
  }
}

String readDHTHumidity() {
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  if (isnan(h)) {
    Serial.println("Failed to read from DHT sensor!");
    return "--";
  }
  else {
    Serial.println(h);
    return String(h);
  }
}

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>ESP32 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">&deg;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">&percnt;</sup>
  </p>
</body>
<script>
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperature").innerHTML = 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").innerHTML = 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 readDHTTemperature();
  }
  else if(var == "HUMIDITY"){
    return readDHTHumidity();
  }
  return String();
}

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);

  dht.begin();
  
  // 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_P(200, "text/html", index_html, processor);
  });
  server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readDHTTemperature().c_str());
  });
  server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readDHTHumidity().c_str());
  });

  // Start server
  server.begin();
}
 
void loop(){
  
}

다음 변수에 네트워크 자격 증명을 삽입하면 코드가 바로 작동합니다.

 

코드 작동 방식

다음 단락에서 우리는 코드가 어떻게 작동하는지 설명할 것입니다. 

자세히 알아보려면 계속 읽으시거나 데모 섹션으로 이동하여 최종 결과를 확인하세요.

라이브러리 가져오기

먼저 필요한 라이브러리를 가져옵니다. 

웹 서버를 구축하기위해서는

WiFiESPAsyncWebServer, ESPAsyncTCP 가 필요하고

DHT11, DHT22 센서를 위해서

Adafruit_Sensor, DHT 라이브러리가 필요합니다

네트워크 자격 증명 설정

ESP32가 로컬 네트워크에 연결할 수 있도록 다음 변수에 네트워크 자격 증명을 삽입합니다.

변수 정의

DHT 데이터 핀이 연결된 GPIO를 정의합니다. 이 경우 다음과 연결됩니다.GPIO 27.

그런 다음 사용 중인 DHT 센서 유형을 선택합니다. 

이 예에서는 DHT22를 사용하고 있습니다. 

다른 유형을 사용하는 경우 센서의 주석 처리를 제거하고 나머지는 모두 주석 처리하면 됩니다.

앞서 정의한  센서타입과 핀을 파라미터로 DHT 객체를 생성합니다.

 

포트 80에  AsyncWebServer 객체를 생성합니다

온도 및 습도 읽기

두 개의 함수를 만들었습니다.

하나는 온도를 읽는 readDHTTemperature()

다른 하나는 습도를 읽는 readDHTHumidity()

 readDHTTemperature(), readDHTHumidity() 사용하여 간단하게 읽어올 수 있습니다.

또한 센서가 판독값을 얻지 못하는 경우 두 개의 대시(-)를 반환하는 조건이 있습니다.

읽은 값은 string 값으로 반환 됩니다.

float 값을 string 으로 변환하기 위해 String() 함수를 사용합니다.

 

기본적으로 온도는 썹씨로 읽어오지만

화씨로 읽어오고 싶으면  다음 처럼하면 됩니다

웹 페이지 구축

웹서버 페이지로 이동합니다.

위의 그림에서 볼 수 있듯이

웹 페이지에는 하나의 제목과 두 개의 단락이 표시됩니다. 

온도를 표시하는 단락과 습도를 표시하는 단락이 있습니다.

 

페이지의 스타일을 지정하는 두 개의 아이콘도 있습니다.

이 웹 페이지가 어떻게 만들어졌는지 봅시다.

스타일이 포함된 모든 HTML 텍스트는 index_html 변수에 저장 됩니다.

이제 HTML 텍스트를 살펴보고 각 부분이 하는 일을 살펴보겠습니다.

 

다음 <meta> 태그는 웹 페이지를 모든 브라우저에서 반응형으로 만듭니다.

< link> 태그는 fontawesome 웹사이트에서 아이콘을 로드하는 데 필요합니다.

스타일

<style></style> 태그 사이에 CSS를 추가하여 웹 페이지의 스타일을 지정합니다.

기본적으로 Arial 글꼴로 텍스트를 여백 없이

블록에 표시하고 중앙에 정렬하도록 HTML 페이지를 설정합니다.

모든 이전 태그는 <head>  </head> 태그 사이에 있어야 합니다. 

이러한 태그는 <meta> , <link> 태그 및 스타일과 같이

사용자에게 직접적으로 표시되지 않는 콘텐츠를 포함하는 데 사용됩니다 .

HTML 본문

<body></body> 태그 내부 는 웹 페이지 콘텐츠를 추가하는 곳입니다.

< h2></h2> 태그는 웹 페이지에 제목을 추가합니다. 

이 경우 "ESP32 DHT server" 텍스트이지만 다른 텍스트를 추가할 수 있습니다.

그러면 두 개의 단락이 있습니다. 

하나는 온도를 표시하고 다른 하나는 습도를 표시합니다. 

단락은 <p>  </p> 태그로 구분됩니다. 온도에 대한 단락은 다음과 같습니다.

습도에 대한 단락은 다음 스니펫에 있습니다.

< i> 태그는 멋진 아이콘을 표시합니다.

 

아이콘을 표시하는 방법

아이콘을 선택하려면 Font Awesome Icons 웹사이트 로 이동하십시오 .

찾고 있는 아이콘을 검색합니다. 예: "온도계".

원하는 아이콘을 클릭하세요. 그런 다음 제공된 HTML 텍스트를 복사하기만 하면 됩니다.

색상을 선택하려면 다음과 같이 16진수 색상과 함께 스타일 매개변수를 전달하면 됩니다.

HTML 텍스트로 진행 중…

다음 줄은 웹 페이지에 "Temperature"라는 단어를 씁니다.

% 기호 사이의 TEMPERATURE 텍스트는 온도 값의 자리 표시자입니다.

이것은 이 %TEMPERATURE% 텍스트가

DHT 센서의 실제 온도 값으로 대체될 변수와 같다는 것을 의미합니다. 

HTML 텍스트의 자리 표시자는 % 기호 사이에 있어야 합니다.

마지막으로 도 기호를 추가합니다.

< sup>< /sup> 태그는 텍스트를 위 첨자로 만듭니다.

습도 단락에 대해 동일한 접근 방식을 사용하지만

다른 아이콘과 %HUMIDITY% 자리 표시자를 사용합니다.

자동 업데이트

마지막으로 웹 페이지에는

10초마다 온도와 습도를 자동으로 업데이트하는 JavaScript 코드가 있습니다.

HTML 텍스트의 스크립트는 <script></script> 태그 사이에 있어야 합니다.

 

백그라운드에서 온도를 업데이트하기 위해서  setInterval() 함수를 10초마다 실행합니다

기본적으로 /temperature URL에 최신 온도 판독값을 요청합니다.

값을 받으면 id 가 temperature 인 HTML 엘리먼트를 업데이트 합니다

요약하면 이 이전 섹션은 온도를 비동기적으로 업데이트하는 역할을 합니다. 

습도 판독값에 대해 동일한 프로세스가 반복됩니다.

 

Processor

processor() 를 만드는데 이는 HTML 안에 있는 자리표시자를 실제 온도와 습도값으로 바꾸는 

역할을 합니다

웹 페이지가 요청되면 HTML에 자리 표시자가 있는지 확인합니다. 

%TEMPERATURE% 자리 표시자를 찾으면
readDHTTemperature()
호출하여 온도를 반환합니다

자리 표시자 %HUMIDITY% 이면 습도 값을 반환합니다.

 

setup()

시리얼모니더와 DHT 센서를 초기화 합니다

로컬 네트워크에 연결하고 ESP32 IP 주소를 인쇄합니다..

마지막으로 웹 서버를 처리할 다음 코드 줄을 추가합니다.

루트 URL에 request을 할 때, 우리는 index_html변수에 저장된 HTML 텍스트를 보냅니다.

또한 모든 자리표시자를 실제 값으로 바꿀 processor() 함수도 같이 보냅니다.

온도 및 습도 판독값을 업데이트하려면 두 개의 handler를 추가해야 합니다

 /temperature URL 에 대한 요청을 받으면 업데이트된 온도 값을 보내기만 하면 됩니다

이는 일반 텍스트이고 char로 보내야 하므로 c_str() 메쏘드를 사용합니다.

습도에 대해서도 동일한 과정을 반복합니다.

마지막으로 서버를 시작할 수 있습니다.

이것은 비동기식 웹 서버이기 때문에 loop()에는 아무것도 쓸 필요가 없습니다

코드 업로드

이제 ESP32에 코드를 업로드합니다. 올바른 보드와 COM 포트를 선택했는지 확인하십시오.

업로드 후 직렬 모니터를 115200의 전송 속도로 엽니다.

ESP32 재설정 버튼을 누릅니다. ESP32 IP 주소는 직렬 모니터에 인쇄되어야 합니다.

 

웹 서버 데모

브라우저를 열고 ESP32 IP 주소를 입력합니다. 웹 서버에 최신 센서 판독값이 표시되어야 합니다.

웹 페이지를 새로 고칠 필요 없이 온도 및 습도 판독값이 자동으로 업데이트됩니다.