07주차 ‐ ESP32 Web Server 실습 2 - gitjs523/SmartDevice2025 GitHub Wiki
- 컴퓨터 네트워크에서 기기(컴퓨터, 스마트폰 등)를 식별하기 위한 고유의 주소
- IP 주소를 통해 인터넷에서 데이터를 올바른 장치로 전송 가능
- IP 주소로 특정 기기 식별 가능
- IP 주소는 숫자로 이루어지고, IPv4와 IPv6 두 가지 형식 존재
- IPv4: 4개의 숫자 그룹, 각각 0부터 255 사이의 숫자
- IPv6: 16진수로 된 8개의 그룹
- 인터넷 서비스 제공업체(ISP)가 부여하는 주소, 전 세계적으로 고유함
- 인터넷 상에서 데이터 주고받기 위해 사용
- 가정이나 회사 등 특정 네트워크 내부에서 사용하는 주소, 외부 접근 불가
- 실시간으로 온도와 습도 측정해서 시리얼 모니터로 출력하기
- DH11 센서 모듈 이용
사용한 코드
#include <DHT.h>
#define DHTPIN 18
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(115200);
dht.begin();
}
void loop() {
delay(2000);
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
Serial.print("온도: ");
Serial.print(temperature);
Serial.print(" °C, 습도: ");
Serial.print(humidity);
Serial.println(" %");
}
- 방금 측정한 온도와 습도를 웹서버에서 TEXT 모드로 표시하기
- 주의 사항
- 필요 시 'charset=utf-8' 이용하기
- 웹 서버에서 글자 깨짐 현상 발생 시 코드 'request->send(200, "text/plain", msg)'를 'request->send(200, "text/plain; charset=utf-8", msg)' 로 바꾸기
사용한 코드
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
const char* ssid = "네트워크_SSID";
const char* password = "네트워크_비밀번호";
#define DHTPIN 18
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
AsyncWebServer server(80);
String readDHTTemperature() {
float t = dht.readTemperature();
if (isnan(t)) {
Serial.println("온도 읽기 실패");
return "--";
} else {
Serial.print("온도: ");
Serial.println(t);
return String(t);
}
}
String readDHTHumidity() {
float h = dht.readHumidity();
if (isnan(h)) {
Serial.println("습도 읽기 실패");
return "--";
} else {
Serial.print("습도: ");
Serial.println(h);
return String(h);
}
}
void setup() {
Serial.begin(115200);
dht.begin();
Serial.print("Wi-Fi 연결 중: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("\nWi-Fi 연결됨. IP 주소:");
Serial.println(WiFi.localIP());
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
String msg = "=== ESP32 온습도 정보 ===\n";
msg += "온도: " + readDHTTemperature() + " °C\n";
msg += "습도: " + readDHTHumidity() + " %\n";
msg += "\n개별 확인: /temperature 또는 /humidity";
request->send(200, "text/plain; charset=utf-8", msg);
});
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain; charset=utf-8", readDHTTemperature());
});
server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain; charset=utf-8", readDHTHumidity());
});
server.begin();
}
void loop() {
// 비동기 웹서버: loop 비워둠
}
- 이번엔 온도와 습도를 웹서버에서 HTML과 CSS를 이용하여 표시하기
사용한 코드
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
const char* ssid = "YourSSID";
const char* password = "YourPassword";
#define DHTPIN 18
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
AsyncWebServer server(80);
String readDHTTemperature() {
float t = dht.readTemperature();
if (isnan(t)) {
Serial.println("DHT 센서에서 읽기 실패!");
return "--";
}
else {
Serial.println(t);
return String(t);
}
}
String readDHTHumidity() {
float h = dht.readHumidity();
if (isnan(h)) {
Serial.println("DHT 센서에서 읽기 실패!");
return "--";
}
else {
Serial.println(h);
return String(h);
}
}
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<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">온도</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">습도</span>
<span id="humidity">%HUMIDITY%</span>
<sup class="units">%</sup>
</p>
</body>
<script>
setInterval(function() {
// XMLHttpRequest 객체를 사용하여 "/temperature" 엔드포인트로 GET 요청을 전송
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();
}, 2000); // 2초 간격으로 업데이트합니다.
setInterval(function() {
// XMLHttpRequest 객체를 사용하여 "/humidity" 엔드포인트로 GET 요청을 전송
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();
}, 2000); //2초 간격으로 업데이트합니다.
</script>
</html>
)rawliteral";
String processor(const String& var){
if(var == "TEMPERATURE"){
return readDHTTemperature();
}
else if(var == "HUMIDITY"){
return readDHTHumidity();
}
return String();
}
void setup(){
Serial.begin(115200);
dht.begin();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Wi-Fi에 연결 중...");
}
Serial.println(WiFi.localIP());
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());
});
server.begin();
}
void loop(){
}
- 웹 서버
- 시리얼 모니터(추가)
- Ngrok 사이트에 가입 후 다운로드
- Ngrok 인증키 복사
- 프롬프트 창에서 ngrok config add-authtoken $YOUR_AUTHTOKEN으로 인증키 값 저장
- Ngrok 실행 후 ngrok tcp http "ESP32에서 할당되는 IP주소" :80 입력 후 URL 생성
- 다른 기기(스마트폰)에서 생성된 URL을 통해 웹서버 접속 실행 결과