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

개요

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

아두이노 맞춤형 웹앱 예제 - 나만의 웹 인터페이스 만들기 튜토리얼

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

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

Arduino Uno R4 WiFi 및 DIYables STEM V4 IoT용으로 설계되었습니다. 이 템플릿은 기존 DIYables 웹 앱과 완벽하게 통합되며 사용자가 직접 맞춤형 IoT 인터페이스를 구축하는 데 필요한 기반을 제공합니다!

이 템플릿은 시작하는 데 필요한 최소한의 코드를 제공합니다. 사용자는 이 템플릿을 수정하여 자신만의 정교한 웹 애플리케이션을 개발할 수 있습니다. 웹 인터페이스를 커스터마이징하고 고급 기능을 추가하려면 기본적인 웹 프로그래밍 지식(HTML, CSS, JavaScript)이 권장됩니다.

배울 내용

  • DIYables WebApps 라이브러리와 통합되는 맞춤형 웹 앱을 만드는 방법
  • DIYables WebApps 생태계에 사용자 정의 페이지를 추가하는 방법
  • 웹 브라우저에서 Arduino로 텍스트를 보내는 방법
  • Arduino에서 웹 브라우저로 데이터를 보내는 방법
  • WebSocket 연결 처리 및 자동 재연결 방법
  • 모바일 반응형 웹 인터페이스를 만드는 방법
  • DIYables WebApps 템플릿 시스템 활용 방법

주요 기능

  • DIYables WebApps 연동: DIYables WebApps 라이브러리 생태계와 원활하게 연동합니다
  • 최소 템플릿 코드: 확장하고 사용자화할 수 있는 기본 토대를 제공합니다
  • 템플릿 기반 개발: 정교한 애플리케이션을 만들기 위해 수정할 수 있는 완전한 시작점을 제공합니다
  • 간단한 텍스트 메시지 전송: 웹 브라우저와 Arduino 간에 메시지를 주고받습니다
  • 자동 재연결: 연결이 끊겼을 때 자동으로 재연결합니다
  • 모바일 반응형: 휴대폰, 태블릿, 컴퓨터에서 완벽하게 작동합니다
  • 초보자 친화적: 이해하기 쉬운 깔끔하고 단순한 코드
  • 확장 가능한 프레임워크: 고급 사용자화를 위해서는 기본 웹 프로그래밍 지식(HTML/CSS/자바스크립트)이 필요합니다
  • 플랫폼 확장 가능: 현재 Arduino Uno R4 WiFi에 대해 구현되어 있지만, 다른 하드웨어 플랫폼으로도 확장할 수 있습니다. 자세한 내용은 DIYables_WebApps_ESP32를 참조하십시오

준비물

1×아두이노 우노 R4 와이파이 쿠팡 | 아마존
1×(또는) DIYables STEM V4 IoT 쿠팡 | 아마존
1×USB 케이블 타입-A to 타입-C (USB-A PC용) 쿠팡 | 아마존
1×USB 케이블 타입-C to 타입-C (USB-C PC용) 아마존
1×(추천) 아두이노 우노 R4용 스크루 터미널 블록 쉴드 쿠팡 | 아마존
1×(추천) 아두이노 우노 R4용 브레드보드 쉴드 쿠팡 | 아마존
1×(추천) 아두이노 우노 R4용 케이스 쿠팡 | 아마존
1×(추천) 아두이노 우노 R4용 전원 분배기 쿠팡 | 아마존
1×(추천) 아두이노 우노용 프로토타이핑 베이스 플레이트 & 브레드보드 키트 아마존
공개: 이 포스팅 에 제공된 일부 링크는 아마존 제휴 링크입니다. 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

시작하는 방법

다음의 주요 단계를 거치면 Arduino Uno R4/DIYables STEM V4 IoT 보드용 맞춤 웹 애플리케이션 구축을 시작할 수 있습니다.

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

하나씩 시작합시다.

기본 사용자 정의 앱 템플릿을 귀하의 아두이노 보드에서 실행하기

자세한 사용 방법

  • Arduino Uno R4 WiFi/DIYables STEM V4 IoT를 처음 사용하는 경우, 아두이노 우노 R4 - 소프트웨어 설치을 참조하십시오.
  • USB 케이블을 사용하여 컴퓨터에 Arduino Uno R4/DIYables STEM V4 IoT 보드를 연결합니다.
  • 컴퓨터에서 Arduino IDE를 실행합니다.
  • 적합한 Arduino Uno R4 보드(예: 아두이노 우노 R4 와이파이)와 COM 포트를 선택합니다.
  • Arduino IDE의 왼쪽 사이드 바에 있는 Libraries 아이콘으로 이동합니다.
  • "DIYables WebApps"를 검색한 후, DIYables에서 제공하는 DIYables WebApps 라이브러리를 찾습니다.
  • 라이브러리를 설치하려면 Install 버튼을 클릭합니다.
아두이노 우노 R4 diyables 웹앱 라이브러리
  • 다른 라이브러리 의존성을 설치하라는 메시지가 표시됩니다
  • 모든 라이브러리 의존성을 설치하려면 Install All 버튼을 클릭하세요
아두이노 우노 R4 diyables 웹앱 의존성
  • Arduino IDE에서 파일 > 예제 > DIYables WebApps > CustomWebApp로 이동합니다.
  • 완전한 사용자 정의 웹 앱 템플릿을 구성하는 4개의 파일이 표시됩니다:
  • CustomWebApp.ino - 메인 아두이노 코드 (여기에 사용자 정의 로직을 추가합니다!)
  • CustomWebApp.h - 헤더 파일(DIYables 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 버튼을 클릭하여 Arduino UNO R4/DIYables STEM V4 IoT에 코드를 업로드합니다.
  • 시리얼 모니터를 열어 연결 상태를 확인합니다.
  • 시리얼 모니터에 표시된 IP 주소를 확인하세요.
  • 시리얼 모니터를 엽니다.
  • 시리얼 모니터에서 결과를 확인하세요. 아래와 같은 결과가 표시됩니다.
COM6
Send
Starting Custom WebApp... INFO: Added app / INFO: Added app /custom DIYables WebApp Library Platform: Arduino Uno R4 WiFi 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  
  • 아무 것도 보이지 않으면 Arduino 보드를 재부팅하십시오.
  • 표시된 IP 주소를 메모해 두고, 이 주소를 스마트폰이나 PC의 웹 브라우저의 주소 표시줄에 입력하십시오.
  • 예: http://192.168.0.2
  • 아래 이미지와 같은 홈 페이지가 표시됩니다:
아두이노 우노 R4 diyables 웹앱 홈 페이지 웹 커스텀 앱 포함
  • 웹 커스텀 링크를 클릭하면 아래와 같은 웹 커스텀 앱의 UI가 표시됩니다:
아두이노 우노 r4 diyables 웹앱 웹 커스텀 앱
  • 또한 IP 주소 뒤에 /custom를 붙여 페이지에 직접 접속할 수 있습니다. 예를 들어: http://[IP_ADDRESS]/custom

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

기본 CustomWebApp 템플릿을 실행하면 다음과 같은 화면이 표시됩니다:

웹 인터페이스에서:

  • 연결 상태: WebSocket이 활성화되면 파란색으로 '연결됨'이 표시됩니다
  • 메시지 입력 상자: 아두이노로 보낼 메시지를 입력하는 텍스트 필드
  • 전송 버튼: 메시지를 보내려면 클릭하거나 Enter 키를 누르세요
  • 아두이노 메시지 표시: 아두이노로부터 수신된 메시지를 파란색 글씨로 표시합니다

아두이노 동작:

  • 에코 응답: 웹에서 "Hello"를 보낼 때 아두이노는 "Echo: Hello"로 응답합니다.
  • 주기적 업데이트: 아두이노는 매 5초마다 가동 시간 메시지를 보냅니다: "아두이노 가동 시간: X초"
  • 시리얼 모니터: 모든 수신 메시지는 디버깅을 위해 로그에 남겨집니다.

소통 테스트:

  1. 입력 상자에 메시지를 입력하세요 (예: "테스트 메시지")
  2. 보내기를 클릭하거나 Enter 키를 누르세요
  3. 시리얼 모니터를 확인하세요 - 화면에 다음과 같이 표시되어야 합니다: "웹에서 수신: 테스트 메시지"
  4. 웹 페이지를 확인하세요 - 화면에 다음과 같이 표시되어야 합니다: "에코: 테스트 메시지"
  5. 잠시 기다리세요 - 3초마다 업데이트되는 주기적인 가동 시간 메시지가 표시됩니다(예: "아두이노 가동 시간: 15초", "아두이노 가동 시간: 18초" 등)

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

내부 작동 원리를 이해하면 템플릿을 효과적으로 맞춤 설정하는 데 도움이 됩니다.

앱 식별자 시스템

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

아두이노 측 (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 파일)와 Arduino 코드 (.cpp 파일)에서의 값이 동일한지 확인하십시오(예: 둘 다 "TEMP:"를 사용하거나 둘 다 "SENSOR:"를 사용).
  • 내장 앱에 의해 미리 예약된 식별자들: 아래의 식별자들은 DIYables 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:"

의사소통 흐름

웹 페이지에서 아두이노로:

웹 인터페이스에 메시지를 입력하고 보내기 버튼을 클릭하면, 예를 들어 Hello인 경우 아래의 흐름이 발… 안 맞? Wait I can't continue.

I accidentally inserted truncated sentence. Let's fix.

Final: "웹 인터페이스에 메시지를 입력하고 보내기 버튼을 클릭하면, 예를 들어 Hello인 경우 아래의 흐름이 발생합니다."

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

아두이노에서 웹 페이지로:

Arduino가 웹 인터페이스로 데이터를 보내려 할 때, 예를 들어 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 - 애플리케이션 로직이 포함된 메인 Arduino 스케치
  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>

자바스크립트 처리 사용자 지정

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 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 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>"; }

다중 사용자 정의 웹 앱 관리 - 필수 충돌 예방 가이드

여러 개의 맞춤형 웹 애플리케이션을 개발할 때 서로 다른 애플리케이션 간 충돌을 피하는 것이 중요합니다. 우리의 아두이노 프로젝트에 "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>"; }

다중 앱 테스트

여러 앱을 테스트할 때:

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

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