ESP32 쿼리 문자열 웹 서버 동적 URL 매개변수

WebServerQueryStrings 예제 - 동적 다중 페이지 서버

개요

이 예제는 URL 쿼리 매개변수를 사용하여 대화형 콘텐츠를 제공하고 매끄러운 페이지 탐색으로 제어 기능을 구현하는 동적 다중 페이지 웹 서버를 만드는 방법을 보여줍니다.

주요 기능

  • 다중 페이지 내비게이션 URL 매개변수에 따라 동적으로 콘텐츠가 제공됩니다
  • 온도 단위 변환(섭씨/화씨)을 쿼리 매개변수를 통해 수행합니다
  • LED 제어를 쿼리 문자열 매개변수를 사용하여 구현합니다
  • 동적 콘텐츠 생성은 사용자 입력에 따라 수행됩니다
  • 전문적인 다중 페이지 레이아웃은 일관된 내비게이션과 함께 제공됩니다
  • URL 매개변수 파싱 및 검증을 수행합니다

준비물

1×ESP32 ESP-WROOM-32 개발 모듈 쿠팡 | 아마존
1×USB 케이블 타입-A to 타입-C (USB-A PC용) 쿠팡 | 아마존
1×USB 케이블 타입-C to 타입-C (USB-C PC용) 아마존
1×(추천) ESP32용 스크루 터미널 확장 보드 쿠팡 | 아마존
1×(추천) Breakout Expansion Board for ESP32 쿠팡 | 아마존
1×(추천) ESP32용 전원 분배기 쿠팡 | 아마존
공개: 이 포스팅 에 제공된 일부 링크는 아마존 제휴 링크입니다. 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

라이브러리 설치

다음 지침을 단계별로 따라가세요:

  • 이것이 ESP32를 처음 사용하는 경우에는 Arduino IDE에서 ESP32를 위한 환경 설정 튜토리얼을 참고하세요 Arduino IDE에서 ESP32를 위한 환경 설정 튜토리얼.
  • ESP32 보드를 USB 케이블로 컴퓨터에 연결하세요.
  • 컴퓨터에서 Arduino IDE를 실행하세요.
  • 적절한 ESP32 보드(예: ESP32)와 COM 포트를 선택하세요.
  • Arduino IDE의 왼쪽에 있는 Library Manager 아이콘을 클릭하여 라이브러리 매니저를 여세요.
  • Web Server for ESP32를 검색하고 DIYables의 mWebSockets를 찾아보세요.
  • Install 버튼을 클릭하여 mWebSockets 라이브러리를 추가하세요.
ESP32 웹 서버 라이브러리

웹 서버 쿼리 문자열 예시

  • Arduino IDE에서 File 예제 ESP32용 웹 서버 WebServerQueryStrings 예제 코드를 열려면

코드 구조

  1. home.h: 홈 페이지 HTML 템플릿
  2. temperature.h: 온도 모니터링 페이지 템플릿
  3. led.h: LED 제어 페이지 템플릿
  4. WebServerQueryStrings.ino: 메인 서버 로직

회로 연결

외부 부품이 필요하지 않습니다. 이 예제는 핀 13에 내장된 LED를 사용합니다.

쿼리 매개변수 기능

온도 페이지 매개변수

  • unit=c or unit=celsius - 섭씨로 온도를 표시
  • unit=f or unit=fahrenheit - 화씨로 온도를 표시
  • 매개변수가 없으면 기본값은 섭씨

LED 제어 매개변수

  • state=on - LED를 켭니다
  • state=off - LED를 끕니다

설정 지침

1. 네트워크 구성

WebServerQueryStrings.ino 파일에서 WiFi 자격 증명을 직접 편집하세요:

const char WIFI_SSID[] = "YOUR_WIFI_SSID"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";

2. 코드 업로드 및 출력 모니터링

  1. ESP32를 컴퓨터에 연결하세요
  2. Arduino IDE에서 올바른 보드와 포트를 선택하세요
  3. WebServerQueryStrings.ino 스케치를 업로드하세요
  4. 시리얼 모니터를 여세요(9600bps)
  5. WiFi 연결을 기다리세요
  6. 표시된 IP 주소를 확인하세요
  7. 시리얼 모니터에 IP 주소가 보이지 않으면 ESP32 보드의 리셋 버튼을 누르세요

사용 예시

웹 브라우저를 열고 시리얼 모니터에 표시된 IP 주소를 입력하여 웹 서버에 접속하십시오.

ESP32 웹 서버 쿼리 문자열

온도 모니터링 기능 테스트:

  • "온도" 메뉴를 클릭하세요.
  • 온도 표시를 확인하세요. 각 버튼을 클릭하여 온도 단위를 변경하세요.
ESP32 웹 서버의 온도 쿼리 문자열

LED 제어 기능을 테스트:

  • LED 제어 메뉴를 클릭하세요. 아래와 같이 웹 인터페이스가 표시됩니다:
LED 제어 페이지 쿼리 문자열
  • 제공된 버튼을 사용하여 LED를 켜고 끄세요.
  • ESP32 보드의 내장 LED 상태가 즉시 업데이트되는 것을 관찰하십시오.

다른 페이지에 접속하기

홈 페이지
  • 웹 주소: http://your-esp32-ip/
  • 주요 기능: 네비게이션 메뉴가 있는 환영 페이지
온도 페이지 (기본값 - 섭씨)
  • URL: http://your-esp32-ip/temperature
  • 표시: 단위 선택이 가능한 섭씨 온도
화씨 온도
  • 주소: http://your-esp32-ip/temperature?unit=f
  • 주소: http://your-esp32-ip/temperature?unit=fahrenheit
  • 표시: 화씨로 변환된 온도
LED 제어
  • 전원 켜기: http://your-esp32-ip/led?state=on
  • 전원 끄기: http://your-esp32-ip/led?state=off

코드 설명

쿼리 파라미터 처리

void handleTemperature(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { // Check for query parameter "unit" String unit = "C"; for (int i = 0; i < params.count; i++) { if (String(params.params[i].key) == "unit") { unit = params.params[i].value; } } // Generate temperature display based on unit String temperatureDisplay = "Simulated temperature: 25°" + unit; // Use the TEMPERATURE_PAGE template and replace placeholder String response = TEMPERATURE_PAGE; response.replace("%TEMPERATURE_VALUE%", temperatureDisplay); server.sendResponse(client, response.c_str()); }

쿼리 매개변수를 사용한 LED 제어

void handleLed(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { // Check for query parameter "state" String state = ""; for (int i = 0; i < params.count; i++) { if (String(params.params[i].key) == "state") { state = params.params[i].value; break; } } // Control LED based on state if (state == "on") { ledState = HIGH; digitalWrite(LED_PIN, ledState); } else if (state == "off") { ledState = LOW; digitalWrite(LED_PIN, ledState); } else if (state == "") { // No state parameter provided, just show current status } else { // Invalid state parameter client.println("HTTP/1.1 400 Bad Request"); client.println("Connection: close"); client.println(); client.print("Invalid state parameter. Use ?state=on or ?state=off"); return; } // Get current LED state String ledStatus = (ledState == HIGH) ? "ON" : "OFF"; // Use the LED_PAGE template and replace placeholders String response = LED_PAGE; response.replace("%LED_STATUS%", ledStatus); server.sendResponse(client, response.c_str()); }

매개변수 검증

// Helper function to find query parameter value String getQueryParam(const QueryParams& params, const String& key) { for (int i = 0; i < params.count; i++) { if (String(params.params[i].key) == key) { return params.params[i].value; } } return ""; } // Validation functions bool isValidTemperatureUnit(String unit) { unit.toLowerCase(); return (unit == "c" || unit == "celsius" || unit == "f" || unit == "fahrenheit" || unit == ""); } bool isValidLedState(String state) { return (state == "on" || state == "off" || state == ""); }

동적 콘텐츠가 포함된 HTML 템플릿

온도 페이지 템플릿

<div class="temperature-display"> <h2>Current Temperature</h2> <div class="temp-value">%TEMPERATURE% %UNIT%</div> <div class="unit-selector"> <p>Display in:</p> <a href="/temperature?unit=c" class="unit-btn">Celsius</a> <a href="/temperature?unit=f" class="unit-btn">Fahrenheit</a> </div> </div>

LED 제어 템플릿

<div class="led-control"> <h2>LED Control</h2> <div class="status">Status: <span>%LED_STATUS%</span></div> <div class="controls"> <a href="/led?state=on" class="btn btn-on">Turn ON</a> <a href="/led?state=off" class="btn btn-off">Turn OFF</a> </div> </div>

고급 기능

라우트 구성

void setup() { Serial.begin(9600); pinMode(LED_PIN, OUTPUT); ledState = LOW; digitalWrite(LED_PIN, ledState); // Initialize web server with credentials server.begin(WIFI_SSID, WIFI_PASSWORD); server.printWifiStatus(); // Add routes server.addRoute("/", handleHome); server.addRoute("/temperature", handleTemperature); server.addRoute("/led", handleLed); // Set custom 404 handler server.setNotFoundHandler(handleNotFound); }

쿼리 매개변수 헬퍼 함수들

// Extract parameter from QueryParams structure String getParam(const QueryParams& params, const String& key, const String& defaultValue = "") { for (int i = 0; i < params.count; i++) { if (String(params.params[i].key) == key) { return params.params[i].value; } } return defaultValue; } // Check if parameter exists bool hasParam(const QueryParams& params, const String& key) { for (int i = 0; i < params.count; i++) { if (String(params.params[i].key) == key) { return true; } } return false; }

URL 구성 도우미

// Helper to build URLs with parameters String buildLedUrl(String state) { return "/led?state=" + state; } String buildTempUrl(String unit) { return "/temperature?unit=" + unit; }

실제 구현 참고 사항

현재의 한계

실제 구현은 기능이 풍부한 웹 서버에 비해 단순화되어 있습니다:

  • 핸들러당 단일 매개변수 추출만 지원합니다.
  • 문자열 기반의 간단한 온도 시뮬레이션(단위 변환 없음)
  • 켜짐/꺼짐 상태만 지원하는 기본 LED 제어
  • 표준 핀 13 대신 핀 9를 사용합니다.

문제 해결

일반적인 문제

매개변수 작동하지 않음

  • URL 형식 확인: page?param=value
  • 매개변수 이름이 정확히 일치하는지 확인합니다 (대소문자 구분)
  • 현재 구현은 LED에 대해 state를 사용하고 있으며, action은 사용하지 않습니다.

LED 핀 이슈

  • 이 예제는 핀 9를 사용하며 핀 13은 사용하지 않습니다
  • LED_PIN 상수가 하드웨어와 일치하는지 확인하세요

쿼리 매개변수 접근

  • QueryParams 구조를 사용하고, server.arg()를 사용하지 마세요.
  • 특정 매개변수를 찾기 위해 params.params[i]를 순회합니다.

디버그 출력

void debugParameters(const QueryParams& params) { Serial.println("=== Request Parameters ==="); Serial.println("Params count: " + String(params.count)); for (int i = 0; i < params.count; i++) { Serial.print(" "); Serial.print(params.params[i].key); Serial.print(" = "); Serial.println(params.params[i].value); } Serial.println("========================"); }

맞춤화

매개변수가 있는 새 핸들러 추가

void handleCustomPage(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { String theme = getParam(params, "theme", "light"); String lang = getParam(params, "lang", "en"); // Process parameters and generate response String response = "<html><body>"; response += "<h1>Custom Page</h1>"; response += "<p>Theme: " + theme + "</p>"; response += "<p>Language: " + lang + "</p>"; response += "</body></html>"; server.sendResponse(client, response.c_str()); } // Register the new route in setup() server.addRoute("/custom", handleCustomPage);

템플릿 시스템 개선

실제 구현은 간단한 자리 표시자 교체를 사용합니다:

String response = TEMPERATURE_PAGE; response.replace("%TEMPERATURE_VALUE%", temperatureDisplay); // Add more replacements as needed response.replace("%UNIT%", unit); response.replace("%TIMESTAMP%", String(millis()));

다음 단계

  • REST API 개발을 위해 WebServerJson.ino를 탐색하기
  • 실시간 통신을 위해 WebServerWithWebSocket.ino를 사용하기
  • POST 매개변수를 사용하여 폼 핸들링을 구현하기

학습 자료