Ví dụ WebApp tùy chỉnh cho ESP32 Hướng dẫn giao diện web đơn giản cho người mới bắt đầu

Tổng quan

Ví dụ này cung cấp một mẫu hoàn chỉnh để bạn tạo các ứng dụng web tùy chỉnh của riêng mình, có thể tích hợp liền mạch với Thư viện DIYables ESP32 WebApps.

ví dụ webapp tùy chỉnh Arduino - hướng dẫn tự xây dựng giao diện web của riêng bạn

Mẫu CustomWebApp hoàn hảo cho người mới bắt đầu muốn bổ sung giao diện web của riêng họ vào hệ sinh thái ESP32 WebApps của DIYables! Hướng dẫn này sẽ cho bạn biết cách xây dựng một trang web đơn giản với trao đổi dữ liệu hai chiều theo thời gian thực giữa trình duyệt web và ESP32 thông qua WebSocket mà có thể:

  • Gửi tin nhắn văn bản từ trình duyệt web tới ESP32 ngay lập tức qua WebSocket
  • Nhận tin nhắn từ ESP32 và hiển thị chúng theo thời gian thực trên trang web
  • Duy trì kết nối WebSocket ổn định cho phép giao tiếp liên tục
  • Tự động kết nối lại khi kết nối WebSocket bị mất
  • Hoạt động trên thiết bị di động với thiết kế đáp ứng

Được thiết kế cho ESP32 - mẫu này tích hợp hoàn hảo với các ứng dụng web DIYables hiện có và cung cấp nền tảng để xây dựng các giao diện IoT tùy chỉnh của riêng bạn!

Mẫu này cung cấp mã tối thiểu để bạn bắt đầu. Người dùng có thể phát triển các ứng dụng web tinh vi của riêng họ bằng cách chỉnh sửa mẫu này. Kiến thức lập trình web cơ bản (HTML, CSS, JavaScript) được khuyến nghị để tùy chỉnh giao diện web và thêm các tính năng nâng cao.

Những điều bạn sẽ học

  • Cách tạo một ứng dụng web tùy chỉnh tích hợp với Thư viện ESP32 WebApps của DIYables
  • Cách thêm trang tùy chỉnh của bạn vào hệ sinh thái ứng dụng web DIYables
  • Cách gửi tin nhắn văn bản từ trình duyệt web đến ESP32
  • Cách gửi dữ liệu từ ESP32 đến trình duyệt web
  • Cách xử lý kết nối WebSocket và tự động kết nối lại
  • Cách làm giao diện web tương thích với điện thoại di động
  • Cách sử dụng hệ thống mẫu DIYables ESP32 WebApps để phát triển nhanh

Tính năng

  • Tích hợp DIYables ESP32 WebApps: Tích hợp liền mạch với hệ sinh thái thư viện DIYables ESP32 WebApps
  • Mã mẫu tối thiểu: Cung cấp nền tảng cơ bản để bạn có thể mở rộng và tuỳ chỉnh
  • Phát triển dựa trên mẫu: Điểm khởi đầu hoàn chỉnh mà bạn có thể chỉnh sửa để tạo các ứng dụng tinh vi
  • Nhắn tin văn bản đơn giản: Gửi tin nhắn giữa trình duyệt web và Arduino
  • Kết nối lại tự động: Tự động kết nối lại khi mất kết nối
  • Phản hồi trên thiết bị di động: Phản hồi trên thiết bị di động
  • Thân thiện với người mới bắt đầu: Mã sạch, đơn giản và dễ hiểu
  • Khung có thể mở rộng: Yêu cầu kiến thức lập trình web căn bản (HTML/CSS/JavaScript) cho tuỳ chỉnh nâng cao

Phần cứng cần chuẩn bị

1×mô-đun phát triển ESP-WROOM-32
1×Alternatively, ESP32 Uno-form board
1×Alternatively, ESP32 S3 Uno-form board
1×USB Cable Type-A to Type-C (for USB-A PC)
1×USB Cable Type-C to Type-C (for USB-C PC)
1×(Khuyến nghị) Screw Terminal Expansion Board for ESP32
1×(Khuyến nghị) Breakout Expansion Board for ESP32
1×(Khuyến nghị) Power Splitter for ESP32

Or you can buy the following kits:

1×DIYables ESP32 Starter Kit (ESP32 included)
1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)

Cách bắt đầu

Bạn có thể bắt đầu xây dựng ứng dụng web tùy chỉnh cho bo mạch ESP32 bằng cách thực hiện các bước chính sau:

  • Chạy Mẫu Ứng dụng Tùy chỉnh Mặc định trên bo mạch ESP32 của bạn
  • Kiểm tra và xác nhận Ứng dụng Web Tùy chỉnh Mặc định hoạt động chính xác
  • Hiểu giao thức truyền thông và cách nó hoạt động ở chế độ nền
  • Chỉnh sửa Mẫu để thích nghi với Ứng dụng của bạn
  • Quản lý nhiều Ứng dụng Web Tùy chỉnh - Hướng dẫn thiết yếu ngăn ngừa xung đột

Chúng ta hãy bắt đầu từng cái một.

Chạy Mẫu Ứng dụng Tùy chỉnh Mặc định trên bo mạch ESP32 của bạn

Hướng dẫn từng bước

  • Nếu đây là lần đầu bạn sử dụng ESP32, hãy tham khảo bài hướng dẫn về ESP32 - Cài Đặt Phần Mềm
  • Kết nối bo mạch ESP32 với máy tính của bạn bằng cáp USB
  • Mở Arduino IDE trên máy tính của bạn
  • Chọn bo mạch ESP32 phù hợp (ví dụ ESP32 Dev Module) và cổng COM
  • Đi tới biểu tượng Libraries ở thanh bên trái của Arduino IDE
  • Tìm "DIYables ESP32 WebApps", sau đó tìm thư viện DIYables ESP32 WebApps của DIYables
  • Nhấp nút Cài đặt để cài đặt thư viện
thư viện ESP32 webapps của diyables
  • Bạn sẽ được yêu cầu cài đặt một số phụ thuộc thư viện khác
  • Nhấp vào nút Cài đặt Tất cả để cài đặt toàn bộ các phụ thuộc thư viện
phụ thuộc của diyables ESP32 webapps
  • Trong Arduino IDE, hãy vào File > Examples > DIYables ESP32 WebApps > CustomWebApp
  • Bạn sẽ thấy 4 tập tin tạo thành mẫu web app tùy chỉnh đầy đủ:
  • CustomWebApp.ino - Mã ESP32 chính (đây là nơi bạn thêm logic tùy chỉnh của mình!)
  • CustomWebApp.h - Tệp tiêu đề (định nghĩa giao diện cho Thư viện DIYables ESP32 WebApps)
  • CustomWebApp.cpp - Tệp triển khai (xử lý tích hợp với khung thư viện)
  • custom_page_html.h - Thiết kế trang web (tùy chỉnh giao diện web của bạn ở đây!)
  • Cấu hình WiFi bằng cách thay đổi các dòng này trong CustomWebApp.ino:
const char WIFI_SSID[] = "YOUR_WIFI_NAME"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";

Bước 5: Tải lên và kiểm tra

  • Nhấp vào nút Tải lên trên Arduino IDE để tải mã lên ESP32.
  • Mở Serial Monitor để xem trạng thái kết nối.
  • Ghi lại địa chỉ IP hiển thị trên Serial Monitor.
  • Mở Serial Monitor.
  • Xem kết quả trên Serial Monitor. Nó trông như hình dưới đây.
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  
  • Nếu bạn không thấy gì, hãy khởi động lại bảng ESP32.
  • Ghi chú địa chỉ IP được hiển thị và nhập địa chỉ này vào thanh địa chỉ của trình duyệt trên điện thoại thông minh hoặc máy tính của bạn.
  • Ví dụ: http://192.168.0.2
  • Bạn sẽ thấy trang chủ như hình dưới đây:
trang chủ webapp ESP32 diyables với ứng dụng web tùy chỉnh
  • Nhấp vào liên kết Web Custom, bạn sẽ thấy giao diện người dùng của ứng dụng Web Custom như hình dưới đây:
ESP32 diyables Ứng dụng web và ứng dụng web tùy chỉnh
  • Hoặc bạn cũng có thể truy cập trang trực tiếp bằng địa chỉ IP theo sau là /custom.
  • Ví dụ: http://[IP_ADDRESS]/custom

Kiểm tra và xác nhận rằng ứng dụng web tùy chỉnh mặc định hoạt động đúng

Khi bạn chạy mẫu CustomWebApp mặc định, đây là những gì bạn sẽ thấy:

Trên Giao diện Web:

  • Trạng thái kết nối: Hiển thị 'Đã kết nối' màu xanh khi WebSocket đang hoạt động
  • Ô nhập tin nhắn: Trường văn bản để gõ tin nhắn gửi tới Arduino
  • Nút Gửi: Nhấp để gửi tin nhắn của bạn (hoặc nhấn Enter)
  • Hiển thị tin nhắn Arduino: Hiển thị các tin nhắn nhận được từ ESP32 bằng chữ màu xanh

Hành vi của ESP32:

  • Phản hồi Echo: Khi bạn gửi "Hello" từ web, ESP32 trả về "Echo: Hello"
  • Cập nhật định kỳ: ESP32 gửi các thông báo thời gian hoạt động mỗi 5 giây: "Arduino uptime: X seconds"
  • Trình theo dõi Serial: Tất cả các tin nhắn nhận được đều được ghi lại để gỡ lỗi

Kiểm tra giao tiếp:

  1. Nhập tin nhắn vào ô nhập liệu (ví dụ: "test message")
  2. Nhấn Gửi hoặc nhấn Enter
  3. Kiểm tra Serial Monitor - bạn sẽ thấy: "Đã nhận từ web: tin nhắn thử"
  4. Kiểm tra trang web - bạn sẽ thấy: "Phản hồi: tin nhắn thử"
  5. Chờ vài giây - bạn sẽ thấy các tin nhắn thời gian hoạt động định kỳ được cập nhật mỗi 3 giây (ví dụ: "Thời gian hoạt động của Arduino: 15 giây", "Thời gian hoạt động của Arduino: 18 giây", v.v.)

Hiểu Giao thức Truyền thông và Cách nó hoạt động ở chế độ nền

Hiểu rõ các cơ chế nội bộ giúp bạn tùy chỉnh mẫu một cách hiệu quả.

Hệ thống Định danh Ứng dụng

Mẫu CustomWebApp sử dụng các thẻ tin nhắn duy nhất (gọi là "App Identifiers") giúp mã ESP32 và các khách hàng web lọc các tin nhắn thuộc về chúng. Điều này là cần thiết vì ứng dụng của bạn có thể bao gồm nhiều ứng dụng web khác nhau, và mỗi ứng dụng cần xử lý chỉ các tin nhắn của riêng nó trong khi bỏ qua các tin nhắn của các ứng dụng khác:

Phía 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);

Phía JavaScript (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);

Các lợi ích của thiết kế này:

  • Nguồn dữ liệu duy nhất: Thay đổi định danh ở một nơi cho mỗi ngôn ngữ
  • Không có chuỗi ma thuật: Loại bỏ chuỗi được nhúng cứng "CUSTOM:" trên toàn bộ mã nguồn
  • An toàn kiểu dữ liệu: Sử dụng hằng số để ngăn sai chính tả
  • Dễ mở rộng: Dễ tạo nhiều ứng dụng tùy chỉnh với các định danh khác nhau
  • Tránh xung đột dữ liệu giữa nhiều ứng dụng: Mỗi ứng dụng sử dụng định danh duy nhất để ngăn chặn sự can thiệp vào tin nhắn
  • Chuyên nghiệp: Tuân thủ các nguyên tắc thiết kế hướng đối tượng

Lưu ý quan trọng:

  • Bạn có thể giữ nguyên định danh hiện tại "CUSTOM:" khi chỉnh sửa mẫu ứng dụng web tùy chỉnh này để phù hợp với dự án của bạn. Tuy nhiên, khi bạn tạo nhiều hơn một ứng dụng tùy chỉnh, hãy đảm bảo thay đổi nó để tránh xung đột.
  • Nếu thay đổi định danh, hãy đảm bảo rằng giá trị trong JavaScript (.h file) và mã ESP32 (.cpp file) là giống nhau (ví dụ, cả hai đều dùng "TEMP:" hoặc cả hai đều dùng "SENSOR:").
  • Các định danh được dự trữ trước bởi các ứng dụng tích hợp sẵn: Các định danh sau đây đã được sử dụng bởi các ứng dụng tích hợp sẵn của DIYables ESP32 WebApps và nên tránh:
  • Các định danh chính của ứng dụng: "CHAT:", "MONITOR:", "PLOTTER:", "DIGITAL_PINS:", "JOYSTICK:", "SLIDER:", "TABLE:", "RTC:", "ROTATOR:", "GAUGE:"
  • Các định danh phụ của giao thức: "TIME:", "DATETIME:", "JOYSTICK_CONFIG:", "PLOTTER_DATA:", "PLOTTER_CONFIG:", "SLIDER_VALUES:", "TABLE_CONFIG:", "TABLE_DATA:", "VALUE_UPDATE:", "PIN_CONFIG:", "PIN_STATES:", "PIN_UPDATE:"

Quy trình giao tiếp

Từ trang web đến ESP32:

Khi bạn nhập một tin nhắn vào giao diện web và nhấn nút gửi, ví dụ: Hello, quy trình dưới đây sẽ diễn ra:

  1. JavaScript thêm định danh: JavaScript tự động thêm định danh của ứng dụng (là "CUSTOM:" trong mẫu này) bằng hằng số APP_IDENTIFIER, sau đó gửi tin nhắn tới ESP32 thông qua WebSocket. Tin nhắn thực tế được gửi là: CUSTOM:Hello
  2. Thư viện ESP32 WebApps DIYables nhận: Thư viện nhận được tin nhắn CUSTOM:Hello và chuyển nó tới phương thức CustomWebAppPage::handleWebSocketMessage của bạn
  3. Lớp CustomWebAppPage loại bỏ định danh: Trong handleWebSocketMessage, lớp CustomWebAppPage kiểm tra xem tin nhắn có bắt đầu bằng APP_IDENTIFIER của nó hay không, loại bỏ định danh bằng cách sử dụng .substring(APP_IDENTIFIER.length()), sau đó truyền phần tin nhắn còn lại Hello bằng cách gọi hàm callback được triển khai trong file .ino của bạn
  4. Ứng dụng của bạn xử lý: Ứng dụng của bạn trong file .ino nhận chỉ Hello và có thể xử lý tin nhắn tùy theo logic tùy chỉnh của bạn. Mẫu hiện tại chỉ in ra và gửi lại một phản hồi

Từ ESP32 đến trang web:

Khi ESP32 của bạn muốn gửi dữ liệu đến giao diện web, ví dụ: Nhiệt độ: 25°C, quá trình dưới đây diễn ra:

  1. Ứng dụng của bạn gọi sendToWeb(): Trong tệp .ino của bạn, bạn gọi customPage.sendToWeb("Temperature: 25°C") để gửi dữ liệu đến trình duyệt web
  2. Lớp CustomWebAppPage thêm định danh và phát sóng: Lớp CustomWebAppPage tự động thêm định danh của ứng dụng bằng hằng số APP_IDENTIFIER vào tin nhắn và phát CUSTOM:Temperature: 25°C tới mọi khách hàng web được kết nối thông qua WebSocket
  3. JavaScript nhận và lọc tin nhắn: Trình duyệt web nhận CUSTOM:Temperature: 25°C thông qua bộ xử lý sự kiện ws.onmessage, nhưng JavaScript chỉ xử lý các tin nhắn bắt đầu bằng APP_IDENTIFIER và loại bỏ định danh bằng cách dùng .substring(APP_IDENTIFIER.length())
  4. Trang web hiển thị tin nhắn sạch: Mẫu hiện tại hiển thị tin nhắn sạch Temperature: 25°C (không có định danh) ở phần "Message from Arduino". Bạn có thể tùy chỉnh JavaScript để phân tích và hiển thị dữ liệu theo các cách khác nhau tùy thuộc vào nhu cầu của ứng dụng.

Tổng quan kiến trúc

Ví dụ CustomWebApp gồm bốn tệp chính:

  1. CustomWebApp.ino - Bản phác thảo ESP32 chính với logic ứng dụng của bạn
  2. CustomWebApp.h - Tập tin tiêu đề định nghĩa lớp trang tùy chỉnh (giao diện thư viện)
  3. CustomWebApp.cpp - Triển khai với logic giao tiếp (mã thư viện)
  4. custom_page_html.h - Giao diện HTML được tách riêng để dễ tùy biến

Chỉnh sửa mẫu để phù hợp với ứng dụng của bạn

Mẫu được thiết kế để dễ dàng tùy biến phù hợp với nhu cầu riêng của bạn. Đây là cách để bạn điều chỉnh nó:

1. Tích hợp phần cứng

Thêm khởi tạo phần cứng

Trong hàm setup() của CustomWebApp.ino:

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);

Xử lý các lệnh tuỳ chỉnh

Mở rộng hàm gọi lại để xử lý các lệnh tùy chỉnh của bạn:

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

Gửi dữ liệu cảm biến thời gian thực

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. Tùy chỉnh Giao diện Web

Chỉnh sửa bố cục HTML

Chỉnh sửa HTML trong custom_page_html.h để thay đổi giao diện:

<!-- 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>

Tùy chỉnh xử lý JavaScript

Cập nhật hàm ws.onmessage để xử lý các loại dữ liệu cụ thể:

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

Thêm Định Dạng

Tùy chỉnh CSS cho ứng dụng của bạn:

<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>

Các tùy chỉnh khác

Ngoài việc chỉnh sửa giao diện web và tích hợp phần cứng, bạn cũng có thể tùy chỉnh cách ứng dụng của bạn hiển thị trong hệ sinh thái DIYables ESP32 WebApps:

1. Tùy chỉnh Đường dẫn Ứng dụng

Bạn có thể thay đổi đường dẫn URL mà ứng dụng web tùy chỉnh của bạn có thể truy cập được bằng cách sửa đổi hàm khởi tạo trong tệp header của bạn:

Đường dẫn mặc định:

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

Các ví dụ về đường dẫn tùy chỉnh:

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

Ghi chú quan trọng:

  • Đường dẫn phải bắt đầu bằng '/': Luôn bắt đầu đường dẫn của bạn bằng dấu gạch chéo '/'.
  • Sử dụng những tên mô tả: Chọn các đường dẫn mô tả rõ chức năng của ứng dụng.
  • Tránh xung đột: Đừng sử dụng các đường dẫn đã có sẵn bởi các ứng dụng tích hợp như /chat, /monitor, /plotter, v.v.
  • Sử dụng chữ thường và dấu gạch ngang: Tuân thủ các quy ước URL trên web để tương thích tốt hơn.

2. Tùy chỉnh thẻ ứng dụng trên trang chủ

Bạn có thể tùy chỉnh cách ứng dụng của bạn hiển thị trên trang chủ DIYables ESP32 WebApps bằng cách sửa đổi phương thức getNavigationInfo() trong tệp triển khai của bạn:

Thẻ Ứng dụng Cơ bản:

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

Thẻ Ứng dụng Nâng cao với CSS nội tuyến:

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

Quản lý nhiều ứng dụng web tùy chỉnh - Hướng dẫn ngăn ngừa xung đột thiết yếu

Khi phát triển nhiều ứng dụng web tùy chỉnh, điều quan trọng là tránh xung đột giữa các ứng dụng khác nhau. Giả sử chúng ta muốn thêm ba ứng dụng tùy chỉnh có tên "Temperature Monitor", "Motor Controller", và "Sensor Dashboard" vào dự án ESP32 của chúng ta. Đây là cách để đảm bảo chúng hoạt động hài hòa với nhau:

1. Sử dụng các định danh ứng dụng duy nhất

Mỗi ứng dụng web tùy chỉnh phải có một định danh duy nhất để ngăn chặn xung đột tin nhắn:

Ví dụ: Ứng dụng Giám sát Nhiệt độ

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

Ví dụ: Ứng dụng Điều khiển Động cơ

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

Ví dụ: Ứng dụng bảng điều khiển cảm biến

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

2. Sử dụng các đường dẫn trang duy nhất

Mỗi ứng dụng web cần một đường dẫn URL duy nhất:

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

3. Sử dụng Tên Lớp Duy Nhất

Tránh xung đột tên bằng cách sử dụng các tên lớp mang tính mô tả:

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

4. Tổ chức nhiều ứng dụng trong một dự án

Đây là cách cấu trúc một dự án với nhiều ứng dụng tùy chỉnh:

// 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. Các thực hành tốt nhất cho nhiều ứng dụng

Cấu trúc tệp
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

Điều hướng giữa các ứng dụng

Cập nhật phương thức getNavigationInfo() trong mỗi ứng dụng để cung cấp điều hướng dễ dàng:

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. Kiểm thử nhiều ứng dụng

Khi thử nghiệm nhiều ứng dụng:

  1. Kiểm tra từng ứng dụng riêng lẻ trước
  2. Kiểm tra Serial Monitor để phát hiện xung đột tin nhắn
  3. Xác nhận các định danh duy nhất hoạt động đúng
  4. Kiểm tra điều hướng giữa các ứng dụng khác nhau
  5. Giám sát mức sử dụng bộ nhớ khi có nhiều ứng dụng được tải

Bằng cách làm theo những hướng dẫn này, bạn có thể tạo ra nhiều ứng dụng web tùy chỉnh khác nhau hoạt động cùng nhau một cách liền mạch mà không can thiệp vào nhau hoặc vào các ESP32 WebApps DIYables khác.