아두이노(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_SSID와 YOUR_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. 실습 진행 및 웹서버 접속 테스트
- 코드 업로드: ESP32를 PC에 연결하고, 아두이노 IDE에서 보드와 포트를 맞춘 후 코드를 업로드합니다. (업로드 중
Connecting......메시지가 지속되면 보드의 BOOT 버튼을 1~2초간 눌러주세요.) - IP 주소 확인: 시리얼 모니터(Baud Rate: 115200)를 엽니다. Wi-Fi에 성공적으로 연결되면
IP Address: 192.168.X.X형식의 내부 IP가 출력됩니다. - 웹 브라우저 접속: 동일한 Wi-Fi 공유기에 연결된 스마트폰이나 PC의 웹 브라우저를 열고, 시리얼 모니터에 찍힌 IP 주소를 그대로 입력합니다.
- 동작 확인: 화면에 나타난 [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 웹서버에 온습도 센서를 결합해 실시간 대시보드 구축하기 실습을 진행해 보겠습니다. 궁금한 점이나 오류가 발생하는 부분은 댓글로 남겨주세요!
'아두이노' 카테고리의 다른 글
| OpenCV + MediaPipe로 손가락 개수 인식해 아두이노 LED 제어하기 – Computer Vision Gesture Control (0) | 2026.08.21 |
|---|---|
| [아두이노 + TinyML] 손 제스처 인식 컨트롤러 만들기 – Arduino Nano 33 BLE Sense 활용법 완전 정복 (2) | 2025.04.25 |
| 아두이노 + RTC 모듈로 디지털 시계 만들기 – DS3231 연결부터 LCD 출력까지 완벽 정리 (0) | 2025.04.23 |
| 아두이노 블로그 시리즈 – 블루투스로 모터 제어하기 (HC-06) (0) | 2025.04.22 |
| 아두이노 UART 디버깅 콘솔 확장 – 설정값 EEPROM에 저장하기 (0) | 2025.04.21 |