ESP32 Bluetooth Table Example Hướng dẫn Giao diện Hiển thị Dữ liệu Có Cấu trúc

Tổng quan

Ví dụ Bluetooth Table cung cấp giao diện hiển thị dữ liệu key-value có cấu trúc được truy cập thông qua ứng dụng DIYables Bluetooth STEM. Được thiết kế cho các bo mạch ESP32 với hỗ trợ kết nối cả BLE (Bluetooth Low Energy)Classic Bluetooth. Định nghĩa các hàng có tên và cập nhật giá trị theo thời gian thực — hoàn hảo cho dashboard, bảng trạng thái cảm biến, giám sát hệ thống, và bất kỳ ứng dụng nào yêu cầu trình bày dữ liệu có tổ chức.

Ví dụ này hỗ trợ hai chế độ Bluetooth:

  • ESP32 BLE (Bluetooth Low Energy): Hoạt động trên cả Android và iOS
  • ESP32 Classic Bluetooth: Chỉ hoạt động trên Android. iOS không hỗ trợ Classic Bluetooth. Sử dụng BLE nếu bạn cần hỗ trợ iOS.
ESP32 Bluetooth table example - hướng dẫn giao diện hiển thị dữ liệu có cấu trúc

Tính năng

  • Hàng Có Cấu trúc: Tối đa 20 hàng thuộc tính có tên
  • Cập Nhật Thời Gian Thực: Cập nhật giá trị từng hàng riêng lẻ mà không cần làm mới toàn bộ bảng
  • Thuộc Tính Có Tên: Mỗi hàng có một nhãn mô tả (ví dụ: "Temperature", "Status")
  • Giá Trị Động: Gửi bất kỳ giá trị chuỗi nào cho mỗi hàng
  • Đồng Bộ Cấu Trúc Bảng: Ứng dụng yêu cầu cấu hình bảng khi kết nối
  • BLE & Classic Bluetooth: Chọn chế độ Bluetooth phù hợp với dự án của bạn
  • Đa Nền Tảng: Chế độ BLE hoạt động trên cả Android và iOS; Classic Bluetooth hoạt động trên Android
  • Tùy Chọn Tiết Kiệm Pin: Chế độ BLE tiêu thụ ít năng lượng hơn Classic Bluetooth

Linh kiện 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×USB Cable Type-A to Type-C (for USB-A PC)
1×USB Cable Type-C to Type-C (for USB-C PC)
1×breadboard
1×dây jumper
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)

Code ESP32

Các bước nhanh

Thực hiện theo từng bước sau:

  • 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 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 và cổng COM phù hợp.
  • Điều hướng đến biểu tượng Libraries ở thanh bên trái của Arduino IDE.
  • Tìm kiếm "DIYables Bluetooth", sau đó tìm thư viện DIYables Bluetooth của DIYables
  • Nhấp nút Install để cài đặt thư viện.
ESP32 diyables Bluetooth thư viện
  • Bạn sẽ được yêu cầu 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.
ESP32 diyables Bluetooth dependency

Chọn một trong hai chế độ Bluetooth bên dưới tùy theo nhu cầu của bạn:

Code ESP32 Classic Bluetooth (chỉ hoạt động với ứng dụng trên Android)

Lưu ý: Classic Bluetooth KHÔNG được hỗ trợ trên iOS. Nếu bạn cần hỗ trợ iOS, hãy sử dụng code BLE bên dưới.

  • Trên Arduino IDE, vào File Examples DIYables Bluetooth Esp32Bluetooth_Table example, hoặc sao chép code trên và dán vào editor của Arduino IDE
/* * DIYables Bluetooth Library - ESP32 Classic Bluetooth Table Example * Works with DIYables Bluetooth STEM app on Android * Note: Classic Bluetooth is NOT supported on iOS. Use BLE examples for iOS support. * * This example demonstrates the Bluetooth Table feature: * - Display structured data in a two-column table * - Real-time value updates for each row * - Perfect for sensor dashboards and status displays * * Compatible Boards: * - ESP32 (all variants with Classic Bluetooth) * - ESP32-WROOM-32 * - ESP32-DevKitC * - ESP32-WROVER * * Note: Select "Huge APP (3MB No OTA/1MB SPIFFS)" partition scheme * in Arduino IDE: Tools > Partition Scheme * * Setup: * 1. Upload the sketch to your ESP32 * 2. Open Serial Monitor (115200 baud) to see connection status * 3. Use DIYables Bluetooth App to connect and view the table * * Tutorial: https://diyables.io/bluetooth-app * Author: DIYables */ #include <DIYables_BluetoothServer.h> #include <DIYables_BluetoothTable.h> #include <platforms/DIYables_Esp32Bluetooth.h> // Create Bluetooth instances DIYables_Esp32Bluetooth bluetooth("ESP32_Table"); DIYables_BluetoothServer bluetoothServer(bluetooth); // Create Table app instance DIYables_BluetoothTable bluetoothTable; // Variables for demo data unsigned long lastUpdate = 0; const unsigned long UPDATE_INTERVAL = 1000; // Update every second int counter = 0; void setup() { Serial.begin(115200); delay(1000); Serial.println("DIYables Bluetooth - ESP32 Table Example"); // Initialize Bluetooth server with platform-specific implementation bluetoothServer.begin(); // Add table app to server bluetoothServer.addApp(&bluetoothTable); // Define table structure (add rows with attribute names) bluetoothTable.addRow("Temperature"); bluetoothTable.addRow("Humidity"); bluetoothTable.addRow("Pressure"); bluetoothTable.addRow("Counter"); bluetoothTable.addRow("Uptime"); bluetoothTable.addRow("Free Heap"); bluetoothTable.addRow("CPU Freq"); bluetoothTable.addRow("Status"); Serial.print("Table rows defined: "); Serial.println(bluetoothTable.getRowCount()); // Set up connection event callbacks bluetoothServer.setOnConnected([]() { Serial.println("Bluetooth connected!"); // Send table structure bluetoothTable.sendTableStructure(); // Send initial values updateTableValues(); }); bluetoothServer.setOnDisconnected([]() { Serial.println("Bluetooth disconnected!"); }); // Optional: Handle requests for table data bluetoothTable.onDataRequest([]() { Serial.println("App requested table data"); bluetoothTable.sendTableStructure(); updateTableValues(); }); Serial.println("Waiting for Bluetooth connection..."); } void updateTableValues() { // TODO: Replace with actual sensor readings // Simulated temperature (20-30°C) float temperature = 20.0 + random(0, 100) / 10.0; bluetoothTable.sendValueUpdate("Temperature", String(temperature, 1) + " °C"); // Simulated humidity (40-60%) int humidity = 40 + random(0, 21); bluetoothTable.sendValueUpdate("Humidity", String(humidity) + " %"); // Simulated pressure (1000-1020 hPa) int pressure = 1000 + random(0, 21); bluetoothTable.sendValueUpdate("Pressure", String(pressure) + " hPa"); // Counter value bluetoothTable.sendValueUpdate("Counter", String(counter)); counter++; // Uptime (in seconds) unsigned long uptime = millis() / 1000; String uptimeStr = String(uptime / 3600) + "h " + String((uptime % 3600) / 60) + "m " + String(uptime % 60) + "s"; bluetoothTable.sendValueUpdate("Uptime", uptimeStr); // ESP32-specific: Free heap memory bluetoothTable.sendValueUpdate("Free Heap", String(ESP.getFreeHeap()) + " bytes"); // ESP32-specific: CPU frequency bluetoothTable.sendValueUpdate("CPU Freq", String(ESP.getCpuFreqMHz()) + " MHz"); // Status bluetoothTable.sendValueUpdate("Status", counter % 2 == 0 ? "Running" : "Active"); Serial.println("Table values updated"); } void loop() { // Handle Bluetooth server communications bluetoothServer.loop(); // Update table values periodically (only when connected) if (bluetooth.isConnected() && millis() - lastUpdate >= UPDATE_INTERVAL) { lastUpdate = millis(); updateTableValues(); } delay(10); }
  • 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 như sau:
COM6
Send
DIYables Bluetooth - ESP32 Table Example Waiting for Bluetooth connection...
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Code ESP32 BLE (hoạt động với ứng dụng trên cả Android và iOS)

  • Trên Arduino IDE, vào File Examples DIYables Bluetooth Esp32BLE_Table example, hoặc sao chép code trên và dán vào editor của Arduino IDE
/* * DIYables Bluetooth Library - ESP32 BLE Table Example * Works with DIYables Bluetooth STEM app on Android and iOS * * This example demonstrates the Bluetooth Table feature: * - Display structured data in a two-column table * - Real-time value updates for each row * - Perfect for sensor dashboards and status displays * * Compatible Boards: * - ESP32-WROOM-32 * - ESP32-DevKitC * - ESP32-WROVER * - ESP32-S3 * - ESP32-C3 * - Any ESP32 board supporting BLE * * Note: Select "Huge APP (3MB No OTA/1MB SPIFFS)" partition scheme * in Arduino IDE: Tools > Partition Scheme * * Setup: * 1. Upload the sketch to your ESP32 * 2. Open Serial Monitor (115200 baud) to see connection status * 3. Use DIYables Bluetooth App to connect and view the table * * Tutorial: https://diyables.io/bluetooth-app * Author: DIYables */ #include <DIYables_BluetoothServer.h> #include <DIYables_BluetoothTable.h> #include <platforms/DIYables_Esp32BLE.h> // BLE Configuration const char* DEVICE_NAME = "ESP32BLE_Table"; const char* SERVICE_UUID = "19B10000-E8F2-537E-4F6C-D104768A1214"; const char* TX_UUID = "19B10001-E8F2-537E-4F6C-D104768A1214"; const char* RX_UUID = "19B10002-E8F2-537E-4F6C-D104768A1214"; // Create Bluetooth instances DIYables_Esp32BLE bluetooth(DEVICE_NAME, SERVICE_UUID, TX_UUID, RX_UUID); DIYables_BluetoothServer bluetoothServer(bluetooth); // Create Table app instance DIYables_BluetoothTable bluetoothTable; // Variables for demo data unsigned long lastUpdate = 0; const unsigned long UPDATE_INTERVAL = 1000; int counter = 0; void setup() { Serial.begin(115200); delay(1000); Serial.println("DIYables Bluetooth - ESP32 BLE Table Example"); // Initialize Bluetooth server with platform-specific implementation bluetoothServer.begin(); // Add table app to server bluetoothServer.addApp(&bluetoothTable); // Define table structure bluetoothTable.addRow("Temperature"); bluetoothTable.addRow("Humidity"); bluetoothTable.addRow("Pressure"); bluetoothTable.addRow("Counter"); bluetoothTable.addRow("Uptime"); bluetoothTable.addRow("Free Heap"); bluetoothTable.addRow("Status"); Serial.print("Table rows defined: "); Serial.println(bluetoothTable.getRowCount()); // Set up connection event callbacks bluetoothServer.setOnConnected([]() { Serial.println("Bluetooth connected!"); bluetoothTable.sendTableStructure(); updateTableValues(); }); bluetoothServer.setOnDisconnected([]() { Serial.println("Bluetooth disconnected!"); }); bluetoothTable.onDataRequest([]() { Serial.println("App requested table data"); bluetoothTable.sendTableStructure(); updateTableValues(); }); Serial.println("Waiting for Bluetooth connection..."); } void updateTableValues() { float temperature = 20.0 + random(0, 100) / 10.0; bluetoothTable.sendValueUpdate("Temperature", String(temperature, 1) + " °C"); int humidity = 40 + random(0, 21); bluetoothTable.sendValueUpdate("Humidity", String(humidity) + " %"); int pressure = 1000 + random(0, 21); bluetoothTable.sendValueUpdate("Pressure", String(pressure) + " hPa"); bluetoothTable.sendValueUpdate("Counter", String(counter)); counter++; unsigned long uptime = millis() / 1000; String uptimeStr = String(uptime / 3600) + "h " + String((uptime % 3600) / 60) + "m " + String(uptime % 60) + "s"; bluetoothTable.sendValueUpdate("Uptime", uptimeStr); bluetoothTable.sendValueUpdate("Free Heap", String(ESP.getFreeHeap()) + " bytes"); bluetoothTable.sendValueUpdate("Status", counter % 2 == 0 ? "Running" : "Active"); Serial.println("Table values updated"); } void loop() { bluetoothServer.loop(); if (bluetooth.isConnected() && millis() - lastUpdate >= UPDATE_INTERVAL) { lastUpdate = millis(); updateTableValues(); } delay(10); }
  • 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 như sau:
COM6
Send
DIYables Bluetooth - ESP32 BLE Table Example Waiting for Bluetooth connection...
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Ứng dụng điện thoại

  • Cài đặt ứng dụng DIYables Bluetooth trên smartphone của bạn: Android | iOS
  • Nếu bạn đang sử dụng code ESP32 Classic Bluetooth, bạn cần ghép nối ESP32 với điện thoại Android trước khi mở ứng dụng:
    • Vào Settings > Bluetooth của điện thoại
    • Đảm bảo Bluetooth được bật
    • Điện thoại sẽ quét các thiết bị có sẵn
    • Tìm và nhấn "ESP32_Table" trong danh sách thiết bị có sẵn
    • Xác nhận yêu cầu ghép nối (không cần PIN)
    • Đợi cho đến khi hiển thị "Paired" dưới tên thiết bị
  • Nếu bạn đang sử dụng code ESP32 BLE, không cần ghép nối. Chỉ cần tiến hành bước tiếp theo.
  • Mở ứng dụng DIYables Bluetooth
  • Khi mở ứng dụng lần đầu tiên, nó sẽ yêu cầu quyền. Vui lòng cấp các quyền sau:
    • Quyền Nearby Devices (Android 12+) / quyền Bluetooth (iOS) - cần thiết để quét và kết nối với thiết bị Bluetooth
    • Quyền Location (chỉ Android 11 trở xuống) - yêu cầu bởi các phiên bản Android cũ để quét thiết bị BLE
  • Đảm bảo Bluetooth được bật trên điện thoại
  • Trên màn hình chính, nhấn nút Connect. Ứng dụng sẽ quét cả thiết bị BLE và Classic Bluetooth.
diyables Bluetooth app - home screen with scan nút nhấn
  • Tìm và nhấn thiết bị của bạn trong kết quả quét để kết nối:
    • Đối với Classic Bluetooth: nhấn "ESP32_Table"
    • Đối với BLE: nhấn "ESP32BLE_Table"
  • Sau khi kết nối, ứng dụng tự động quay lại màn hình chính. Chọn ứng dụng Table từ menu ứng dụng.
diyables Bluetooth app - home screen with table app

Lưu ý: Bạn có thể nhấn biểu tượng cài đặt trên màn hình chính để ẩn/hiện các ứng dụng trên màn hình chính. Để biết thêm chi tiết, xem Hướng dẫn sử dụng DIYables Bluetooth App.

  • Bảng sẽ được điền với các tên thuộc tính và giá trị hiện tại của chúng
diyables Bluetooth app - table screen

Bây giờ hãy nhìn lại Serial Monitor trên Arduino IDE. Bạn sẽ thấy:

COM6
Send
Bluetooth connected! App requested table data Sent table structure Temperature: 25.3 Humidity: 62% Pressure: 1013 hPa Counter: 1 Uptime: 0h 0m 5s Free Heap: 245780 Status: Running
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  
  • Theo dõi các giá trị bảng cập nhật theo thời gian thực trong ứng dụng

Tùy chỉnh Sáng tạo - Điều chỉnh Code cho Dự án của Bạn

Định nghĩa Hàng Bảng

Thêm các hàng thuộc tính vào bảng (tối đa 20 hàng):

// Thêm hàng trong quá trình setup bluetoothTable.addRow("Temperature"); bluetoothTable.addRow("Humidity"); bluetoothTable.addRow("Pressure"); bluetoothTable.addRow("Status"); bluetoothTable.addRow("Uptime"); // Kiểm tra số lượng hàng int rows = bluetoothTable.getRowCount(); Serial.println("Total rows: " + String(rows)); // Lấy tên thuộc tính theo chỉ số String attr = bluetoothTable.getAttribute(0); // Trả về "Temperature"

Cập nhật Giá trị Hàng

Cập nhật giá trị hàng riêng lẻ theo tên thuộc tính hoặc chỉ số:

// Cập nhật theo tên thuộc tính bluetoothTable.sendValueUpdate("Temperature", "25.3 °C"); bluetoothTable.sendValueUpdate("Humidity", "62%"); bluetoothTable.sendValueUpdate("Status", "Running"); // Cập nhật theo chỉ số hàng (bắt đầu từ 0) bluetoothTable.sendValueUpdate(0, "25.3 °C"); // Hàng đầu tiên bluetoothTable.sendValueUpdate(1, "62%"); // Hàng thứ hai

Xử lý Yêu cầu Dữ liệu từ Ứng dụng

Khi ứng dụng kết nối hoặc yêu cầu làm mới:

bluetoothTable.onDataRequest([]() { Serial.println("App requested table data"); bluetoothTable.sendTableStructure(); // Gửi tên hàng // Gửi giá trị hiện tại cho tất cả hàng bluetoothTable.sendValueUpdate("Temperature", String(temperature, 1) + " °C"); bluetoothTable.sendValueUpdate("Humidity", String(humidity) + "%"); bluetoothTable.sendValueUpdate("Status", "Online"); });

Xóa và Xây dựng lại Bảng

// Xóa tất cả hàng bluetoothTable.clearTable(); // Thêm hàng mới bluetoothTable.addRow("Sensor A"); bluetoothTable.addRow("Sensor B"); // Gửi cấu trúc cập nhật đến ứng dụng bluetoothTable.sendTableStructure();

Xử lý Sự kiện Kết nối

bluetoothServer.setOnConnected([]() { Serial.println("Bluetooth connected!"); }); bluetoothServer.setOnDisconnected([]() { Serial.println("Bluetooth disconnected!"); });

Cách sử dụng Bảng

Giao diện Ứng dụng

Giao diện bảng trong ứng dụng DIYables Bluetooth hiển thị:

  • Cột Attribute: Nhãn hàng được định nghĩa bởi addRow()
  • Cột Value: Giá trị hiện tại được cập nhật bởi sendValueUpdate()
  • Tự động Làm mới: Giá trị cập nhật theo thời gian thực khi chúng nhận được

Giới hạn Bảng

  • Tối đa 20 hàng mỗi bảng (MAX_TABLE_ROWS = 20)
  • Tên thuộc tính nên ngắn gọn nhưng mô tả rõ ràng
  • Giá trị được hiển thị dưới dạng chuỗi

Ví dụ Lập trình

Dashboard Cảm biến

// Định nghĩa các hàng dashboard cảm biến bluetoothTable.addRow("Temperature"); bluetoothTable.addRow("Humidity"); bluetoothTable.addRow("Pressure"); bluetoothTable.addRow("Light Level"); bluetoothTable.addRow("Air Quality"); void loop() { bluetoothServer.loop(); static unsigned long lastUpdate = 0; if (millis() - lastUpdate >= 2000) { lastUpdate = millis(); float temp = readTemperature(); float hum = readHumidity(); float press = readPressure(); int light = analogRead(34); int airQuality = analogRead(35); bluetoothTable.sendValueUpdate("Temperature", String(temp, 1) + " °C"); bluetoothTable.sendValueUpdate("Humidity", String(hum, 0) + "%"); bluetoothTable.sendValueUpdate("Pressure", String(press, 0) + " hPa"); bluetoothTable.sendValueUpdate("Light Level", String(map(light, 0, 4095, 0, 100)) + "%"); bluetoothTable.sendValueUpdate("Air Quality", airQuality < 1000 ? "Good" : "Poor"); } delay(10); }

Giám sát Trạng thái Hệ thống

bluetoothTable.addRow("Uptime"); bluetoothTable.addRow("Free Heap"); bluetoothTable.addRow("CPU Temp"); bluetoothTable.addRow("WiFi Signal"); bluetoothTable.addRow("Clients"); bluetoothTable.addRow("Status"); void updateSystemStatus() { unsigned long uptime = millis() / 1000; int hours = uptime / 3600; int minutes = (uptime % 3600) / 60; int seconds = uptime % 60; bluetoothTable.sendValueUpdate("Uptime", String(hours) + "h " + String(minutes) + "m " + String(seconds) + "s"); bluetoothTable.sendValueUpdate("Free Heap", String(ESP.getFreeHeap()) + " bytes"); bluetoothTable.sendValueUpdate("CPU Temp", String(temperatureRead(), 1) + " °C"); bluetoothTable.sendValueUpdate("Status", "Online"); }

Bảng Trạng thái GPIO Pin

const int PINS[] = {2, 4, 5, 12, 13, 14, 15, 16}; const int NUM_PINS = sizeof(PINS) / sizeof(PINS[0]); void setup() { // ... Thiết lập Bluetooth ... for (int i = 0; i < NUM_PINS; i++) { pinMode(PINS[i], INPUT); bluetoothTable.addRow("GPIO " + String(PINS[i])); } } void loop() { bluetoothServer.loop(); static unsigned long lastUpdate = 0; if (millis() - lastUpdate >= 1000) { lastUpdate = millis(); for (int i = 0; i < NUM_PINS; i++) { int state = digitalRead(PINS[i]); bluetoothTable.sendValueUpdate("GPIO " + String(PINS[i]), state == HIGH ? "HIGH ?" : "LOW ?"); } } delay(10); }

Mảng Cảm biến Analog

struct SensorConfig { String name; int pin; String unit; float scale; }; SensorConfig sensors[] = { {"Temperature", 34, "°C", 0.0488}, {"Humidity", 35, "%", 0.0244}, {"Light", 36, "lux", 0.244}, {"Pressure", 39, "hPa", 0.488} }; const int NUM_SENSORS = sizeof(sensors) / sizeof(sensors[0]); void setup() { // ... Thiết lập Bluetooth ... for (int i = 0; i < NUM_SENSORS; i++) { bluetoothTable.addRow(sensors[i].name); } } void loop() { bluetoothServer.loop(); static unsigned long lastUpdate = 0; if (millis() - lastUpdate >= 2000) { lastUpdate = millis(); for (int i = 0; i < NUM_SENSORS; i++) { int raw = analogRead(sensors[i].pin); float value = raw * sensors[i].scale; bluetoothTable.sendValueUpdate(sensors[i].name, String(value, 1) + " " + sensors[i].unit); } } delay(10); }

Kỹ thuật Lập trình Nâng cao

Định dạng Có điều kiện với Emoji

void updateTemperatureRow(float temp) { String status; if (temp < 10) { status = "❄️ " + String(temp, 1) + " °C (Cold)"; } else if (temp < 30) { status = "✅ " + String(temp, 1) + " °C (Normal)"; } else { status = "🔥 " + String(temp, 1) + " °C (Hot!)"; } bluetoothTable.sendValueUpdate("Temperature", status); }

Cập nhật Theo Sự kiện

float lastTemp = 0; float threshold = 0.5; // Chỉ cập nhật khi có thay đổi đáng kể void loop() { bluetoothServer.loop(); float temp = readTemperature(); if (abs(temp - lastTemp) >= threshold) { lastTemp = temp; bluetoothTable.sendValueUpdate("Temperature", String(temp, 1) + " °C"); bluetoothTable.sendValueUpdate("Last Change", getTimestamp()); } delay(100); }

Ý tưởng Tích hợp Phần cứng

Bảng Trạm Thời tiết BME280

Kết nối cảm biến BME280 để hiển thị nhiệt độ, độ ẩm và áp suất trong bảng.

Dashboard Đa Cảm biến

Kết nối nhiều cảm biến (DHT22, BMP280, LDR, MQ-135) và hiển thị tất cả các giá trị đo dưới dạng hàng.

Bảng Thông tin Thiết bị

Hiển thị thông tin hệ thống ESP32: model chip, kích thước flash, heap trống, uptime, và địa chỉ MAC.

BLE vs Classic Bluetooth - Nên chọn cái nào?

Tính năngBLE (Esp32BLE_Table)Classic Bluetooth (Esp32Bluetooth_Table)
Hỗ trợ iOS? Có? Không
Hỗ trợ Android? Có? Có
Tiêu thụ PinThấpCao hơn
Tầm xa~30-100m~10-100m
Tốc độ Dữ liệuThấp hơnCao hơn
Cần Ghép nốiKhông (tự kết nối)Có (ghép nối thủ công)
Tốt nhất choChạy pin, đa nền tảngThông lượng cao, chỉ Android

Khắc phục Sự cố

Vấn đề Thường gặp

1. Không thể tìm thấy thiết bị trong ứng dụng

  • Đảm bảo ESP32 được cấp nguồn và sketch đã được upload
  • Đối với BLE: Đảm bảo Bluetooth và Location của điện thoại được bật
  • Đối với Classic Bluetooth: Ghép nối thiết bị trước trong cài đặt Bluetooth của điện thoại
  • Kiểm tra rằng partition scheme chính xác được chọn (Huge APP)

2. Bảng không hiển thị dữ liệu

  • Đảm bảo sendTableStructure() được gọi trong callback onDataRequest
  • Xác minh các hàng được thêm với addRow() trước khi gửi cập nhật
  • Kiểm tra Serial Monitor để thấy thông báo "App requested table data"

3. Giá trị không cập nhật

  • Xác minh tên thuộc tính trong sendValueUpdate() khớp chính xác với những gì được thêm bằng addRow()
  • Kiểm tra timer khoảng cách cập nhật của bạn đang hoạt động
  • Đảm bảo Bluetooth vẫn được kết nối

4. Thiếu hàng trong bảng

  • Tối đa 20 hàng được hỗ trợ
  • Kiểm tra getRowCount() để xác minh tất cả hàng đã được thêm
  • Hàng phải được thêm trước khi gửi cấu trúc bảng

5. Kết nối thường xuyên bị ngắt

  • Di chuyển gần hơn với ESP32 (giảm khoảng cách)
  • Đối với BLE: Kiểm tra nhiễu từ các thiết bị BLE khác
  • Đối với Classic Bluetooth: Đảm bảo nguồn điện ổn định cho ESP32

6. Sketch quá lớn / không đủ không gian

  • Trong Arduino IDE, vào Tools > Partition Scheme và chọn "Huge APP (3MB No OTA/1MB SPIFFS)" hoặc "No OTA (Large APP)"
  • Partition scheme mặc định chỉ cung cấp ~1.2MB cho code ứng dụng, không đủ cho thư viện Bluetooth
  • Cài đặt này cung cấp ~3MB bằng cách hy sinh partition OTA (cập nhật qua không khí)

Mẹo Debug

Thêm debug toàn diện:

void debugTable() { Serial.println("=== Table Debug ==="); Serial.println("Row Count: " + String(bluetoothTable.getRowCount())); for (int i = 0; i < bluetoothTable.getRowCount(); i++) { Serial.println("Row " + String(i) + ": " + bluetoothTable.getAttribute(i)); } Serial.println("==================="); }

Ý tưởng Dự án

Dashboard Giám sát

  • Hiển thị trạm thời tiết (nhiệt độ, độ ẩm, áp suất, gió)
  • Giám sát trạng thái server/mạng
  • Dashboard chăm sóc cây trồng (độ ẩm đất, ánh sáng, nhiệt độ)
  • Giám sát bể cá (nhiệt độ, pH, TDS)

Thông tin Hệ thống

  • Chẩn đoán hệ thống ESP32
  • Chi tiết kết nối WiFi
  • Theo dõi sử dụng bộ nhớ
  • Hiển thị trạng thái pin

Ghi dữ liệu

  • Theo dõi min/max/trung bình cảm biến
  • Hiển thị bộ đếm sự kiện
  • Thống kê thời gian (thời gian phản hồi, uptime)
  • Tổng kết trạng thái pin I/O

Tự động hóa Nhà

  • Hiển thị nhiệt độ từng phòng
  • Tổng quan trạng thái thiết bị
  • Tóm tắt tiêu thụ năng lượng
  • Trạng thái cảm biến an ninh