14.1 ESP32를 웹서버로 구동하기 - sunbang123/Smart_device GitHub Wiki

웹 서버란?

  • 웹 서버는 웹 클라이언트에 대한 웹 페이지의 유지, 가져오기 및 제공을 담당하는 하드웨어와 소프트웨어의 조합 .

  • 웹 페이지의 정보는 HTML 문서, 이미지, 비디오, 응용 프로그램 등의 형식의 텍스트와 같은 모든 형식.[ 초보자를 위한 ESP32 프로젝트 ]

  • 웹 클라이언트에 대해 말하자면, 노트북과 휴대폰의 웹 브라우저는 가장 간단한 유형의 웹 클라이언트 중 하나.

  • 웹 서버와 웹 클라이언트 간의 통신은 종종 클라이언트-서버 통신 모델이라고 함.

웹-클라이언트-서버-모델

  • Hyper Text Transfer Protocol 또는 간단히 HTTP는 클라이언트와 서버 간의 통신을 담당하는 프로토콜.

  • 이러한 유형의 통신에서 웹 클라이언트는 HTTP를 사용하여 서버에서 정보를 요청.

  • 항상 요청을 대기(수신)하는 웹 서버는 클라이언트의 요청에 적절한 웹 페이지로 응답.

  • 요청한 페이지를 찾을 수 없으면 서버는 HTTP 404 오류로 응답.


ESP32의 Wi-Fi 작동 모드

스테이션 모드(STA)

소프트 액세스 포인트 모드(AP)

스테이션 + 소프트 AP 모드

  • 스테이션 모드에서 ESP32 모듈은 휴대폰 및 노트북과 마찬가지로 무선 라우터에 의해 설정된 기존 WiFi 네트워크에 연결.
  • ESP32 Wi-Fi 모듈은 라우터의 SSID 및 암호를 사용하여 라우터의 Wi-Fi 네트워크에 연결하고 라우터는 ESP32용 로컬 IP 주소를 할당.

ESP32-STA-모드

  • 액세스 포인트 모드로 전환하면 ESP32 모듈은 무선 라우터와 같은 자체 WiFi 네트워크를 생성
  • 휴대폰, 노트북 및 기타 ESP32 모듈(STA 모드)과 같은 다른 스테이션이 해당 네트워크에 연결.

ESP32-AP 모드

  • ESP32에는 유선 이더넷이 인터넷에 연결되어 있지 않기 때문에 이 AP 모드를 소프트 AP 모드라고 함.

  • AP 모드에서 ESP32를 구성하는 동안 다른 장치가 해당 자격 증명을 사용하여 해당 네트워크에 연결할 수 있도록 네트워크의 SSID 및 비밀번호를 설정해야 함.

  • 스테이션 + 소프트 AP는 스테이션 모드와 소프트 AP 모드의 조합.

  • 여기에서 ESP32는 스테이션과 액세스 포인트의 역할을 모두 수행함.

실습 : DHT 센서에서 온도 및 습도를 읽고 웹 서버로 구축하기

순서

  1. ESPAsyncWebServer, AsyncTCP 라이브러리를 다운로드하여 비동기 웹 서버를 구축함.
  2. 압축 해제 후 Arduino 라이브러리에 붙여넣기 \Documents\Arduino\libraries
  3. 웹 페이지를 새로 고칠 필요 없이 자동으로 센서 판독값을 업데이트함.

개념 및 구성도


ESP 32 연결

DHT 11 연결

웹 서버 구동 성공!

코드

라이브러리 가져오기

/*********
  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     // ESP32의 27번 핀에 연결

// Uncomment the type of sensor in use:
#define DHTTYPE    DHT11     // DHT 11

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(){
  
}

실습을 통해 느낀점

  • 웹 서버와 웹 클라이언트 간의 관계와 통신 모델에 대해 배움.
  • 웹 서버는 웹 페이지를 제공하고, 웹 클라이언트는 웹 서버에 정보를 요청하는 역할을 수행함을 알게 됨.
  • ESP32는 Wi-Fi 연결을 위해 다양한 모드를 지원. STA 모드로 무선 라우터에 연결하거나, AP 모드로 ESP32 자체의 Wi-Fi 네트워크를 생성할 수 있음을 알게 됨.
  • 또한 STA+AP 모드로 두 가지 모드를 동시에 사용할 수도 있음을 알게 됨. ESP32 웹 서버를 통해 센서 데이터를 실시간으로 모니터링할 수 있다는 점이 기억에 남음.
⚠️ **GitHub.com Fallback** ⚠️