아두이노

ESP32 아두이노 웹서버 만들기: 스마트폰으로 LED 켜고 끄기 완벽 가이드

게임교수 2026. 8. 21. 21:13
반응형

아두이노(Arduino Uno) 프로젝트를 진행하다 보면 "스마트폰이나 PC 웹 브라우저에서 무선으로 장치를 제어하고 싶다"는 생각이 들 때가 있습니다. 기존 아두이노는 Wi-Fi 기능이 없어 별도의 실드나 모듈이 필요하지만, ESP32 보드를 활용하면 단 한 대의 보드만으로도 완벽한 웹서버(Web Server)를 구축할 수 있습니다.

이번 포스팅에서는 ESP32의 내장 Wi-Fi 기능을 활용하여, 동일한 네트워크 내의 웹 브라우저 접속을 통해 LED를 원격 제어하는 웹서버 시스템을 단계별로 구축해 보겠습니다. 기초 회로 구성부터 소스코드 한 줄 한 줄 분석, 그리고 자주 발생하는 오류 해결법까지 완벽하게 정리해 드립니다.




1. 준비물 및 하드웨어 회로 구성

실습을 위해 아래의 기본 부품을 준비해 주세요. ESP32는 3.3V 논리 레벨을 사용하므로 핀 연결 시 주의가 필요합니다.

  • ESP32 Dev Module (30핀 또는 38핀 호환 보드)
  • LED 1개220Ω 저항 1개 (ESP32 내장 LED 사용 시 생략 가능)
  • 브레드보드 및 점퍼선
  • Micro 5pin USB 케이블 (데이터 전송 지원용 필수)

[회로 연결 상세 안내]
1. LED의 긴 다리(아노드)를 220Ω 저항을 거쳐 ESP32의 GPIO 2번 핀에 연결합니다.
2. LED의 짧은 다리(캐소드)를 ESP32의 GND 핀에 연결합니다.
※ 대부분의 ESP32 개발 보드는 GPIO 2번에 파란색 내장 LED가 연결되어 있어, 외장 회로 없이 보드만으로도 바로 테스트 가능합니다.


2. ESP32 아두이노 IDE 환경 설정 및 웹서버 소스코드

아두이노 IDE에 ESP32 보드 라이브러리가 설치되어 있어야 합니다. (보드 매니저에서 'esp32 by Espressif Systems' 설치) 아래 소스코드의 YOUR_SSIDYOUR_PASSWORD 부분을 실제 사용 중인 Wi-Fi 정보로 변경해 주세요.

#include <WiFi.h>

// 접속할 Wi-Fi 정보 설정
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";

// 80번 포트(기본 HTTP 포트)로 웹서버 객체 생성
WiFiServer server(80);

// 제어할 LED 핀 정의 (GPIO 2)
const int ledPin = 2;

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  // Wi-Fi 네트워크 연결 시작
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi Connected!");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP()); // 할당받은 IP 주소 출력

  server.begin();
}

void loop() {
  WiFiClient client = server.available(); // 클라이언트 접속 대기

  if (client) {
    Serial.println("New Client Connected.");
    String currentLine = "";
    
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        
        if (c == '\n') {
          if (currentLine.length() == 0) {
            // HTTP 응답 헤더 전송
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();

            // HTML 웹페이지 디자인 및 UI 구현
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<style>body { font-family: Arial; text-align: center; margin-top: 50px; }");
            client.println(".button { font-size: 24px; padding: 15px 30px; margin: 10px; border-radius: 8px; border: none; cursor: pointer; }");
            client.println(".on { background-color: #4CAF50; color: white; }");
            client.println(".off { background-color: #f44336; color: white; }</style></head>");
            client.println("<body><h1>ESP32 Web Server Control</h1>");
            client.println("<p><a href=\"/H\"><button class=\"button on\">LED ON</button></a></p>");
            client.println("<p><a href=\"/L\"><button class=\"button off\">LED OFF</button></a></p>");
            client.println("</body></html>");
            client.println();
            break;
          } else {
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }

        // URL 요청에 따른 GPIO 제어 조건문
        if (currentLine.endsWith("GET /H")) {
          digitalWrite(ledPin, HIGH); // LED 켜기
        }
        if (currentLine.endsWith("GET /L")) {
          digitalWrite(ledPin, LOW);  // LED 끄기
        }
      }
    }
    client.stop();
    Serial.println("Client Disconnected.");
  }
}



3. 핵심 코드 원리 분석

코드가 작동하는 세부적 메커니즘을 파악하면 향후 다양한 센서 응용에 유용합니다.

1) HTTP 서버 개설 및 포트 설정
WiFiServer server(80); 구문은 웹에서 사용하는 기본 통신 규약인 80번 포트를 열어두겠다는 의미입니다. 사용자가 웹 브라우저 주소창에 IP 주소를 치면 ESP32의 80번 포트로 연결 요청이 들어오게 됩니다.

2) 웹 UI 반응형 스타일링
소스코드 내부의 <meta name=\"viewport\"...> 태그는 모바일 스마트폰 화면에서도 버튼이 깨지지 않고 보기 좋게 반응형으로 리사이징되도록 해줍니다. 버튼에는 CSS 속성을 부여해 가독성을 높였습니다.

3) GET 요청을 통한 동작 스위칭
사용자가 [LED ON] 버튼을 누르면 브라우저는 http://[IP주소]/H 경로로 GET 요청을 보냅니다. ESP32는 currentLine.endsWith("GET /H") 구문을 통해 이를 감지하고 digitalWrite(ledPin, HIGH)를 실행해 신호를 줍니다.


4. 실습 진행 및 웹서버 접속 테스트

  1. 코드 업로드: ESP32를 PC에 연결하고, 아두이노 IDE에서 보드와 포트를 맞춘 후 코드를 업로드합니다. (업로드 중 Connecting...... 메시지가 지속되면 보드의 BOOT 버튼을 1~2초간 눌러주세요.)
  2. IP 주소 확인: 시리얼 모니터(Baud Rate: 115200)를 엽니다. Wi-Fi에 성공적으로 연결되면 IP Address: 192.168.X.X 형식의 내부 IP가 출력됩니다.
  3. 웹 브라우저 접속: 동일한 Wi-Fi 공유기에 연결된 스마트폰이나 PC의 웹 브라우저를 열고, 시리얼 모니터에 찍힌 IP 주소를 그대로 입력합니다.
  4. 동작 확인: 화면에 나타난 [LED ON][LED OFF] 버튼을 눌러보며, 실제 ESP32의 GPIO 2번 LED가 동기화되어 켜지고 꺼지는지 확인합니다.

5. 트러블슈팅 (자주 발생하는 오류 해결법)

실습 도중 접속이 안 되거나 동작하지 않을 때 체크해야 할 3가지 사항입니다.

  • 웹페이지 접속 불가 (타임아웃 발생): PC/스마트폰과 ESP32가 서로 다른 Wi-Fi에 연결되어 있는지 확인하세요. (특히 5GHz Wi-Fi가 아닌 2.4GHz 대역 공유기에 똑같이 접속되어 있어야 합니다.)
  • 시리얼 모니터 외계어 출력: 아두이노 IDE 우측 하단의 보드레이트 설정이 115200 baud로 설정되어 있는지 확인하세요.
  • 코드 업로드 오류 (Failed to connect to ESP32): USB 케이블이 데이터 전송을 지원하는 케이블인지 확인하고, 업로드 진행 시 보드의 BOOT 버튼을 길게 누르면 해결됩니다.

6. 실전 활용 모듈 확장 팁

본 실습의 웹서버 로직은 IoT 응용 프로젝트의 가장 기초가 되는 뼈대입니다. 이 코드를 기반으로 다음과 같이 확장할 수 있습니다.

  • 릴레이 모듈(Relay) 결합: 220V 전원에 연결된 조명이나 가전제품을 웹 스위치로 제어하는 스마트홈 시스템 구축
  • DHT11/DHT22 센서 추가: 웹페이지에 실시간 온도 및 습도 데이터를 그래프 형태로 시각화
  • mDNS(ESPmDNS) 설정: 복잡한 IP 주소 대신 http://esp32.local 같은 고유 도메인 주소로 접속 가능하도록 개선

다음 포스팅에서는 ESP32 웹서버에 온습도 센서를 결합해 실시간 대시보드 구축하기 실습을 진행해 보겠습니다. 궁금한 점이나 오류가 발생하는 부분은 댓글로 남겨주세요!



반응형