06주차 ‐ ESP32 Web Server 실습 - gitjs523/SmartDevice2025 GitHub Wiki
ESP32는 강력한 Wi-Fi 기능을 내장하여 무선 네트워크에 연결하거나 자체적으로 Wi-Fi 네트워크를 생성하여 웹서버 기능을 구현할 수 있다. STA 모드(Station 모드)와 AP 모드(Access Point 모드) 두 가지가 있다.
- ESP32가 Wi-Fi 클라이언트(사용자 기기)로 동작함
- 집이나 회사에 기존에 있던 Wi-Fi 공유기에 연결됨
- 연결된 상태에서 인터넷 사용 및 다른 장치들과 네트워크 내 통신 가능
- 로컬 IP 주소를 공유기로부터 할당받음
- 인터넷과 연결된 웹서버 구축 시 주로 사용
- 활용 예: 웹서버, 클라우드 연결
- ESP32가 Wi-Fi 공유기 역할을 수행
- 스마트폰, 태블릿 등 ESP32가 아닌 다른 기기가 ESP32에 직접 연결
- 인터넷 없이 작동 가능 (로컬 통신 전용), Wi-Fi 없는 외부 환경에서 ESP32 직접 제어 가능
- SSID 및 비밀번호 사용자가 직접 설정 가능
- 연결된 장치는 ESP32에서 제공하는 웹 페이지 및 서비스에 접근 가능
- 활용 예: 로컬 제어, 오프라인 제어
- ESP32는 STA + AP 모드 동시 지원이 가능
- 다른 Wi-Fi에 연결되면서도 자체 네트워크를 열 수 있음
- ESP32를 중간 다리 역할로 활용할 때 유용함
- 웹서버는 클라이언트(브라우저)의 요청을 받아 웹페이지를 제공하는 역할을 수행
- ESP32는 간단한 웹서버를 구동해 다양한 센서 정보 제공 및 제어가 가능
- 실습 전 주의사항
- 스마트폰의 핫스팟을 이용하여 ESP32를 AP에 연결하고 동시에 같은 스마트폰의 브라우저로 ESP32 웹서버에 접속은 안될 수 있다.
- 노트북, ESP32를 스마트폰으로 실행한 동일한 핫스팟에 연결한다.
사용한 코드
#include <WiFi.h>
#include <WebServer.h>
const char* ssid = "YourSSID";
const char* password = "YourPassword";
WiFiServer server(80);
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting...");
}
Serial.println(WiFi.localIP());
server.begin();
}
void loop() {
WiFiClient client = server.available();
if (client) {
client.println("Hello from ESP32!");
delay(10);
client.stop();
}
}
- HTML 파일에 %STATE%, %BUTTON%을 사용해 LED 상태 실시간 표시
- 상태에 따라 버튼과 텍스트 자동 갱신
사용한 코드
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
const char* ssid = "YourSSID";
const char* password = "YourPassword";
String output2State = "off";
const int output2 = 2;
AsyncWebServer server(80);
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="icon" href="data:,">
<style>
html { font-family: Helvetica; display: inline-block;
margin: 0px auto; text-align: center; }
.button { background-color: #4CAF50; border: none;
color: white; padding: 16px 40px; text-decoration: none;
font-size: 30px; margin: 2px; cursor: pointer; }
.button2 { background-color: #555555; }
</style>
</head>
<body>
<h1>ESP32 웹 서버</h1>
<p>GPIO 2 - 상태 %STATE%</p>
%BUTTON%
</body>
</html>
)rawliteral";
String processor(const String& var){
if(var == "STATE")
{
return output2State;
}
if(var == "BUTTON"){
String buttons = "";
if (output2State == "off")
{
buttons += "<p><a href=\"/2/on\"> \
<button class=\"button\">ON</button></a></p>";
}
else
{
buttons += "<p><a href=\"/2/off\"> \
<button class=\"button button2\">OFF</button></a></p>";
}
return buttons;
}
return String();
}
void setup(){
Serial.begin(115200);
delay(3000);
pinMode(output2, OUTPUT);
digitalWrite(output2, LOW);
Serial.print("연결 중: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("Wi-Fi 연결됨.");
Serial.println("IP 주소: ");
Serial.println(WiFi.localIP());
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
server.on("/2/on", HTTP_GET, [] (AsyncWebServerRequest *request) {
Serial.println("GPIO 2 ON");
output2State = "on";
digitalWrite(output2, HIGH);
request->send_P(200, "text/html", index_html, processor);
});
server.on("/2/off", HTTP_GET, [] (AsyncWebServerRequest *request) {
Serial.println("GPIO 2 OFF");
output2State = "off";
digitalWrite(output2, LOW);
request->send_P(200, "text/html", index_html, processor);
});
server.begin();
}
void loop() {
}