ESP32 WebTable Example Hướng Dẫn Giao Diện Bảng Dữ Liệu

Tổng Quan

Ví dụ WebTable cung cấp giao diện bảng dữ liệu hai cột dựa trên web để hiển thị thông tin thời gian thực từ các dự án ESP32 của bạn. Được thiết kế cho ESP32 với nền tảng giáo dục có khả năng trực quan hóa dữ liệu tiên tiến, làm nổi bật thay đổi giá trị thông minh, và tích hợp liền mạch với hệ sinh thái giáo dục.

Arduino webtable example - real-time data màn hình tutorial

Tính Năng Chính

Chức Năng Cốt Lõi

  • Bảng Dữ Liệu Hai Cột: Cặp thuộc tính-giá trị sạch sẽ cho việc hiển thị dữ liệu có tổ chức
  • Cập Nhật Giá Trị Thời Gian Thực: Làm mới dữ liệu tức thì dựa trên WebSocket mà không cần tải lại trang
  • Thiết Kế Tiết Kiệm Bộ Nhớ: Không lưu trữ giá trị trong bộ nhớ ESP32 - tất cả được theo dõi trong giao diện web
  • Cấu Hình Động: Thiết lập cấu trúc bảng một lần trong hàm setup() của ESP32
  • Điều Khiển Tương Tác: Nút làm mới để yêu cầu dữ liệu thủ công và khả năng kết nối lại tự động

Hệ Thống Làm Nổi Bật Thông Minh

  • Phát Hiện Thay Đổi Thông Minh: Tự động phát hiện giá trị nào thực sự thay đổi theo thời gian
  • Theo Dõi Giá Trị Tự Động: Tự động so sánh giá trị hiện tại với giá trị trước đó
  • Làm Nổi Bật Hai Cấp:
    • Làm nổi bật màu đỏ: Cho các giá trị đang thay đổi tích cực
    • Làm nổi bật màu xanh: Cho các giá trị ổn định theo thời gian
  • Không Cần Thiết Lập: Hệ thống tự động học những giá trị nào thay đổi mà không cần cấu hình gì
  • Phản Hồi Trực Quan: Hiệu ứng mượt mà cung cấp phản hồi trực quan rõ ràng cho việc cập nhật giá trị

Giao Diện Web Hiện Đại

  • Thiết Kế Responsive: Hoạt động liền mạch trên desktop, tablet và thiết bị di động
  • Kiểu Dáng Chuyên Nghiệp: Bố cục dạng thẻ với hiệu ứng hover và thẩm mỹ hiện đại
  • Trạng Thái Kết Nối: Chỉ báo trực quan cho trạng thái kết nối WebSocket
  • Tích Hợp Footer: Kiểu dáng nhất quán phù hợp với các web app DIYables khác
  • Xử Lý Trạng Thái Rỗng: Thông báo thân thiện với người dùng khi không có dữ liệu

Phần Cứng Cần Thiết

1×mô-đun phát triển ESP-WROOM-32
1×Alternatively, ESP32 Uno-form board
1×Alternatively, ESP32 S3 Uno-form board
1×Cáp USB Type-C
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)

Hướng Dẫn Thiết Lập

Các Bước Nhanh

Làm theo các hướng dẫn này từng bước:

  • Nếu đây là lần đầu tiên bạn sử dụng ESP32, hãy tham khảo hướng dẫn ESP32 - Cài Đặt Phần Mềm.
  • Kết nối board ESP32 với máy tính của bạn bằng cáp USB.
  • Khởi động Arduino IDE trên máy tính của bạn.
  • Chọn board ESP32 phù hợp (ví dụ: ESP32 Dev Module) và COM port.
  • Điều hướng đến biểu tượng Libraries trên thanh bên trái của Arduino IDE.
  • Tìm kiếm "DIYables ESP32 WebApps", sau đó tìm DIYables ESP32 WebApps Library by DIYables
  • Nhấp nút Install để cài đặt thư viện.
diyables ESP32 webapps thư viện
  • Bạn sẽ được hỏi về việc cài đặt một số thư viện phụ thuộc khác
  • Nhấp nút Install All để cài đặt tất cả thư viện phụ thuộc.
diyables ESP32 webapps dependency
  • Trên Arduino IDE, Vào File Examples DIYables ESP32 WebApps WebTable example, hoặc copy code và paste vào editor của Arduino IDE
/* * DIYables ESP32 WebApps Library - WebTable Example * * This example demonstrates how to create a web-based table interface * that displays real-time data in a two-column format (attribute-value pairs). * * Features: * - Two-column table with attributes and real-time values * - WebSocket-based real-time updates * - Configurable table rows in setup() * - Dynamic value updates during runtime * - Modern responsive web interface * * Hardware: ESP32 Boards * * Instructions: * 1. Update WiFi credentials below * 2. Upload the code to your Arduino * 3. Open Serial Monitor to get the IP address * 4. Open web browser and go to: * - Home page: http://[ARDUINO_IP]/ * - WebTable: http://[ARDUINO_IP]/web-table * 5. Watch real-time data updates in the table * * Created by DIYables * Visit: https://diyables.com for more tutorials and projects */ #include <DIYables_ESP32_Platform.h> #include <DIYablesWebApps.h> // WiFi credentials - Update these with your network details const char WIFI_SSID[] = "YOUR_WIFI_SSID"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // Initialize web server and pages ESP32ServerFactory serverFactory; DIYablesWebAppServer server(serverFactory, 80, 81); DIYablesHomePage homePage; DIYablesWebTablePage tablePage; // Variables to simulate sensor data float temperature = 20.5; float humidity = 65.0; int lightLevel = 512; unsigned long uptime = 0; bool ledState = false; int counter = 0; void setup() { Serial.begin(9600); Serial.println("DIYables ESP32 WebApp - Web Table Example"); // Initialize built-in LED pinMode(LED_BUILTIN, OUTPUT); // Add web apps server.addApp(&homePage); server.addApp(&tablePage); // Optional: Add 404 page for better user experience server.setNotFoundPage(DIYablesNotFoundPage()); // Start the WebApp server server.begin(WIFI_SSID, WIFI_PASSWORD); // Set up callback for data requests tablePage.onTableValueRequest(onDataRequested); // Configure table structure in setup - attributes are set once setupTableStructure(); Serial.println("WebTable Server started!"); } void loop() { server.loop(); // Update sensor values every 2 seconds static unsigned long lastUpdate = 0; if (millis() - lastUpdate > 2000) { updateSensorValues(); sendRealTimeUpdates(); lastUpdate = millis(); } // Toggle LED every 5 seconds static unsigned long lastLedToggle = 0; if (millis() - lastLedToggle > 5000) { ledState = !ledState; digitalWrite(LED_BUILTIN, ledState); // Send LED status update to web interface tablePage.sendValueUpdate("LED Status", ledState ? "ON" : "OFF"); lastLedToggle = millis(); } delay(10); } // Setup table structure - called once in setup() void setupTableStructure() { Serial.println("Setting up table structure..."); // Add table rows with attributes only (no values stored) tablePage.addRow("Device Name"); tablePage.addRow("Temperature"); tablePage.addRow("Humidity"); tablePage.addRow("Light Level"); tablePage.addRow("Uptime"); tablePage.addRow("LED Status"); tablePage.addRow("Counter"); tablePage.addRow("WiFi SSID"); tablePage.addRow("IP Address"); tablePage.addRow("Free Memory"); Serial.println("Table structure configured with " + String(tablePage.getRowCount()) + " rows"); } // Simulate sensor readings and send values to web interface void updateSensorValues() { // Simulate temperature sensor (20-30°C range) temperature = 20.0 + (sin(millis() / 10000.0) * 5.0) + random(-10, 10) / 10.0; // Simulate humidity sensor (40-80% range) humidity = 60.0 + (cos(millis() / 8000.0) * 15.0) + random(-20, 20) / 10.0; // Simulate light sensor (0-1023 range) lightLevel = 512 + (sin(millis() / 5000.0) * 400) + random(-50, 50); if (lightLevel < 0) lightLevel = 0; if (lightLevel > 1023) lightLevel = 1023; // Update uptime uptime = millis() / 1000; // Increment counter counter++; } // Send real-time updates to web interface void sendRealTimeUpdates() { // Send individual value updates to web clients tablePage.sendValueUpdate("Temperature", String(temperature, 1) + "°C"); tablePage.sendValueUpdate("Humidity", String(humidity, 1) + "%"); tablePage.sendValueUpdate("Light Level", String(lightLevel)); tablePage.sendValueUpdate("Uptime", formatUptime(uptime)); tablePage.sendValueUpdate("Counter", String(counter)); tablePage.sendValueUpdate("Free Memory", String(getFreeMemory()) + " bytes"); } // Callback function called when web client requests table data void onDataRequested() { Serial.println("Web client requested table data"); // Send all current values to web interface tablePage.sendValueUpdate("Device Name", "ESP32"); tablePage.sendValueUpdate("Temperature", String(temperature, 1) + "°C"); tablePage.sendValueUpdate("Humidity", String(humidity, 1) + "%"); tablePage.sendValueUpdate("Light Level", String(lightLevel)); tablePage.sendValueUpdate("Uptime", formatUptime(uptime)); tablePage.sendValueUpdate("LED Status", ledState ? "ON" : "OFF"); tablePage.sendValueUpdate("Counter", String(counter)); tablePage.sendValueUpdate("WiFi SSID", WIFI_SSID); tablePage.sendValueUpdate("IP Address", WiFi.localIP().toString()); tablePage.sendValueUpdate("Free Memory", String(getFreeMemory()) + " bytes"); } // Format uptime in human-readable format String formatUptime(unsigned long seconds) { unsigned long days = seconds / 86400; unsigned long hours = (seconds % 86400) / 3600; unsigned long minutes = (seconds % 3600) / 60; unsigned long secs = seconds % 60; String result = ""; if (days > 0) result += String(days) + "d "; if (hours > 0) result += String(hours) + "h "; if (minutes > 0) result += String(minutes) + "m "; result += String(secs) + "s"; return result; } // Get approximate free memory int getFreeMemory() { // Simple approximation for demonstration // In a real application, you might use a more accurate method return 2048 - (counter % 1024); }

Cấu Hình WiFi

Cấu hình thông tin đăng nhập WiFi trong code bằng cách cập nhật những dòng này:

const char WIFI_SSID[] = "YOUR_WIFI_NETWORK"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";
  • Nhấp nút Upload trên Arduino IDE để upload code lên ESP32
  • Mở Serial Monitor
  • Kiểm tra kết quả trên Serial Monitor. Nó trông giống như bên dưới
COM6
Send
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/ 📊 Web Table: http://192.168.0.2/web-table ==========================================
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  
  • Nếu bạn không thấy gì, hãy khởi động lại board ESP32.

Sử Dụng Giao Diện Web

  • Mở trình duyệt web trên máy tính hoặc thiết bị di động kết nối với cùng mạng WiFi
  • Nhập địa chỉ IP hiển thị trong Serial Monitor vào trình duyệt web
  • Ví dụ: http://192.168.1.100
  • Bạn sẽ thấy trang chủ như hình bên dưới:
ESP32 diyables webapp home page with web table app
  • Nhấp vào link Web Table, bạn sẽ thấy giao diện của Web Table app như bên dưới:
ESP32 diyables webapp web table app
  • Hoặc bạn cũng có thể truy cập trang trực tiếp bằng địa chỉ IP theo sau bởi /web-table. Ví dụ: http://192.168.1.100/web-table
  • Bạn sẽ thấy giao diện Web Table hiển thị:
    • Bảng Dữ Liệu Thời Gian Thực: Bảng hai cột với các thuộc tính và giá trị hiện tại của chúng
    • Làm Nổi Bật Thông Minh: Tự động mã hóa màu sắc các giá trị thay đổi so với ổn định
    • Trạng Thái Kết Nối: Chỉ báo trực quan hiển thị trạng thái kết nối WebSocket
    • Nút Làm Mới: Khả năng làm mới thủ công cho dữ liệu mới nhất
    • Cập Nhật Tự Động: Giá trị cập nhật thời gian thực qua WebSocket

Hệ Thống Làm Nổi Bật Thông Minh

Cách Hoạt Động

WebTable có một hệ thống làm nổi bật tiên tiến tự động phát hiện giá trị nào thay đổi theo thời gian mà không cần cấu hình gì trong code ESP32 của bạn.

Phát Hiện Thay Đổi Tự Động

Giao diện web tự động theo dõi dữ liệu của bạn và cung cấp phản hồi trực quan:

  • Làm nổi bật màu đỏ: Áp dụng cho các giá trị thay đổi thường xuyên (như số liệu cảm biến, bộ đếm, timer)
  • Làm nổi bật màu xanh: Áp dụng cho các giá trị ổn định (như tên thiết bị, địa chỉ IP, cài đặt cấu hình)
  • Không cần thiết lập: Hệ thống học tự động khi ESP32 của bạn gửi cập nhật

Những Gì Bạn Thấy

  • Các giá trị thay đổi theo thời gian (nhiệt độ, uptime, số liệu cảm biến) sẽ được làm nổi bật bằng màu đỏ
  • Thông tin tĩnh (tên thiết bị, WiFi SSID, địa chỉ IP) sẽ được làm nổi bật bằng màu xanh
  • Điều này giúp bạn nhanh chóng xác định dữ liệu nào đang thay đổi so với thông tin ổn định

Lợi Ích Chính

  • Không Cần Cấu Hình: Chỉ cần sử dụng sendValueUpdate() và làm nổi bật hoạt động tự động
  • Học Trực Quan: Dễ dàng xem phần nào của hệ thống đang hoạt động
  • Thân Thiện Với Người Mới Bắt Đầu: Hoạt động mà không cần kiến thức lập trình web
  • Tiết Kiệm Bộ Nhớ: Tất cả làm nổi bật xảy ra trong trình duyệt web, không phải trên Arduino
  • Cập Nhật Thời Gian Thực: Làm nổi bật thay đổi ngay lập tức khi giá trị cập nhật

Cấu Hình Cấu Trúc Bảng

Cấu trúc bảng được cấu hình một lần trong hàm setup() sử dụng phương thức addRow():

void setupTableStructure() { // Thêm các hàng bảng với thuộc tính và giá trị ban đầu tablePage.addRow("Device Name", "ESP32"); tablePage.addRow("Temperature", "0.0°C"); tablePage.addRow("LED Status", "OFF"); tablePage.addRow("Uptime", "0 seconds"); tablePage.addRow("WiFi Signal", "0 dBm"); tablePage.addRow("Free Memory", "0 bytes"); }

Cập Nhật Giá Trị Thời Gian Thực

Giá trị được cập nhật trong thời gian chạy sử dụng phương thức sendValueUpdate():

Phương Thức Cập Nhật Trực Tiếp (Khuyến Nghị)

void updateSensorValues() { // Đọc dữ liệu cảm biến float temperature = readTemperature(); bool ledStatus = digitalRead(LED_BUILTIN); // Gửi cập nhật trực tiếp đến giao diện web tablePage.sendValueUpdate("Temperature", String(temperature, 1) + "°C"); tablePage.sendValueUpdate("LED Status", ledStatus ? "ON" : "OFF"); tablePage.sendValueUpdate("Uptime", formatUptime(millis() / 1000)); }

Lợi Ích Của Cập Nhật Trực Tiếp

  • Tiết Kiệm Bộ Nhớ: Không lưu trữ giá trị trong bộ nhớ ESP32
  • Thời Gian Thực: Cập nhật tức thì đến giao diện web
  • Làm Nổi Bật Tự Động: Giao diện web tự động phát hiện thay đổi
  • Code Đơn Giản: Không cần quản lý lưu trữ giá trị cục bộ

Giải Thích Code

Các Thành Phần Chính

#include <DIYablesWebApps.h> // Khởi tạo web server và table page DIYablesWebAppServer server; DIYablesWebTablePage tablePage;

Hàm Setup

void setup() { Serial.begin(9600); // Thiết lập kết nối WiFi server.setupWiFi(WIFI_SSID, WIFI_PASSWORD); // Thêm table page vào server server.addWebApp(tablePage); // Thiết lập callback cho yêu cầu dữ liệu tablePage.onTableValueRequest(onDataRequested); // Cấu hình cấu trúc bảng setupTableStructure(); // Khởi động server server.begin(); }

Cập Nhật Thời Gian Thực Trong Loop

void loop() { server.handleClient(); // Cập nhật giá trị cảm biến mỗi 2 giây static unsigned long lastUpdate = 0; if (millis() - lastUpdate > 2000) { updateSensorValues(); sendRealTimeUpdates(); lastUpdate = millis(); } delay(10); }

Hàm Callback

// Được gọi khi giao diện web yêu cầu dữ liệu bảng void onDataRequested() { Serial.println("Web client requested table data"); // Cập nhật tất cả giá trị hiện tại trước khi gửi updateSensorValues(); // Dữ liệu bảng được gửi tự động bởi thư viện }

Hàm Cập Nhật Giá Trị

void updateSensorValues() { // Cập nhật số liệu cảm biến temperature = readTemperatureSensor(); humidity = readHumiditySensor(); // Cập nhật giá trị trong bảng tablePage.updateValue("Temperature", String(temperature, 1) + "°C"); tablePage.updateValue("Humidity", String(humidity, 1) + "%"); } void sendRealTimeUpdates() { // Gửi cập nhật đến web client tablePage.sendValueUpdate("Temperature", String(temperature, 1) + "°C"); tablePage.sendValueUpdate("Humidity", String(humidity, 1) + "%"); }

Phương Thức API

Phương Thức Class DIYablesWebTablePage

addRow(attribute, initialValue)

  • Thêm hàng mới vào cấu trúc bảng
  • Tham số:
    • attribute: String - Tên thuộc tính (cột trái)
    • initialValue: String - Giá trị ban đầu (cột phải, tùy chọn)
  • Sử dụng: Được gọi trong setup() để cấu hình cấu trúc bảng

updateValue(attribute, value)

  • Cập nhật giá trị theo tên thuộc tính (chỉ lưu trữ cục bộ)
  • Tham số:
    • attribute: String - Tên thuộc tính cần cập nhật
    • value: String - Giá trị mới cần đặt
  • Sử dụng: Cập nhật dữ liệu bảng cục bộ

updateValue(index, value)

  • Cập nhật giá trị theo chỉ số hàng (chỉ lưu trữ cục bộ)
  • Tham số:
    • index: int - Chỉ số hàng (bắt đầu từ 0)
    • value: String - Giá trị mới cần đặt
  • Sử dụng: Cập nhật dữ liệu bảng cục bộ theo vị trí

sendValueUpdate(attribute, value)

  • Gửi cập nhật giá trị đến web client theo tên thuộc tính
  • Tham số:
    • attribute: String - Tên thuộc tính cần cập nhật
    • value: String - Giá trị mới cần gửi
  • Sử dụng: Cập nhật thời gian thực đến giao diện web

sendValueUpdate(index, value)

  • Gửi cập nhật giá trị đến web client theo chỉ số hàng
  • Tham số:
    • index: int - Chỉ số hàng (bắt đầu từ 0)
    • value: String - Giá trị mới cần gửi
  • Sử dụng: Cập nhật thời gian thực đến giao diện web theo vị trí

sendTableData()

  • Gửi dữ liệu bảng hoàn chỉnh đến web client
  • Sử dụng: Làm mới toàn bộ bảng trên giao diện web

clearTable()

  • Xóa tất cả dữ liệu bảng và reset số hàng
  • Sử dụng: Reset cấu trúc bảng (hiếm khi cần)

getRowCount()

  • Trả về số hàng trong bảng
  • Trả về: int - Số hàng hiện tại
  • Sử dụng: Lấy thông tin kích thước bảng

getAttribute(index)

  • Lấy tên thuộc tính theo chỉ số hàng
  • Tham số: index: int - Chỉ số hàng (bắt đầu từ 0)
  • Trả về: String - Tên thuộc tính
  • Sử dụng: Truy cập thông tin cấu trúc bảng

getValue(index)

  • Lấy giá trị theo chỉ số hàng
  • Tham số: index: int - Chỉ số hàng (bắt đầu từ 0)
  • Trả về: String - Giá trị hiện tại
  • Sử dụng: Truy cập giá trị bảng hiện tại

onTableValueRequest(callback)

  • Thiết lập hàm callback cho yêu cầu dữ liệu từ web client
  • Tham số: void (*callback)() - Hàm cần gọi khi dữ liệu được yêu cầu
  • Sử dụng: Xử lý yêu cầu dữ liệu từ web client

Giao Tiếp WebSocket

Tin Nhắn Từ Web Đến Arduino

  • TABLE:GET_DATA - Yêu cầu dữ liệu bảng hoàn chỉnh
  • TABLE:UPDATE:attribute:value - Cập nhật giá trị cho thuộc tính cụ thể

Tin Nhắn Từ ESP32 Đến Web

  • TABLE_DATA:attr1:val1|attr2:val2|... - Gửi dữ liệu bảng hoàn chỉnh
  • VALUE_UPDATE:attribute:value - Gửi cập nhật giá trị đơn

Khắc Phục Sự Cố

Các Vấn Đề Thường Gặp

1. Bảng Không Hiển Thị Dữ Liệu

  • Vấn đề: Bảng trống hoặc thông báo "No Data Available"
  • Nguyên nhân: Cấu trúc bảng chưa được cấu hình hoặc vấn đề kết nối WiFi
  • Giải pháp:
    • Xác minh setupTableStructure() được gọi trong setup()
    • Kiểm tra trạng thái kết nối WiFi
    • Nhấp nút refresh để yêu cầu dữ liệu thủ công
    • Kiểm tra Serial Monitor để biết thông báo lỗi

    2. Giá Trị Không Cập Nhật Thời Gian Thực

    • Vấn đề: Bảng hiển thị giá trị cũ mặc dù ESP32 đã cập nhật
    • Nguyên nhân: Kết nối WebSocket bị mất hoặc hàm cập nhật không được gọi
    • Giải pháp:
      • Kiểm tra chỉ báo trạng thái kết nối trên trang web
      • Làm mới trang web
      • Xác minh sendValueUpdate() được gọi đúng cách
      • Kiểm tra tính ổn định của mạng

      3. Làm Nổi Bật Không Hoạt Động

      • Vấn đề: Giá trị không hiển thị màu đỏ hoặc xanh làm nổi bật
      • Nguyên nhân: JavaScript không phát hiện thay đổi giá trị đúng cách
      • Giải pháp:
        • Làm mới trang web để reset phát hiện thay đổi
        • Đảm bảo giá trị thực sự thay đổi (kiểm tra Serial Monitor)
        • Xóa cache trình duyệt nếu làm nổi bật có vẻ bị kẹt
        • Giá trị cần nhiều cập nhật để kích hoạt hệ thống làm nổi bật

        4. Lỗi "Not connected to Arduino"

        • Vấn đề: Lỗi khi nhấp nút refresh
        • Nguyên nhân: Kết nối WebSocket thất bại
        • Giải pháp:
          • Xác minh địa chỉ IP của ESP32 là chính xác
          • Kiểm tra ESP32 có trên cùng mạng WiFi không
          • Khởi động lại ESP32 và làm mới trang web
          • Kiểm tra cài đặt firewall

          3. Lỗi "Not connected to Arduino"

          • Vấn đề: Lỗi khi nhấp nút refresh
          • Nguyên nhân: Kết nối WebSocket thất bại
          • Giải pháp:
            • Xác minh địa chỉ IP của ESP32 là chính xác
            • Kiểm tra ESP32 có trên cùng mạng WiFi không
            • Khởi động lại ESP32 và làm mới trang web
            • Kiểm tra cài đặt firewall

            4. Thay Đổi Cấu Trúc Bảng Không Phản Ánh

            • Vấn đề: Các hàng được thêm/xóa không xuất hiện trên giao diện web
            • Nguyên nhân: Cấu trúc bảng chỉ được cấu hình trong setup()
            • Giải pháp:
              • Khởi động lại ESP32 để áp dụng thay đổi cấu trúc
              • Sử dụng clearTable()addRow() nếu cần thay đổi động
              • Làm mới trang web sau khi khởi động lại ESP32

              Mẹo Debug

              Bật Debug Serial:

              void onDataRequested() { Serial.println("Web client requested table data"); Serial.println("Sending table configuration..."); // Gửi cấu hình bảng đến web client tablePage.sendTableConfig(); }

              Theo Dõi Cập Nhật Giá Trị:

              void updateSensorValues() { float temperature = readTemperature(); Serial.print("Updating temperature: "); Serial.println(String(temperature, 1) + "°C"); // Gửi cập nhật đến giao diện web (làm nổi bật sẽ được xử lý tự động) tablePage.sendValueUpdate("Temperature", String(temperature, 1) + "°C"); }

              Kiểm Tra Trạng Thái Kết Nối:

              void setup() { // ... code setup khác setupTableStructure(); Serial.println("Table configured with real-time highlighting"); Serial.println("Values will be highlighted automatically based on changes"); }

Ví Dụ Sử Dụng Nâng Cao

Giám Sát Cảm Biến Với Làm Nổi Bật Thông Minh

void updateEnvironmentalSensors() { // Đọc các cảm biến khác nhau float temperature = readTemperatureSensor(); float humidity = readHumiditySensor(); int lightLevel = analogRead(A0); bool motionDetected = digitalRead(2); // Gửi cập nhật - làm nổi bật xảy ra tự động tablePage.sendValueUpdate("Temperature", String(temperature, 1) + "°C"); tablePage.sendValueUpdate("Humidity", String(humidity, 1) + "%"); tablePage.sendValueUpdate("Light Level", String(lightLevel)); tablePage.sendValueUpdate("Motion", motionDetected ? "DETECTED" : "CLEAR"); }