ESP32 맞춤형 웹앱 예제 초보자를 위한 간단한 웹 인터페이스 튜토리얼

개요

이 예제는 DIYables ESP32 WebApps 라이브러리와 원활하게 통합되는 자신만의 맞춤형 웹 애플리케이션을 만들기 위한 완전한 템플릿을 제공합니다.

아두이노 사용자 정의 웹앱 예제 - 나만의 웹 인터페이스 만들기 튜토리얼

CustomWebApp 템플릿은 DIYables ESP32 WebApps 생태계에 자신만의 웹 인터페이스를 추가하고 싶은 초보자에게 완벽합니다! 이 튜토리얼은 웹 브라우저와 ESP32 간의 WebSocket을 통한 실시간 양방향 데이터 교환이 가능한 간단한 웹 페이지를 구축하는 방법을 보여줍니다:

  • 웹 브라우저에서 ESP32로 WebSocket을 통해 텍스트 메시지를 즉시 전송
  • ESP32로부터 메시지를 수신하고 웹 페이지에 실시간으로 표시
  • 지속적인 통신을 위한 WebSocket 연결 유지
  • WebSocket 연결이 끊어지면 자동으로 재연결
  • 반응형 디자인으로 모바일 기기에서도 작동

ESP32용으로 설계되었습니다 - 이 템플릿은 기존 DIYables 웹 앱과 완벽하게 통합되며 자신만의 맞춤형 IoT 인터페이스를 구축하기 위한 토대를 제공합니다!

이 템플릿은 시작하는 데 필요한 최소한의 코드를 제공합니다.

사용자는 이 템플릿을 수정하여 자신만의 정교한 웹 애플리케이션을 개발할 수 있습니다.

웹 프로그래밍 기초 지식(HTML, CSS, JavaScript)은 웹 인터페이스를 커스터마이즈하고 고급 기능을 추가하기 위해 권장됩니다.

배울 내용

  • DIYables ESP32 WebApps 라이브러리와 통합되는 맞춤형 웹 앱 만들기
  • DIYables 웹 앱 생태계에 맞춤 페이지를 추가하는 방법
  • 웹 브라우저에서 ESP32로 문자 메시지를 보내는 방법
  • ESP32에서 웹 브라우저로 데이터 전송하는 방법
  • 웹소켓 연결을 처리하고 자동 재연결하는 방법
  • 모바일 반응형 웹 인터페이스를 만드는 방법
  • 빠른 개발을 위한 DIYables ESP32 WebApps 템플릿 시스템 사용 방법

주요 기능

  • DIYables ESP32 WebApps 통합: DIYables ESP32 WebApps 라이브러리 생태계와 매끄럽게 통합됩니다.
  • 최소 템플릿 코드: 확장하고 맞춤화할 수 있는 기본 토대를 제공합니다.
  • 템플릿 기반 개발: 수정하여 고급 애플리케이션을 만들 수 있는 완전한 시작점입니다.
  • 간단한 텍스트 메시지 전송: 웹 브라우저와 Arduino 간에 메시지를 보냅니다.
  • 자동 재연결: 연결이 끊어지면 자동으로 재연결합니다.
  • 모바일 반응형: 휴대폰, 태블릿 및 컴퓨터에서 완벽하게 작동합니다.
  • 초보자 친화적: 이해하기 쉬운 깔끔하고 단순한 코드입니다.
  • 확장 가능한 프레임워크: 고급 맞춤화를 위해 기본 웹 프로그래밍 지식(HTML/CSS/JavaScript)이 필요합니다.

준비물

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 보드를 위한 맞춤형 웹 애플리케이션을 구축하기 시작할 수 있습니다:

  • ESP32 보드에서 기본 사용자 정의 앱 템플릿을 실행합니다.
  • 기본 사용자 정의 웹 앱이 올바르게 작동하는지 테스트하고 확인합니다.
  • 통신 프로토콜과 백그라운드에서 작동하는 방식 이해합니다.
  • 템플릿을 수정하여 애플리케이션에 맞게 조정합니다.
  • 여러 개의 사용자 정의 웹 앱 관리에 대한 필수 충돌 방지 가이드

하나씩 시작합시다.

ESP32 보드에서 기본 커스텀 앱 템플릿 실행

자세한 사용 방법

  • ESP32를 처음 사용하는 경우 Arduino IDE에서 ESP32용 개발 환경 설정 튜토리얼을 참조하십시오 ESP32 - 소프트웨어 설치
  • USB 케이블로 ESP32 보드를 컴퓨터에 연결합니다
  • 컴퓨터에서 Arduino IDE를 실행합니다
  • 적절한 ESP32 보드(예: ESP32 Dev Module)와 COM 포트를 선택합니다
  • Arduino IDE의 왼쪽 바에 있는 Libraries 아이콘으로 이동합니다
  • "DIYables ESP32 WebApps"를 검색한 다음 DIYables에서 제공하는 DIYables ESP32 WebApps 라이브러리를 찾습니다
  • Install 버튼을 클릭하여 라이브러리를 설치합니다
diyables ESP32 웹앱 라이브러리
  • 다른 라이브러리 의존성 설치를 요청받게 됩니다
  • 모든 라이브러리 의존성을 설치하려면 Install All 버튼을 클릭하십시오
diyables ESP32 webapps 의존성
  • 아두이노 IDE에서 File > Examples > DIYables ESP32 WebApps > CustomWebApp 로 이동하세요
  • 완전한 커스텀 웹 앱 템플릿을 구성하는 4개의 파일이 표시됩니다:
  • CustomWebApp.ino - 메인 ESP32 코드(여기에 사용자 정의 로직을 추가합니다!)
  • CustomWebApp.h - 헤더 파일(DIYables ESP32 WebApps 라이브러리의 인터페이스를 정의합니다)
  • CustomWebApp.cpp - 구현 파일(라이브러리 프레임워크와의 통합을 처리합니다)
  • custom_page_html.h - 웹 페이지 디자인(여기에서 웹 인터페이스를 사용자 정의하세요!)
  • CustomWebApp.ino에서 WiFi 설정을 구성하려면 다음 줄들을 변경합니다:
const char WIFI_SSID[] = "YOUR_WIFI_NAME"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";

5단계: 업로드 및 테스트

  • Arduino IDE에서 Upload 버튼을 클릭하여 ESP32에 코드를 업로드합니다.
  • 연결 상태를 확인하려면 시리얼 모니터를 엽니다.
  • 시리얼 모니터에 표시된 IP 주소를 확인하세요.
  • 시리얼 모니터를 엽니다.
  • 시리얼 모니터에서 결과를 확인하세요. 아래와 같이 표시됩니다.
COM6
Send
Starting Custom WebApp... INFO: Added app / INFO: Added app /custom DIYables WebApp Library Platform: ESP32 Network connected! IP address: 192.168.0.2 HTTP server started on port 80 Configuring WebSocket server callbacks... WebSocket server started on port 81 WebSocket URL: ws://192.168.0.2:81 WebSocket server started on port 81 ========================================== DIYables WebApp Ready! ========================================== 📱 Web Interface: http://192.168.0.2 🔗 WebSocket: ws://192.168.0.2:81 📋 Available Applications: 🏠 Home Page: http://192.168.0.2/ 🔧 Custom WebApp: http://192.168.0.2/custom ==========================================
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  
  • 화면에 아무 것도 보이지 않으면 ESP32 보드를 재부팅하십시오.
  • 표시된 IP 주소를 메모해 두고 이 주소를 스마트폰이나 PC의 웹 브라우저 주소창에 입력하십시오.
  • 예시: http://192.168.0.2
  • 아래 그림과 같은 홈 페이지가 표시됩니다:
ESP32 diyables 웹앱 홈 페이지 및 웹 커스텀 앱
  • Web Custom 링크를 클릭하면 아래와 같이 Web Custom 앱의 UI가 표시됩니다:
ESP32 diyables 웹앱 웹 커스텀 앱
  • 또는 IP 주소 뒤에 /custom을 붙여 페이지에 직접 접근할 수도 있습니다. 예: http://[IP_ADDRESS]/custom

기본 사용자 정의 웹 앱이 올바르게 작동하는지 테스트하고 확인

기본 CustomWebApp 템플릿을 실행하면 다음과 같은 내용을 보게 됩니다:

웹 인터페이스에서:

  • 연결 상태: WebSocket이 활성화되면 파란색으로 'Connected'를 표시합니다
  • 메시지 입력 상자: 아두이노에 보낼 메시지를 입력하는 텍스트 필드
  • 보내기 버튼: 클릭하여 메시지를 보냅니다(또는 Enter 키를 누르세요)
  • 아두이노 메시지 표시: ESP32로부터 수신된 메시지를 파란색 텍스트로 표시합니다

ESP32 동작:

  • 에코 응답: 웹에서 "Hello"를 보낼 때 ESP32는 "Echo: Hello"로 응답합니다
  • 주기적 업데이트: ESP32는 매 5초마다 가동 시간 메시지를 보냅니다: "Arduino uptime: X seconds"
  • 시리얼 모니터: 수신된 모든 메시지는 디버깅을 위해 기록됩니다

의사소통 테스트:

  1. 메시지를 입력하세요 입력 상자에 (예: "test message")
  2. 전송 버튼을 클릭하거나 Enter 키를 누르세요
  3. 시리얼 모니터를 확인 - 보시면: "Received from web: test message"
  4. 웹 페이지를 확인 - 보시면: "Echo: test message"
  5. 잠시 기다리세요 - 3초마다 업데이트되는 주기적 가동 시간 메시지가 표시됩니다(예: "Arduino uptime: 15 seconds", "Arduino uptime: 18 seconds" 등)

통신 프로토콜 이해 및 백그라운드에서 작동하는 방식

내부 메커니즘을 이해하면 템플릿을 효과적으로 사용자 정의하는 데 도움이 됩니다.

앱 식별자 시스템

CustomWebApp 템플릿은 고유한 메시지 태그(“App Identifiers”라고 불림)를 사용하여 ESP32 코드와 웹 클라이언트가 자신에게 속한 메시지를 필터링하도록 돕습니다. 이는 애플리케이션에 여러 개의 웹 앱이 포함될 수 있으며 각 앱은 다른 앱의 메시지를 무시하고 자신의 메시지만 처리해야 하기 때문에 필수적입니다:

ESP32 측 (CustomWebApp.h 및 CustomWebApp.cpp)

// In CustomWebApp.h class CustomWebAppPage : public DIYablesWebAppPageBase { private: // WebSocket message identifier for this custom app static const String APP_IDENTIFIER; // ... }; // In CustomWebApp.cpp const String CustomWebAppPage::APP_IDENTIFIER = "CUSTOM:"; // Usage in handleWebSocketMessage: if (message.startsWith(APP_IDENTIFIER)) { String payload = message.substring(APP_IDENTIFIER.length()); // Process clean payload without identifier } // Usage in sendToWeb: broadcastToAllClients(APP_IDENTIFIER + message);

자바스크립트 측 (custom_page_html.h)

// WebSocket message identifier for this custom app const APP_IDENTIFIER = 'CUSTOM:'; // Usage in receiving: if (event.data.startsWith(APP_IDENTIFIER)) { let message = event.data.substring(APP_IDENTIFIER.length); // Process clean message without identifier } // Usage in sending: ws.send(APP_IDENTIFIER + userInput);

이 디자인의 이점:

  • 단일 진실의 원천: 언어당 한 곳에서 식별자를 변경합니다.
  • 하드코드된 문자열 없음: 코드 전체에서 하드코드된 "CUSTOM:"을 제거합니다.
  • 타입 안전성: 상수를 사용하면 오타를 방지할 수 있습니다.
  • 확장 가능: 서로 다른 식별자로 여러 개의 커스텀 앱을 쉽게 만들 수 있습니다.
  • 다중 앱 간 데이터 충돌 방지: 각 앱은 메시지 간섭을 방지하기 위해 고유한 식별자를 사용합니다.
  • 전문적: 객체지향 설계 원칙을 준수합니다.

중요한 주의사항:

  • 이 사용자 정의 웹 앱 템플릿을 수정하여 프로젝트에 맞게 조정할 때 현재 식별자 "CUSTOM:"를 유지할 수 있습니다. 다만 하나 이상의 사용자 정의 앱을 생성할 경우 충돌을 피하기 위해 이를 변경해야 합니다.
  • 식별자를 변경하는 경우, JavaScript (.h 파일)와 ESP32 코드 (.cpp 파일)의 값이 동일한지 확인하십시오(예: 둘 다 "TEMP:"를 사용하거나 둘 다 "SENSOR:"를 사용).
  • 빌트인 앱에 의해 미리 예약된 식별자: 아래 식별자는 이미 DIYables ESP32 WebApps 내장 애플리케이션에서 사용 중이며 피해야 합니다:
  • 주요 앱 식별자: "CHAT:", "MONITOR:", "PLOTTER:", "DIGITAL_PINS:", "JOYSTICK:", "SLIDER:", "TABLE:", "RTC:", "ROTATOR:", "GAUGE:"
  • 하위 프로토콜 식별자: "TIME:", "DATETIME:", "JOYSTICK_CONFIG:", "PLOTTER_DATA:", "PLOTTER_CONFIG:", "SLIDER_VALUES:", "TABLE_CONFIG:", "TABLE_DATA:", "VALUE_UPDATE:", "PIN_CONFIG:", "PIN_STATES:", "PIN_UPDATE:"

의사소통 흐름

웹 페이지에서 ESP32로:

웹 인터페이스에서 메시지를 입력하고 전송 버튼을 클릭하면, 예를 들어 Hello와 같이 아래의 흐름이 발생합니다:

  1. 자바스크립트가 식별자를 추가합니다: 템플릿에서의 앱 식별자는 CUSTOM:이며, APP_IDENTIFIER 상수를 사용해 자동으로 식별자를 첨부한 뒤 WebSocket을 통해 ESP32로 메시지를 보냅니다. 실제로 전송되는 메시지는: CUSTOM:Hello
  2. DIYables ESP32 WebApps 라이브러리가 수신합니다: 라이브러리는 CUSTOM:Hello 메시지를 수신하고 이를 당신의 CustomWebAppPage::handleWebSocketMessage 메서드로 전달합니다
  3. CustomWebAppPage 클래스가 식별자를 제거합니다: handleWebSocketMessage에서 CustomWebAppPage 클래스는 메시지가 자신의 APP_IDENTIFIER로 시작하는지 확인하고, .substring(APP_IDENTIFIER.length())를 사용해 식별자를 제거한 뒤 남은 메시지 Hello를 당신의 .ino 파일에 구현된 콜백 함수를 호출해 전달합니다
  4. 당신의 애플리케이션이 처리합니다: .ino 파일의 애플리케이션은 단지 Hello를 수신하고 사용자 정의 로직에 따라 메시지를 처리할 수 있습니다. 현재 템플릿은 이를 출력하고 응답을 보냅니다

ESP32에서 웹 페이지로:

ESP32가 웹 인터페이스로 데이터를 보내고자 할 때, 예를 들어: Temperature: 25°C처럼 아래의 흐름이 발생합니다:

  1. 당신의 애플리케이션이 sendToWeb()를 호출합니다: 당신의 .ino 파일에서 customPage.sendToWeb("Temperature: 25°C")를 호출하여 데이터를 웹 브라우저로 보냅니다
  2. CustomWebAppPage 클래스가 식별자를 추가하고 방송합니다: CustomWebAppPage 클래스는 메시지에 앱 식별자를 자동으로 추가하기 위해 APP_IDENTIFIER 상수를 사용하고 WebSocket을 통해 연결된 모든 웹 클라이언트에 CUSTOM:Temperature: 25°C를 브로드캐스트합니다
  3. 자바스크립트가 메시지를 수신하고 필터링합니다: 웹 브라우저는 ws.onmessage 이벤트 핸들러를 통해 CUSTOM:Temperature: 25°C를 수신하지만, 자바스크립트는 APP_IDENTIFIER로 시작하는 메시지만 처리하고 .substring(APP_IDENTIFIER.length())를 사용해 식별자를 잘라냅니다
  4. 웹 페이지가 깨끗한 메시지를 표시합니다: 현재 템플릿은 "Arduino로부터의 메시지" 섹션에 식별자 없이 깨끗한 메시지인 Temperature: 25°C를 표시합니다. 애플리케이션의 필요에 따라 데이터를 파싱하고 표시하는 방법을 자바스크립트를 수정하여 다양한 방식으로 표시할 수 있습니다

아키텍처 개요

CustomWebApp 예제는 네 개의 주요 파일로 구성되어 있습니다:

  1. CustomWebApp.ino - 애플리케이션 로직이 포함된 메인 ESP32 스케치
  2. CustomWebApp.h - 커스텀 페이지 클래스를 정의하는 헤더 파일(라이브러리 인터페이스)
  3. CustomWebApp.cpp - 통신 로직을 구현한 코드(라이브러리 코드)
  4. custom_page_html.h - 손쉽게 커스터마이즈할 수 있도록 분리된 HTML 인터페이스

템플릿을 수정하여 애플리케이션에 맞게 조정하기

템플릿은 귀하의 특정 필요에 맞게 쉽게 사용자화할 수 있도록 설계되었습니다. 이를 조정하는 방법은 다음과 같습니다:

1. 하드웨어 통합

하드웨어 초기화 추가하기

CustomWebApp.ino의 setup() 함수에서:

void setup() { Serial.begin(9600); // Add your hardware initialization here pinMode(LED_BUILTIN, OUTPUT); // Built-in LED pinMode(3, OUTPUT); // PWM output pin pinMode(4, INPUT_PULLUP); // Button input with pullup pinMode(A0, INPUT); // Analog sensor input // Initialize sensors, displays, motors, etc. // servo.attach(9); // lcd.begin(16, 2); // Rest of setup... webAppsServer.addApp(&homePage); webAppsServer.addApp(&customPage); webAppsServer.begin(WIFI_SSID, WIFI_PASSWORD);

사용자 정의 명령 처리

콜백 함수를 확장하여 사용자 정의 명령을 처리하도록 하세요:

customPage.onCustomMessageReceived([](const String& message) { Serial.println("Received: " + message); // LED Control if (message == "led_on") { digitalWrite(LED_BUILTIN, HIGH); customPage.sendToWeb("LED turned ON"); } else if (message == "led_off") { digitalWrite(LED_BUILTIN, LOW); customPage.sendToWeb("LED turned OFF"); } // Servo Control else if (message.startsWith("servo:")) { int angle = message.substring(6).toInt(); // Get number after "servo:" // servo.write(angle); customPage.sendToWeb("Servo moved to " + String(angle) + " degrees"); } // Sensor Reading Request else if (message == "get_temperature") { float temp = readTemperatureSensor(); // Your sensor function customPage.sendToWeb("Temperature: " + String(temp) + "°C"); } // Add more custom commands here });

실시간 센서 데이터 전송

void loop() { webAppsServer.loop(); // Send sensor data every 3 seconds static unsigned long lastSend = 0; if (millis() - lastSend > 3000) { // Read your sensors int lightLevel = analogRead(A0); bool buttonPressed = !digitalRead(4); // Inverted due to pullup float temperature = readTemperatureSensor(); // Send to web interface customPage.sendToWeb("Light: " + String(lightLevel)); customPage.sendToWeb("Button: " + String(buttonPressed ? "Pressed" : "Released")); customPage.sendToWeb("Temp: " + String(temperature) + "°C"); lastSend = millis(); } }

2. 웹 인터페이스 커스터마이징

HTML 레이아웃 수정

인터페이스를 변경하려면 custom_page_html.h의 HTML을 편집하세요:

<!-- Add new controls --> <div> <h3>🔌 Device Control</h3> <button onclick="send('led_on')">LED ON</button> <button onclick="send('led_off')">LED OFF</button> <br><br> <label>Servo Angle:</label> <input type="range" id="servoSlider" min="0" max="180" value="90" onchange="send('servo:' + this.value)"> <span id="servoValue">90°</span> </div> <div> <h3>📊 Sensor Data</h3> <div>Temperature: <span id="tempValue">--°C</span></div> <div>Light Level: <span id="lightValue">--</span></div> <div>Button Status: <span id="buttonValue">--</span></div> </div>

JavaScript 처리 맞춤 설정

ws.onmessage 함수를 특정 데이터 타입을 처리하도록 업데이트:

ws.onmessage = function(event) { if (event.data.startsWith(APP_IDENTIFIER)) { let message = event.data.substring(APP_IDENTIFIER.length); // Display all messages in general area document.getElementById('rawMessage').textContent = message; // Handle specific message types if (message.startsWith('Temperature:')) { let temp = message.split(':')[1].trim(); document.getElementById('tempValue').textContent = temp; } else if (message.startsWith('Light:')) { let light = message.split(':')[1].trim(); document.getElementById('lightValue').textContent = light; } else if (message.startsWith('Button:')) { let button = message.split(':')[1].trim(); document.getElementById('buttonValue').textContent = button; } } };

스타일 추가

애플리케이션용 CSS를 사용자 정의하세요:

<style> .control-panel { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 15px; padding: 20px; margin: 10px 0; color: white; } .sensor-display { background: #f8f9fa; border: 2px solid #e9ecef; border-radius: 10px; padding: 15px; margin: 10px 0; } button { background: #007bff; color: white; border: none; padding: 10px 20px; border-radius: 5px; margin: 5px; cursor: pointer; } button:hover { background: #0056b3; } </style>

기타 맞춤 설정

웹 인터페이스와 하드웨어 통합을 넘어서도, DIYables ESP32 WebApps 생태계에서 귀하의 앱이 어떻게 보이도록 맞춤화할 수 있습니다:

1. 앱 경로 사용자 지정

헤더 파일의 생성자를 수정하여 사용자 정의 웹 앱에 접근할 수 있는 URL 경로를 변경할 수 있습니다:

기본 경로:

// In CustomWebApp.cpp - Default path is "/custom" CustomWebAppPage::CustomWebAppPage() : DIYablesWebAppPageBase("/custom") { }

사용자 정의 경로 예시:

// Temperature monitoring app CustomWebAppPage::CustomWebAppPage() : DIYablesWebAppPageBase("/new-path") { } // Accessible at: http://[IP_ADDRESS]/new-path

중요한 주의사항:

  • 경로는 '/'로 시작해야 합니다: 경로는 항상 '/'로 시작해야 합니다
  • 설명적인 이름을 사용하세요: 앱의 기능을 명확히 설명하는 경로를 선택하세요
  • 충돌을 피하세요: /chat, /monitor, /plotter 등 내장 앱이 이미 차지하고 있는 경로를 사용하지 마세요
  • 소문자와 하이픈을 사용하세요: 더 나은 호환성을 위해 웹 URL 표준을 따르세요

2. 홈 페이지에서 앱 카드 맞춤 설정

구현 파일의 getNavigationInfo() 메서드를 수정하여 DIYables ESP32 WebApps의 홈 페이지에 앱이 표시되는 방식을 사용자 정의할 수 있습니다:

기본 앱 카드:

// In CustomWebApp.cpp String CustomWebAppPage::getNavigationInfo() const { return "<a href=\"" + getPagePath() + "\" class=\"app-card\">" "<h3>🔧 Custom App</h3>" "<p>My custom web application</p>" "</a>"; }

인라인 CSS가 포함된 고급 앱 카드:

// In CustomWebApp.cpp String CustomWebAppPage::getNavigationInfo() const { return "<a href=\"" + getPagePath() + "\" class=\"app-card\" " "style=\"background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);\">" "<h3>🌡️ Temperature Monitor</h3>" "<p>Real-time temperature monitoring</p>" "</a>"; }

다중 맞춤형 웹 앱 관리 - 필수 충돌 예방 가이드

여러 개의 맞춤형 웹 애플리케이션을 개발할 때 서로 다른 애플리케이션 간의 충돌을 피하는 것이 중요합니다. ESP32 프로젝트에 'Temperature Monitor', 'Motor Controller', 'Sensor Dashboard'라는 세 개의 맞춤형 애플리케이션을 추가하고자 한다고 가정해 봅시다. 다음은 이들이 함께 조화롭게 작동하도록 보장하는 방법입니다:

1. 고유한 앱 식별자 사용

각 사용자 정의 웹 앱은 메시지 충돌을 방지하기 위해 고유한 식별자를 가져야 합니다:

예시: 온도 모니터링 앱

// In TemperatureApp.cpp const String TemperatureAppPage::APP_IDENTIFIER = "TEMP:"; // JavaScript in temperature_page_html.h const APP_IDENTIFIER = 'TEMP:';

예시: 모터 컨트롤러 앱

// In MotorApp.cpp const String MotorAppPage::APP_IDENTIFIER = "MOTOR:"; // JavaScript in motor_page_html.h const APP_IDENTIFIER = 'MOTOR:';

예시: 센서 대시보드 앱

// In SensorApp.cpp const String SensorAppPage::APP_IDENTIFIER = "SENSOR:"; // JavaScript in sensor_page_html.h const APP_IDENTIFIER = 'SENSOR:';

2. 고유한 페이지 경로 사용

각 웹 애플리케이션은 고유한 URL 경로가 필요합니다:

// Temperature App TemperatureAppPage::TemperatureAppPage() : DIYablesWebAppPageBase("/temperature") { } // Motor Controller App MotorAppPage::MotorAppPage() : DIYablesWebAppPageBase("/motor") { } // Sensor Dashboard App SensorAppPage::SensorAppPage() : DIYablesWebAppPageBase("/sensors") { }

3. 고유한 클래스 이름 사용

설명적인 클래스 이름을 사용하여 이름 충돌을 피하십시오:

// Instead of multiple "CustomWebAppPage" classes class TemperatureMonitorPage : public DIYablesWebAppPageBase { }; class MotorControllerPage : public DIYablesWebAppPageBase { }; class SensorDashboardPage : public DIYablesWebAppPageBase { };

4. 하나의 프로젝트에서 여러 앱 구성하기

다음은 여러 개의 커스텀 앱으로 프로젝트를 구성하는 방법입니다:

// In main .ino file #include "TemperatureApp.h" #include "MotorApp.h" #include "SensorApp.h" // Create instances DIYablesHomePage homePage; TemperatureMonitorPage tempPage; MotorControllerPage motorPage; SensorDashboardPage sensorPage; void setup() { // Add all pages to server webAppsServer.addApp(&homePage); // pre-built app webAppsServer.addApp(&tempPage); webAppsServer.addApp(&motorPage); webAppsServer.addApp(&sensorPage); webAppsServer.begin(WIFI_SSID, WIFI_PASSWORD); // Set up callbacks for each app tempPage.onTemperatureMessageReceived([](const String& message) { // Handle temperature app messages }); motorPage.onMotorMessageReceived([](const String& message) { // Handle motor app messages }); sensorPage.onSensorMessageReceived([](const String& message) { // Handle sensor app messages }); }

5. 다중 앱을 위한 모범 사례

파일 구성
MyProject/ ├── MyProject.ino // Main sketch ├── TemperatureApp.h // Temperature app header ├── TemperatureApp.cpp // Temperature app implementation ├── temperature_page_html.h // Temperature app web page ├── MotorApp.h // Motor app header ├── MotorApp.cpp // Motor app implementation ├── motor_page_html.h // Motor app web page ├── SensorApp.h // Sensor app header ├── SensorApp.cpp // Sensor app implementation └── sensor_page_html.h // Sensor app web page

앱 간 탐색

각 앱에서 getNavigationInfo() 메서드를 업데이트하여 쉬운 탐색을 제공합니다:

String TemperatureMonitorPage::getNavigationInfo() const { return "<a href=\"" + getPagePath() + "\" class=\"app-card temperature\">" "<h3>🌡️ Temperature Monitor</h3>" "<p>View real-time temperature data</p>" "</a>"; } String MotorControllerPage::getNavigationInfo() const { return "<a href=\"" + getPagePath() + "\" class=\"app-card motor\">" "<h3>⚙️ Motor Controller</h3>" "<p>Control servo and stepper motors</p>" "</a>"; }

6. 다중 앱 테스트

여러 앱을 테스트할 때:

  1. 먼저 각 앱을 개별적으로 테스트하세요
  2. 시리얼 모니터에서 메시지 충돌 여부를 확인하세요
  3. 고유 식별자들이 정상 작동하는지 확인하세요
  4. 다른 앱 간의 이동을 테스트하세요
  5. 여러 앱이 로드된 상태에서 메모리 사용량을 모니터링하세요

이 가이드라인을 따르면 서로 간섭하지 않으면서도 다른 DIYables ESP32 WebApps와도 매끄럽게 함께 작동하는 여러 개의 맞춤형 웹 애플리케이션을 만들 수 있습니다.