ESP32 Bluetooth Monitor Hướng Dẫn Giao Diện Serial Monitor Thời Gian Thực
Ví dụ Bluetooth Monitor cung cấp giao diện serial monitor không dây có thể truy cập thông qua ứng dụng DIYables Bluetooth STEM. Được thiết kế cho các board ESP32 với hỗ trợ cả kết nối BLE (Bluetooth Low Energy) và Classic Bluetooth. Truyền tải tin nhắn trạng thái thời gian thực đến ứng dụng, nhận và xử lý các lệnh văn bản, hiển thị thông tin hệ thống, và debug các dự án của bạn một cách không dây — hoàn hảo cho việc giám sát không cần dây, debug từ xa, và hiển thị trạng thái hệ thống.
Ví dụ này hỗ trợ hai chế độ Bluetooth:
Truyền Tải Thời Gian Thực: Gửi tin nhắn trạng thái liên tục đến màn hình ứng dụng
Xử Lý Lệnh: Nhận và xử lý các lệnh văn bản từ ứng dụng
Giám Sát Hệ Thống: Hiển thị thời gian hoạt động, bộ nhớ trống, thông tin CPU và nhiều hơn nữa
Điều Khiển LED: Lệnh BẬT/TẮT LED tích hợp để kiểm tra nhanh
Cập Nhật Định Kỳ: Tin nhắn heartbeat và trạng thái tự động với khoảng thời gian có thể cấu hình
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 Điện: Chế độ BLE tiêu thụ ít điện năng hơn Classic Bluetooth
| 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) | | |
Thực hiện theo các hướng dẫn từng bước sau:
Kết nối board 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 board ESP32 và COM port phù hợp.
Đ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 Bluetooth", sau đó tìm thư viện DIYables Bluetooth bởi DIYables
Nhấp vào nút Install để cài đặt thư viện.
Chọn một trong hai chế độ Bluetooth dưới đây tùy theo nhu cầu của bạn:
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.
#include <DIYables_BluetoothServer.h>
#include <DIYables_BluetoothMonitor.h>
#include <platforms/DIYables_Esp32Bluetooth.h>
DIYables_Esp32Bluetooth bluetooth("ESP32_Monitor");
DIYables_BluetoothServer bluetoothServer(bluetooth);
DIYables_BluetoothMonitor bluetoothMonitor;
unsigned long lastUpdate = 0;
const unsigned long UPDATE_INTERVAL = 3000;
int messageCount = 0;
bool ledState = false;
const int LED_PIN = 2;
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("DIYables Bluetooth - ESP32 Monitor Example");
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
bluetoothServer.begin();
bluetoothServer.addApp(&bluetoothMonitor);
bluetoothServer.setOnConnected([]() {
Serial.println("Bluetooth connected!");
bluetoothMonitor.send("=== ESP32 Monitor Connected ===");
bluetoothMonitor.send("System Ready");
bluetoothMonitor.send("Type HELP for available commands");
bluetoothMonitor.send("");
});
bluetoothServer.setOnDisconnected([]() {
Serial.println("Bluetooth disconnected!");
});
bluetoothMonitor.onMonitorMessage([](const String& message) {
Serial.print("Received command: ");
Serial.println(message);
handleCommand(message);
});
Serial.println("Waiting for Bluetooth connection...");
}
void handleCommand(const String& cmd) {
if (cmd == "HELP") {
bluetoothMonitor.send("Available Commands:");
bluetoothMonitor.send(" LED_ON - Turn LED on");
bluetoothMonitor.send(" LED_OFF - Turn LED off");
bluetoothMonitor.send(" STATUS - Show system status");
bluetoothMonitor.send(" HEAP - Show memory info");
bluetoothMonitor.send(" CLEAR - Clear monitor (if supported)");
bluetoothMonitor.send(" HELP - Show this help");
}
else if (cmd == "LED_ON") {
digitalWrite(LED_PIN, HIGH);
ledState = true;
bluetoothMonitor.send("✓ LED turned ON");
}
else if (cmd == "LED_OFF") {
digitalWrite(LED_PIN, LOW);
ledState = false;
bluetoothMonitor.send("✓ LED turned OFF");
}
else if (cmd == "STATUS") {
showStatus();
}
else if (cmd == "HEAP") {
bluetoothMonitor.send("=== Memory Info ===");
bluetoothMonitor.send("Free Heap: " + String(ESP.getFreeHeap()) + " bytes");
bluetoothMonitor.send("Min Free Heap: " + String(ESP.getMinFreeHeap()) + " bytes");
bluetoothMonitor.send("Heap Size: " + String(ESP.getHeapSize()) + " bytes");
bluetoothMonitor.send("===================");
}
else if (cmd == "CLEAR") {
bluetoothMonitor.send("");
}
else {
bluetoothMonitor.send("✗ Unknown command: " + cmd);
bluetoothMonitor.send("Type HELP for available commands");
}
}
void showStatus() {
bluetoothMonitor.send("=== System Status ===");
bluetoothMonitor.send("LED State: " + String(ledState ? "ON" : "OFF"));
unsigned long uptime = millis() / 1000;
bluetoothMonitor.send("Uptime: " + String(uptime / 3600) + "h " + String((uptime % 3600) / 60) + "m " + String(uptime % 60) + "s");
bluetoothMonitor.send("Free Heap: " + String(ESP.getFreeHeap()) + " bytes");
bluetoothMonitor.send("CPU Freq: " + String(ESP.getCpuFreqMHz()) + " MHz");
bluetoothMonitor.send("Chip Model: " + String(ESP.getChipModel()));
bluetoothMonitor.send("Messages Sent: " + String(messageCount));
bluetoothMonitor.send("====================");
}
void sendPeriodicUpdate() {
messageCount++;
if (messageCount % 3 == 0) {
bluetoothMonitor.send("[INFO] Heartbeat #" + String(messageCount));
}
else if (messageCount % 5 == 0) {
bluetoothMonitor.send("[HEAP] Free: " + String(ESP.getFreeHeap()) + " bytes");
}
else {
bluetoothMonitor.send("[TIME] Uptime: " + String(millis() / 1000) + "s");
}
Serial.print("Sent update #");
Serial.println(messageCount);
}
void loop() {
bluetoothServer.loop();
if (bluetooth.isConnected() && millis() - lastUpdate >= UPDATE_INTERVAL) {
lastUpdate = millis();
sendPeriodicUpdate();
}
delay(10);
}
DIYables Bluetooth - ESP32 Monitor Example
Waiting for Bluetooth connection...
#include <DIYables_BluetoothServer.h>
#include <DIYables_BluetoothMonitor.h>
#include <platforms/DIYables_Esp32BLE.h>
const char* DEVICE_NAME = "ESP32BLE_Monitor";
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";
DIYables_Esp32BLE bluetooth(DEVICE_NAME, SERVICE_UUID, TX_UUID, RX_UUID);
DIYables_BluetoothServer bluetoothServer(bluetooth);
DIYables_BluetoothMonitor bluetoothMonitor;
unsigned long lastUpdate = 0;
const unsigned long UPDATE_INTERVAL = 3000;
int messageCount = 0;
bool ledState = false;
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("DIYables Bluetooth - ESP32 BLE Monitor Example");
pinMode(2, OUTPUT);
digitalWrite(2, LOW);
bluetoothServer.begin();
bluetoothServer.addApp(&bluetoothMonitor);
bluetoothServer.setOnConnected([]() {
Serial.println("Bluetooth connected!");
bluetoothMonitor.send("=== ESP32 BLE Monitor Connected ===");
bluetoothMonitor.send("System Ready");
bluetoothMonitor.send("Type HELP for available commands");
bluetoothMonitor.send("");
});
bluetoothServer.setOnDisconnected([]() {
Serial.println("Bluetooth disconnected!");
});
bluetoothMonitor.onMonitorMessage([](const String& message) {
Serial.print("Received command: ");
Serial.println(message);
handleCommand(message);
});
Serial.println("Waiting for Bluetooth connection...");
}
void handleCommand(const String& cmd) {
if (cmd == "HELP") {
bluetoothMonitor.send("Available Commands:");
bluetoothMonitor.send(" LED_ON - Turn LED on");
bluetoothMonitor.send(" LED_OFF - Turn LED off");
bluetoothMonitor.send(" STATUS - Show system status");
bluetoothMonitor.send(" HEAP - Show free heap memory");
bluetoothMonitor.send(" HELP - Show this help");
}
else if (cmd == "LED_ON") {
digitalWrite(2, HIGH);
ledState = true;
bluetoothMonitor.send("LED turned ON");
}
else if (cmd == "LED_OFF") {
digitalWrite(2, LOW);
ledState = false;
bluetoothMonitor.send("LED turned OFF");
}
else if (cmd == "STATUS") {
showStatus();
}
else if (cmd == "HEAP") {
bluetoothMonitor.send("Free heap: " + String(ESP.getFreeHeap()) + " bytes");
}
else {
bluetoothMonitor.send("Unknown command: " + cmd);
bluetoothMonitor.send("Type HELP for available commands");
}
}
void showStatus() {
bluetoothMonitor.send("=== System Status ===");
bluetoothMonitor.send("LED State: " + String(ledState ? "ON" : "OFF"));
unsigned long uptime = millis() / 1000;
bluetoothMonitor.send("Uptime: " + String(uptime / 3600) + "h " + String((uptime % 3600) / 60) + "m " + String(uptime % 60) + "s");
bluetoothMonitor.send("Free Heap: " + String(ESP.getFreeHeap()) + " bytes");
bluetoothMonitor.send("Messages Sent: " + String(messageCount));
bluetoothMonitor.send("====================");
}
void sendPeriodicUpdate() {
messageCount++;
if (messageCount % 3 == 0) {
bluetoothMonitor.send("[INFO] Heartbeat #" + String(messageCount));
}
else if (messageCount % 5 == 0) {
bluetoothMonitor.send("[HEAP] Free: " + String(ESP.getFreeHeap()) + " bytes");
}
else {
bluetoothMonitor.send("[TIME] Uptime: " + String(millis() / 1000) + "s");
}
Serial.print("Sent update #");
Serial.println(messageCount);
}
void loop() {
bluetoothServer.loop();
if (bluetooth.isConnected() && millis() - lastUpdate >= UPDATE_INTERVAL) {
lastUpdate = millis();
sendPeriodicUpdate();
}
delay(10);
}
DIYables Bluetooth - ESP32 BLE Monitor Example
Waiting for Bluetooth connection...
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 của mình trước khi mở ứng dụng:
Đi đến Settings > Bluetooth của điện thoại
Đảm bảo Bluetooth đã được bật
Điện thoại của bạn sẽ quét các thiết bị có sẵn
Tìm và chạm vào "ESP32_Monitor" trong danh sách các thiết bị có sẵn
Xác nhận yêu cầu ghép nối (không cần PIN)
Chờ 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ếp tục 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 các thiết bị Bluetooth
Quyền Location (chỉ Android 11 trở xuống) - cần thiết cho 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 của bạn
Trên màn hình chính, chạm vào nút Connect. Ứng dụng sẽ quét cả thiết bị BLE và Classic Bluetooth.

Tìm và chạm vào thiết bị của bạn trong kết quả quét để kết nối:
Sau khi kết nối, ứng dụng tự động quay về màn hình chính. Chọn ứng dụng Monitor từ menu ứng dụng.
Lưu ý: Bạn có thể chạm vào 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ạn sẽ thấy các tin nhắn trạng thái đang được truyền tải trên màn hình monitor
Gõ LED_ON vào trường nhập liệu và chạm vào Send — LED tích hợp trên ESP32 sẽ BẬT, và monitor sẽ hiển thị tin nhắn xác nhận
Bây giờ hãy nhìn lại Serial Monitor trên Arduino IDE. Bạn sẽ thấy:
Bluetooth connected!
Sent update #1
Sent update #2
Received command: HELP
Received command: STATUS
Gõ các lệnh trong ứng dụng (HELP, STATUS, LED_ON, LED_OFF, HEAP) và xem các phản hồi
Sử dụng phương thức send() để truyền tải tin nhắn văn bản đến màn hình monitor:
bluetoothMonitor.send("System initialized");
bluetoothMonitor.send("Sensor reading: 25.3°C");
bluetoothMonitor.send("[INFO] Heartbeat #" + String(count));
bluetoothMonitor.send("[WARN] Temperature high: " + String(temp) + "°C");
bluetoothMonitor.send("[ERROR] Sensor disconnected");
bluetoothMonitor.send("Free Heap: " + String(ESP.getFreeHeap()) + " bytes");
bluetoothMonitor.send("Uptime: " + String(millis() / 1000) + " seconds");
Sử dụng callback onMonitorMessage() để nhận các lệnh được gõ trong ứng dụng Monitor và phản ứng với chúng:
bluetoothMonitor.onMonitorMessage([](const String& message) {
Serial.print("Received command: ");
Serial.println(message);
if (message == "HELP") {
bluetoothMonitor.send("Available Commands:");
bluetoothMonitor.send(" LED_ON - Turn LED on");
bluetoothMonitor.send(" LED_OFF - Turn LED off");
bluetoothMonitor.send(" STATUS - Show system status");
bluetoothMonitor.send(" HEAP - Show memory info");
} else if (message == "LED_ON") {
digitalWrite(LED_BUILTIN, HIGH);
bluetoothMonitor.send("LED turned ON");
} else if (message == "LED_OFF") {
digitalWrite(LED_BUILTIN, LOW);
bluetoothMonitor.send("LED turned OFF");
} else if (message == "STATUS") {
bluetoothMonitor.send("System is running normally");
bluetoothMonitor.send("Uptime: " + String(millis() / 1000) + "s");
} else if (message == "HEAP") {
bluetoothMonitor.send("Free Heap: " + String(ESP.getFreeHeap()) + " bytes");
} else {
bluetoothMonitor.send("Unknown command: " + message);
}
});
Bạn có thể thêm nhiều lệnh tùy chỉnh theo nhu cầu bằng cách thêm nhiều khối else if hơn. Ví dụ, thêm RELAY_ON / RELAY_OFF để điều khiển relay, hoặc READ để kích hoạt đọc cảm biến — bất kỳ từ nào bạn gõ trong ứng dụng đều có thể trở thành lệnh.
Bạn có thể phát hiện khi ứng dụng kết nối hoặc ngắt kết nối với ESP32:
bluetoothServer.setOnConnected([]() {
Serial.println("Bluetooth connected!");
bluetoothMonitor.send("=== ESP32 Monitor Connected ===");
bluetoothMonitor.send("System Ready");
bluetoothMonitor.send("Type HELP for available commands");
});
bluetoothServer.setOnDisconnected([]() {
Serial.println("Bluetooth disconnected!");
});
if (bluetoothServer.isConnected()) {
bluetoothMonitor.send("Status update");
}
Giao diện monitor trong ứng dụng DIYables Bluetooth cung cấp:
Hiển Thị Tin Nhắn: Danh sách tin nhắn nhận được có thể cuộn với tính năng tự động cuộn
Nhập Văn Bản: Gõ lệnh ở phía dưới
Nút Send: Chạm để gửi lệnh đã gõ đến ESP32
Code ví dụ bao gồm các lệnh tích hợp này:
HELP — Hiển thị tất cả các lệnh có sẵn
LED_ON — Bật LED tích hợp
LED_OFF — Tắt LED tích hợp
STATUS — Hiển thị trạng thái hệ thống (trạng thái LED, thời gian hoạt động, heap, tin nhắn đã gửi)
HEAP — Hiển thị thông tin bộ nhớ chi tiết
unsigned long lastUpdate = 0;
const unsigned long UPDATE_INTERVAL = 3000;
int messageCount = 0;
void loop() {
bluetoothServer.loop();
if (bluetooth.isConnected() && millis() - lastUpdate >= UPDATE_INTERVAL) {
lastUpdate = millis();
messageCount++;
if (messageCount % 3 == 0) {
bluetoothMonitor.send("[INFO] Heartbeat #" + String(messageCount));
} else if (messageCount % 5 == 0) {
bluetoothMonitor.send("[HEAP] Free: " + String(ESP.getFreeHeap()) + " bytes");
} else {
bluetoothMonitor.send("[TIME] Uptime: " + String(millis() / 1000) + "s");
}
}
delay(10);
}
#include <DHT.h>
DHT dht(4, DHT22);
unsigned long lastSensorRead = 0;
const unsigned long SENSOR_INTERVAL = 5000;
void setup() {
dht.begin();
bluetoothMonitor.onMonitorMessage([](const String& message) {
if (message == "READ") {
readAndSendSensorData();
} else if (message == "INTERVAL") {
bluetoothMonitor.send("Sensor interval: " + String(SENSOR_INTERVAL / 1000) + "s");
}
});
}
void readAndSendSensorData() {
float temp = dht.readTemperature();
float hum = dht.readHumidity();
if (!isnan(temp) && !isnan(hum)) {
bluetoothMonitor.send("Temp: " + String(temp, 1) + "°C | Humidity: " + String(hum, 1) + "%");
} else {
bluetoothMonitor.send("[ERROR] Failed to read sensor");
}
}
void loop() {
bluetoothServer.loop();
if (bluetooth.isConnected() && millis() - lastSensorRead >= SENSOR_INTERVAL) {
lastSensorRead = millis();
readAndSendSensorData();
}
delay(10);
}
void sendDashboard() {
bluetoothMonitor.send("========== DASHBOARD ==========");
bluetoothMonitor.send("Temp: " + String(readTemperature(), 1) + "°C");
bluetoothMonitor.send("Humidity: " + String(readHumidity(), 0) + "%");
bluetoothMonitor.send("Light: " + String(analogRead(34)));
bluetoothMonitor.send("Battery: " + String(readBatteryVoltage(), 2) + "V");
bluetoothMonitor.send("Heap: " + String(ESP.getFreeHeap()) + " bytes");
unsigned long uptime = millis() / 1000;
bluetoothMonitor.send("Uptime: " + String(uptime / 3600) + "h " +
String((uptime % 3600) / 60) + "m " +
String(uptime % 60) + "s");
bluetoothMonitor.send("===============================");
}
const int MONITOR_PINS[] = {16, 17, 18, 19, 21, 22};
const int NUM_PINS = 6;
int lastPinStates[6] = {0};
void setup() {
for (int i = 0; i < NUM_PINS; i++) {
pinMode(MONITOR_PINS[i], INPUT_PULLUP);
lastPinStates[i] = digitalRead(MONITOR_PINS[i]);
}
bluetoothMonitor.onMonitorMessage([](const String& message) {
if (message == "PINS") {
for (int i = 0; i < NUM_PINS; i++) {
int state = digitalRead(MONITOR_PINS[i]);
bluetoothMonitor.send("Pin " + String(MONITOR_PINS[i]) + ": " +
String(state ? "HIGH" : "LOW"));
}
}
});
}
void loop() {
bluetoothServer.loop();
for (int i = 0; i < NUM_PINS; i++) {
int state = digitalRead(MONITOR_PINS[i]);
if (state != lastPinStates[i]) {
lastPinStates[i] = state;
if (bluetooth.isConnected()) {
bluetoothMonitor.send("[PIN] GPIO " + String(MONITOR_PINS[i]) +
" changed to " + String(state ? "HIGH" : "LOW"));
}
}
}
delay(10);
}
enum LogLevel { LOG_INFO, LOG_WARN, LOG_ERROR, LOG_DEBUG };
void sendLog(LogLevel level, const String& message) {
String prefix;
switch (level) {
case LOG_INFO: prefix = "[INFO] "; break;
case LOG_WARN: prefix = "[WARN] "; break;
case LOG_ERROR: prefix = "[ERROR] "; break;
case LOG_DEBUG: prefix = "[DEBUG] "; break;
}
bluetoothMonitor.send(prefix + message);
}
sendLog(LOG_INFO, "System started");
sendLog(LOG_WARN, "Battery low: " + String(voltage, 2) + "V");
sendLog(LOG_ERROR, "Sensor read failed");
sendLog(LOG_DEBUG, "Loop time: " + String(loopTime) + "ms");
int sensorInterval = 3000;
bool verboseMode = false;
bluetoothMonitor.onMonitorMessage([](const String& message) {
String cmd = message;
cmd.toUpperCase();
if (cmd.startsWith("SET INTERVAL ")) {
sensorInterval = cmd.substring(13).toInt() * 1000;
bluetoothMonitor.send("Interval set to " + String(sensorInterval / 1000) + "s");
} else if (cmd == "VERBOSE ON") {
verboseMode = true;
bluetoothMonitor.send("Verbose mode enabled");
} else if (cmd == "VERBOSE OFF") {
verboseMode = false;
bluetoothMonitor.send("Verbose mode disabled");
} else if (cmd == "CONFIG") {
bluetoothMonitor.send("Interval: " + String(sensorInterval / 1000) + "s");
bluetoothMonitor.send("Verbose: " + String(verboseMode ? "ON" : "OFF"));
}
});
unsigned long lastLoopTime = 0;
unsigned long maxLoopTime = 0;
int warningCount = 0;
void loop() {
unsigned long loopStart = millis();
bluetoothServer.loop();
performTasks();
unsigned long loopTime = millis() - loopStart;
if (loopTime > maxLoopTime) {
maxLoopTime = loopTime;
}
if (loopTime > 100) {
warningCount++;
if (bluetooth.isConnected()) {
bluetoothMonitor.send("[WARN] Slow loop: " + String(loopTime) + "ms");
}
}
delay(10);
}
| Tính Năng | BLE (Esp32BLE_Monitor) | Classic Bluetooth (Esp32Bluetooth_Monitor) |
| Hỗ Trợ iOS | ✅ Có | ❌ Không |
| Hỗ Trợ Android | ✅ Có | ✅ Có |
| Tiêu Thụ Điện Năng | Thấp | Cao hơn |
| Tầm Xa | ~30-100m | ~10-100m |
| Tốc Độ Dữ Liệu | Thấp hơn | Cao hơn |
| Cần Ghép Nối | Không (tự động kết nối) | Có (ghép nối thủ công) |
| Phù Hợp Nhất Cho | Chạy pin, đa nền tảng | Thông lượng cao, chỉ Android |
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 đúng đã được chọn (Huge APP)
2. Tin nhắn không xuất hiện trong monitor
Kiểm tra trạng thái kết nối Bluetooth trong ứng dụng
Xác minh kết nối trong Serial Monitor
Đảm bảo tin nhắn đang được gửi với bluetoothMonitor.send()
Thử ngắt kết nối và kết nối lại
3. Lệnh không được nhận
Xác minh callback onMonitorMessage() đã được thiết lập đúng
Kiểm tra Serial Monitor cho các lệnh nhận được
Đảm bảo màn hình ứng dụng monitor đã được chọn trong ứng dụng di động
4. Kết nối thường xuyên bị ngắt
Di chuyển gần ESP32 hơn (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
Giảm tần suất tin nhắn nếu gửi quá nhanh
5. Tin nhắn xuất hiện bị lỗi hoặc bị cắt ngắn
Giữ các tin nhắn đơn lẻ ngắn (dưới 200 ký tự)
Thêm độ trễ nhỏ giữa các lần gửi nhanh
Kiểm tra bộ nhớ heap trống để tránh vấn đề buffer
6. Sketch quá lớn / không đủ không gian
Trong Arduino IDE, đi đến 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 các thư viện Bluetooth
Cài đặt này cung cấp ~3MB bằng cách hy sinh phần OTA (over-the-air update)