7주차 스마트디바이스 (IP 실습) - jungjaeyeol/jyeol03 GitHub Wiki
- 컴퓨터 네트워크의 기기(컴퓨터, 스마트폰 등)를 식별하기 고유한 주소입니다.
- IP는 숫자로 처리된 곳, IPv4 와 IPv6 두 가지 형식이 있습니다.
- IPv4 : 4개의 숫자 그룹, 각각 0부터 255 사이의 숫자
- IPv6 : 16진수로 된 8개의 그룹
-
외부 IP 주소(공용 IP 주소)
- 서비스 제공 업체(ISP)가 부여되는 주소로, 전 세계적으로 고유합니다.
- 인터넷 데이터를 받기 위해 사용됩니다.
-
사설 IP 주소 (사설 IP 주소)
- 집 회사 등 특정 사무실 내부에서 사용하는 주소, 외부에서는 접근할 수 없습니다.
-
공인 IP
- 정의 :인터넷 서비스 제공업체(ISP)로부터 할당받은 IP 주소로, 전 세계 어디서든 유일한 주소입니다.
- 역할 : 인터넷상에서 다른 네트워크와 통신할 때 사용됩니다. 예를 들어, 웹사이트나 서버를 운영할 경우 공인 IP가 필요하다.
- 예시 : 123.45.67.89 같은 형식의 IP 주소가 공인 IP입니다.
- 사용처 : 웹 서버, 이메일 서버, 인터넷 공유기의 WAN 포트 등
-
사설 IP
- 정의 : 내부 네트워크(예: 가정, 회사)에서 사용하는 IP 주소로, 인터넷에서는 직접 사용 불가능합니다.
- 역할 : 공유기를 통해 여러 기기가 하나의 공인 IP를 공유하면서 각각 내부 IP를 갖습니다.
- 예시 : 192.168.0.0 ~ 192.168.255.255
- 사용처 : 가정의 컴퓨터, 스마트폰, 프린터 등 내부 네트워크 기기
-
고정 IP
- 정의: 항상 동일하게 유지되는 IP 주소입니다.
- 특징: 인터넷을 끊었다 다시 연결해도 IP 주소가 변하지 않는다.
- 장점: 언제나 같은 주소로 접근 가능해서 서버 운영에 적합하다.
- 단점: 보안상 노출 위험이 있고, 일반적으로 추가 요금이 부과될 수 있다.
-
유동 IP
- 정의: 인터넷 연결 시마다 바뀔 수 있는 IP 주소입니다.
- 특징: 인터넷을 재연결하면 다른 IP가 부여될 수 있어요.
- 장점: 관리가 쉬움, 보안상 위험이 상대적으로 낮음
- 단점: IP가 자주 바뀌면 원격 접속이나 서버 운영에 불편할 수 있음
- Serial Monitor를 통하여 알 수 있는 온/습도 센
-
아래 사진처럼 DHT sensor library by Adafruit 라이브러리를 다운 받는다.
-
실습 코드
#include <DHT.h>
#define DHTPIN 18 // DHT11 센서에 연결된 핀 번호
// 사용 중인 센서 유형으로 변경하세요. DHT11, DHT22, DHT21
#define DHTTYPE DHT11 // DHT 센서 유형
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(115200);
dht.begin();
}
void loop() {
delay(2000); // 2초마다 센서 값을 읽습니다.
// 온도 및 습도 값 읽기
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
// 센서 값 출력
Serial.print("온도: ");
Serial.print(temperature);
Serial.print(" °C, 습도: ");
Serial.print(humidity);
Serial.println(" %");
}
- 실습 결과
default.mp4
- 실습 코드
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
// Wi-Fi 정보 입력
const char* ssid = "iPhone03";
const char* password = "jy_031024";
// DHT 센서 설정
#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();
// Wi-Fi 연결
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 비워둠
}
- 실습 결과
- 실습 코드
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
// 실습 환경의 WIFI아이디와 비밀번호로 수정하세요.
const char* ssid = "iPhone03";
const char* password = "jy_031024";
#define DHTPIN 18 // DHT 센서에 연결된 디지털 핀
// 사용 중인 센서 유형으로 변경하세요. DHT11, DHT22, DHT21
#define DHTTYPE DHT11 //
// 온습도 센서 객체 생성
DHT dht(DHTPIN, DHTTYPE);
// 80번 포트에서 AsyncWebServer 객체 생성
AsyncWebServer server(80);
// DHT 온도 읽기 함수
String readDHTTemperature() {
// 센서 읽기는 최대 2초가 소요될 수 있습니다. (센서가 매우 느립니다.)
// 기본값으로 섭씨로 온도 읽기
float t = dht.readTemperature();
// 화씨로 온도 읽으려면 매개 변수를 true로 설정
//float t = dht.readTemperature(true);
// 읽기 실패 시 조기에 종료하고 다시 시도합니다.
if (isnan(t)) {
Serial.println("DHT 센서에서 읽기 실패!");
return "--";
}
else {
Serial.println(t);
return String(t);
}
}
// DHT 습도 읽기 함수
String readDHTHumidity() {
// 센서 읽기는 최대 2초가 소요될 수 있습니다. (센서가 매우 느립니다.)
float h = dht.readHumidity();
if (isnan(h)) {
Serial.println("DHT 센서에서 읽기 실패!");
return "--";
}
else {
Serial.println(h);
return String(h);
}
}
// 인덱스 HTML 페이지
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";
// 플레이스홀더를 DHT 값으로 대체하는 함수
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();
// Wi-Fi 연결
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Wi-Fi에 연결 중...");
}
// ESP32 로컬 IP 주소 출력
Serial.println(WiFi.localIP());
// 루트(/) 웹 페이지 라우팅
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
// "/temperature" 엔드포인트에 대한 GET 요청 처리
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", readDHTTemperature().c_str());
});
// "/humidity" 엔드포인트에 대한 GET 요청 처리
server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", readDHTHumidity().c_str());
});
// 서버 시작
server.begin();
}
void loop(){
}
- 실습 결과
HTML.mp4
-
- "https://ngrok.com/download" 에서 프로그램 설치 후 압축을 푼다.
-
- "Your Authtoken"에서 Authtoken 코드를 복사한다
-
- Ngrok 에서 ngrok config add-authtoken $YOUR_AUTHTOKEN 코드를 사용하여 인증을한다.
-
- 인증 후 ngrok https $WepIP:80 를 사용한다.
-
실습 결과
- text IP 주소 들어가기 실습 에서
"text/plain"
코드를 사용하면 글씨가 깨진다, 그러니"text/plain; charset=utf-8"
를 사용하자. - Ngrok 를 사용할때 visa 카드가 있으면 인증 후 사용하면 되지만 visa 카드가 없는 경우
ngrok https $WepIP:80
를 사용하자.