6주차 스마트디바이스 (ESP32 웹 서버) - jungjaeyeol/jyeol03 GitHub Wiki

1. ESP WiFi

  • ESP32는 내장 WiFi 기능을 통해 웹서버 기능을 구현할 수 있습니다.
  • ESP32는 강력한 Wi-Fi 기능을 내장한 마이크로컨트롤러로, *STA(Station) 모드와 AP(Access Point) 모드 두 가지 주요 Wi-Fi 동작 모드를 지원합니다. 이 두 모드는 각각의 목적과 상황에 따라 활용됩니다.

1-1. STA 모드

  • 역할: ESP32가 Wi-Fi 클라이언트가 되어 기존 Wi-Fi 네트워크(공유기)에 접속합니다.
  • 사용 목적: 인터넷에 연결하거나, 로컬 네트워크 내 다른 장치와 통신하기 위해 사용

특징

  • 일반 스마트폰이나 노트북처럼 기존 Wi-Fi 네트워크에 접속

  • 로컬 IP 주소를 공유기로부터 할당받음

  • 인터넷과 연결된 웹서버 구축 시 주로 사용

  • 예시 코드

WiFi.begin("MyWiFi", "MyPassword");

while (WiFi.status() != WL_CONNECTED) {
  delay(1000);
  Serial.println("Connecting...");
}

Serial.println("Connected with IP:");
Serial.println(WiFi.localIP());

1-2. AP 모드

  • 역할: ESP32가 Wi-Fi 공유기 역할을 합니다. 다른 기기(스마트폰 등)가 ESP32에 직접 연결할 수 있습니다.
  • 사용 목적: 외부 네트워크 없이, ESP32와 직접 통신하고 싶을 때 사용 (설정 페이지 제공 등).

특징

  • 인터넷 없이도 작동 가능

  • SSID 및 비밀번호 직접 설정 가능

  • 연결된 장치는 ESP32에서 제공하는 페이지/서비스에 접근 가능

  • 예시 코드

WiFi.softAP("ESP32-AccessPoint", "12345678");

IPAddress IP = WiFi.softAPIP();
Serial.println("AP IP address: ");
Serial.println(IP)

1-3. STA + AP 동시모드 (혼합 모드)

  • 개념 : Station 모드(STA)Access Point 모드(AP) 를 동시에 사용하는 모드입니다
  • 사용 상황 : ESP32가 자체 와이파이(AP)를 띄워서 설정 페이지를 제공하고, 그 설정 페이지에서 입력받은 공유기 정보를 이용해 STA 모드로 인터넷에 연결

장점

  • 설정이 유연하다.
  • OTA 업데이트나 로컬 서버 기능을 동시에 활용할 수 있다.
  • 스마트 홈, 무선 설정기기, 휴대용 데이터 로거 등에 유용하다.

2. Web Server 개념

  • 웹서버는 클라이언트(브라우저) 의 요청을 받아 웹페이지를 제공하는 역할을 합니다. ESP32는 간단한 웹서버를 구동해 다양한 센서 정보 제공 및 제어 가 가능합니다.

2-1. Web Server 구성 요소

  • 클라이언트: 보통 웹 브라우저 (Chrome, Safari 등)
  • ESP32 웹 서버: 웹 페이지를 제공하거나 데이터를 받는 역할
  • Wi-Fi 연결: AP 모드 또는 STA 모드로 연결

3. Web Server 실습

  • 핸드폰과 ESP32 핫스팟 연결할것, iPhone 사용시에는 개인용 핫스팟에 호환성 최대화 활성화 하기

  • 간단한 웹 서버 구축

#include <WiFi.h>        // WiFi 라이브러리를 포함합니다.
#include <WebServer.h>   // WebServer 라이브러리를 포함합니다.

const char* ssid = "iPhone03";             // 연결할 Wi-Fi의 SSID를 입력합니다.
const char* password = "j2y_031024";     // Wi-Fi의 비밀번호를 입력합니다.

WebServer server(80);                          // 포트 번호 80을 사용하여 WebServer 객체를 생성합니다.

void handleRoot() {
  server.send(200, "text/plain", "Hello from ESP32!");   // "/" 경로에 대한 요청을 처리하는 핸들러 함수입니다.
}

void setup() {
  Serial.begin(115200);                         // 시리얼 통신을 초기화합니다.

  WiFi.begin(ssid, password);                    // Wi-Fi에 연결합니다.
  Serial.println("Connected to WiFi");           
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }

  server.on("/", handleRoot);                    // "/" 경로에 대한 요청을 handleRoot() 함수로 처리합니다.

  while (WiFi.status() != WL_CONNECTED) {        // Wi-Fi 연결이 완료될 때까지 대기합니다.
      delay(500);
      Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());                // Wi-Fi의 로컬 IP 주소를 출력합니다.

  server.begin();                                // 서버를 시작합니다.
}

void loop() {
  server.handleClient();                         // 클라이언트의 요청을 처리합니다.
}
  • 실습 결과

4. 내장 LED를 제어하는 웹서버

  • 코드
// Import required libraries
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>

// Replace with your network credentials
const char* ssid = "iPhone03";
const char* password = "j2y_031024";

// 현재 출력 상태를 저장하는 보조 변수
String output2State = "off";

// GPIO 핀에 출력 변수 할당
const int output2 = 2;

// Create AsyncWebServer object on port 80
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";

// Replaces placeholder with button section in your web page
String processor(const String& var){
  //Serial.println(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 port for debugging purposes
  Serial.begin(115200);
  delay(3000);

  // 출력 변수를 출력으로 초기화
  pinMode(output2, OUTPUT);
  // 출력을 LOW로 설정
  digitalWrite(output2, LOW);
  
  // SSID와 비밀번호로 Wi-Fi 네트워크에 연결
  Serial.print("연결 중: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // 로컬 IP 주소 출력 및 웹 서버 시작
  Serial.println("");
  Serial.println("Wi-Fi 연결됨.");
  Serial.println("IP 주소: ");
  Serial.println(WiFi.localIP());
  
  // Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });

  // Send a GET request to <ESP_IP>/2/on 
  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);
  });

  // Send a GET request to <ESP_IP>/2/off
  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);
  });
  
  // Start server
  server.begin();
}

void loop() {

}
  • 실습 결과
6-1.mp4

5. 주의할점.

  • ESP32 간단한 웹 서버 구축할때 들어가는 디바이스 또한 핫스팟에 연결시켜야한다.
  • iPhoe 사용시에는 개인 핫스팟 설정에 있는 호환성 최대화 켜주기.
  • #include <ESPAsyncWebSrv.h>라이브러리 보다는 #include <ESPAsyncWebServer.h> 라이브러리 사용하기
⚠️ **GitHub.com Fallback** ⚠️