Cách kết nối Bluetooth ESP32 – Hướng dẫn chi tiết kèm code mẫu
ESP32 là một mạch lập trình có hỗ trợ cả WiFi và Bluetooth Classic lẫn BLE. Bạn muốn kết nối Bluetooth ESP32 để phục vụ dự án của mình? Trong bài này, mình sẽ hướng dẫn bạn cách sử dụng Bluetooth Classic trên ESP32 để trao đổi dữ liệu với điện thoại Smartphone, thông qua phần mềm lập trình Arduino IDE.
Cụ thể, chúng ta sẽ gửi kết quả dữ liệu mà cảm biến của ESP32 đọc được đến điện thoại, thông qua ESP32 Serial Bluetooth. Ngoài ra, chúng tôi cũng đã có bài viết khác nói về BLE ESP32 (một loại phương thức kết nối Bluetooth tiết kiệm năng lượng), bạn có thể xem nhé!
Giới thiệu về kết nối Bluetooth Classic
Việc kết nối Bluetooth Classic trên ESP32 sẽ đơn giản hơn BLE ESP32 khá nhiều, chúng sử dụng giao thức và tiêu chuẩn Serial (nối tiếp). Nhìn chung, giao tiếp Serial khá quan trọng khi làm việc với các mạch điều khiển như ESP32, vì đây là giao thức cho phép các thiết bị trao đổi dữ liệu với nhau.
Trên mạch ESP32 có sẵn nhiều cổng UART và các phương thức truyền thông khác, để bạn có thể trao đổi dữ liệu với PC, Smartphone, phục vụ dự án của mình tốt hơn.
Trong bài hướng dẫn về ESP32 Serial Bluetooth này, chúng ta sẽ dùng một đoạn code mẫu có sẵn trong Arduino IDE để hiểu hơn về chúng. Sau đó, chúng ta cùng làm một dự án đơn giản để trao đổi dữ liệu giữa Smartphone (chạy trên Android) và ESP32.
Chuẩn bị
- Mạch ESP32
- Điện thoại Smartphone có hỗ trợ Bluetooth
- Đèn LED 5mm
- Điện trở 330 Ohm
- Cảm biến nhiệt độ DS18B20
- Điện trở 4,7k Ohm
- Dây Jumper
- Breadboard
Cài phần mềm Serial Bluetooth Terminal trên điện thoại
Để kết nối Bluetooth ESP32 với điện thoại, trên Smartphone bạn cần cài sẵn phần mềm “Serial Bluetooth Terminal“. Bạn có thể tải chúng dễ dàng từ CH Play (Google Play):
Demo 1: Dùng code mẫu có sẵn trong Arduino IDE
Cách mở code mẫu có sẵn
Trên Arduino IDE, bạn cần cài tiện ích ESP32 theo hướng dẫn. Sau đó, bạn truy cập vào File >> Examples >> BluetoothSerial >> SerialtoSerialBT, phần mềm sẽ tự load đoạn code mẫu sau:
#include "BluetoothSerial.h" #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it #endif BluetoothSerial SerialBT; void setup() { Serial.begin(115200); SerialBT.begin("ESP32test"); //Bluetooth device name Serial.println("The device started, now you can pair it with bluetooth!"); } void loop() { if (Serial.available()) { SerialBT.write(Serial.read()); } if (SerialBT.available()) { Serial.write(SerialBT.read()); } delay(20); }
Đây là đoạn code giúp khởi tạo kết nối Bluetooth ESP32 với thiết bị khác. Dưới đây là giải thích chi tiết về đoạn code:
Giải thích về code
Khai báo thư viện BluetoothSerial:
#include "BluetoothSerial.h"
Kiểm tra xem ESP32 Serial Bluetooth đã được bật đúng cách chưa:
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
Tạo một SerialBT:
BluetoothSerial SerialBT;
Trong setting(), đầu tiên bạn khởi tạo giao tiếp Serial với tốc độ 115200:
Serial.begin(115200);
Khởi tạo thiết bị Serial Bluetooth và đặt tên cho nó. Mặc định thì tên là ESP32test, bạn có thể đổi tên nó thành bất kỳ tên nào mình muốn:
SerialBT.begin("ESP32test"); //Tên thiết bị Bluetooth
Trong vòng lặp loop(), bạn lập trình để trao đổi dữ liệu qua ESP32 Serial Bluetooth.
Đầu tiên, bạn kiểm tra xem có byte nào được nhận qua ESP32 Serial Bluetooth không, nếu có thì hãy gửi dữ liệu đó đến thiết bị đã kết nối qua Bluetooth Classic:
if (Serial.available()) {
SerialBT.write(Serial.read());
}
Trong đó:
- SerialBT.write(): Gửi dữ liệu thông qua kết nối Bluetooth ESP32
- Serial.read(): Trả về dữ liệu đã nhận trong cổng Serial
Tiếp đó, bạn kiểm tra xem có byte nào để đọc trong cổng ESP32 Serial Bluetooth không, nếu có thì hãy in chúng ra màn hình Serial:
if (SerialBT.available()) {
Serial.write(SerialBT.read());
}
Bây giờ, bạn hãy đi tới phần demo kết quả dự án kết nối Bluetooth ESP32 này, để hiểu hơn về cách hoạt động của code.
Demo cách hoạt động của code mẫu
Upload code trên vào mạch ESP32, sau đó mở Serial Monitor ở tốc độ 115200 và nhấn nút Enable trên ESP32.
Sau vài giây, trên màn hình Serial sẽ hiển thị thông báo rằng thiết bị đã sẵn sàng để kết nối Bluetooth như hình:
Khi đó, bạn mở Smartphone của mình, bật ứng dụng Serial Bluetooth Terminal vừa cài và bật Bluetooth của điện thoại (nhớ cấp quyền truy cập của ứng dụng vào Bluetooth).
Nếu đây là lần đầu bạn kết nối Bluetooth ESP32 với điện thoại, bạn cần ghép nối với thiết bị mới. Khi đó, bạn chọn mục Devices như hình:
Sau đó, bạn cho điện thoại quét và ghép nối với thiết bị mới. Trong danh sách được quét sẽ xuất hiện một thiết bị có tên là ESP32test (tên của ESP32), bạn chọn ghép nối:
Sau đó, bạn quay lại ứng dụng, click vào icon trên cùng bên phải của app để kết nối Bluetooth với ESP32. Khi kết nối thành công, app sẽ thông báo “Connected” như hình:
Bây giờ, để demo việc kết nối Bluetooth ESP32 với điện thoại, bạn hãy nhập bất kỳ dòng chữ nào trong app trên điện thoại, chẳng hạn như “Hello” và nhấn gửi.
Sau đó, bạn sẽ nhận được dòng chữ “Hello” trên màn hình Serial Monitor của Arduino IDE như hình:
Ngược lại, bạn cũng có thể nhập thông tin mình cần trên Serial Monitor bằng thanh trên cùng, chẳng hạn như “Hi. How are you?” sau đó nhấn gửi. Trên app của điện thoại sẽ nhận được thông báo đó:
Demo 2: Trao đổi dữ liệu qua ESP32 Serial Bluetooth
Sau khi biết cách trao đổi dữ liệu qua Bluetooth giữa ESP32 và điện thoại, bạn có thể ứng dụng vào dự án của mình sao cho hữu ích hơn, chẳng hạn như gửi kết quả cảm biến đo được đến điện thoại, hoặc kiểm soát ESP32 thực hiện hành động nào đó khi nhận được một tin nhắn nhất định.
Dưới đây là một ví dụ:
- Gửi nhiệt độ đo được từ DS18B20 cứ định kỳ 10 giây 1 lần đến Smartphone của bạn.
- Dùng Smartphone để gửi yêu cầu bật / tắt đèn LED trên ESP32. Khi ESP32 nhận được thông báo led_on, chân GPIO sẽ bật => bật đèn LED. Ngược lại, khi nhận thông báo led_off thì tắt chân GPIO.
Kết nối phần cứng
Viết chương trình
Để làm việc với cảm biến DS18B20, bạn cần tải 2 thư viện sau (theo link đính kèm):
Sau khi cài thư viện, bạn copy đoạn code sau nạp vào Arduino IDE:
#include "BluetoothSerial.h" #include <OneWire.h> #include <DallasTemperature.h> // Kiểm tra kết nối Bluetooth #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it #endif // Bluetooth Serial object BluetoothSerial SerialBT; // Khai báo chân GPIO của đèn LED const int ledPin = 25; // Khai báo chân GPIO của cảm biến nhiệt độ DS18B20 const int oneWireBus = 32; // Cấu hình oneWire để kết nối với các thiết bị OneWire OneWire oneWire(oneWireBus); // Pass our oneWire reference to Dallas Temperature sensor DallasTemperature sensors(&oneWire); // Xử lý dữ liệu gửi và nhận String message = ""; char incomingChar; String temperatureString = ""; // Timer: auxiliar variables unsigned long previousMillis = 0; // Stores last time temperature was published const long interval = 10000; // interval at which to publish sensor readings void setup() { pinMode(ledPin, OUTPUT); Serial.begin(115200); // Bluetooth device name SerialBT.begin("ESP32"); Serial.println("The device started, now you can pair it with bluetooth!"); } void loop() { unsigned long currentMillis = millis(); // Send temperature readings if (currentMillis - previousMillis >= interval){ previousMillis = currentMillis; sensors.requestTemperatures(); temperatureString = String(sensors.getTempCByIndex(0)) + "C " + String(sensors.getTempFByIndex(0)) + "F"; SerialBT.println(temperatureString); } // Nhận thông tin và gán vào biến message if (SerialBT.available()){ char incomingChar = SerialBT.read(); if (incomingChar != '\n'){ message += String(incomingChar); } else{ message = ""; } Serial.write(incomingChar); } // Kiểm tra tin nhắn nhận được qua kết nối Bluetooth ESP32 và bật tắt đèn LED tương ứng if (message =="led_on"){ digitalWrite(ledPin, HIGH); } else if (message =="led_off"){ digitalWrite(ledPin, LOW); } delay(20); }
Giải thích chương trình
Khai báo các thư viện cần dùng:
#include "BluetoothSerial.h"
#include <OneWire.h>
#include <DallasTemperature.h>
Tạo SerialBT:
BluetoothSerial SerialBT;
Tạo một biến ledPin kết nối với chân GPIO mà bạn cần điều khiển bật / tắt, trong trường hợp này là GPIO 25:
const int ledPin = 25;
Khai báo chân mà cảm biến DS18B20 đang kết nối, trong trường hợp này là GPIO 32:
const int oneWireBus = 32;
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);
Tạo một chuỗi trống là message để lưu các tin đã nhận khi kết nối Bluetooth ESP32:
String message = "";
Tạo biến incomingChar để lưu các ký tự gửi đến qua ESP32 Serial Bluetooth:
char incomingChar;
Chuỗi temperatureString giúp lưu giữ các chỉ số nhiệt độ được truyền qua Bluetooth:
String temperatureString = "";
Tạo các biến hẹn giờ để gửi kết quả đọc sau mỗi giây:
unsigned long previousMillis = 0;
const long interval = 10000;
Trong setting, bạn cấu hình ledPin như một đầu ra:
pinMode(ledPin, OUTPUT);
Tạo ESP32 thành thiết bị Bluetooth có tên là ESP32:
SerialBT.begin("ESP32");
Trong vòng lặp loop(), gửi các tin nhắn nhận được và nhiệt độ, đồng thời thực hiện các hành động tương ứng.
Đoạn code dưới đây sẽ kiểm tra từ lần đọc cuối đã qua 10 giây chưa, nếu rồi thì chúng ta nhận nhiệt độ mới nhất và lưu nó dưới dạng độ C lẫn độ F trong biến temperatureString:
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
sensors.requestTemperatures();
temperatureString = " " + String(sensors.getTempCByIndex(0)) + "C " + String(sensors.getTempFByIndex(0)) + "F";
Gửi giá trị của biến trên qua kết nối Bluetooth ESP32:
SerialBT.println(temperatureString);
Tiếp theo, ta đọc các tin nhắn gửi đến qua ESP32 Serial Bluetooth. Chúng ta sẽ nhận lần lượt mỗi ký tự tại một thời điểm, khi tin nhắn kết thúc, bạn nhận được \N.
Do đó, ta kiểm tra xem trong ESP32 Serial Bluetooth có dữ liệu nhận được không:
if (SerialBT.available()) {
Nếu có, bạn lưu ký tự lại vào biến incomingChar:
char incomingChar = SerialBT.read();
Nếu biến incomingChar có giá trị khác với \N, chung ta sẽ ghép ký tự đó vào tin nhắn:
if (incomingChar!= '\n'){
message += String(incomingChar);
}
Khi đã đọc xong hết các ký tự qua kết nối Bluetooth, chúng ta xóa biến message để chuẩn bị cho việc nhận tin nhắn khác tiếp theo sau đó (nếu có). Nếu không, các tin nhắn sẽ liên tục nối vào nhau:
message = "";
Kiểm tra tin nhắn nhận được, nếu tin nhắn là led_on thì bật chân GPIO, bật đèn LED:
if (message =="led_on"){
digitalWrite(ledPin, HIGH);
}
Nếu tin nhắn là led_off thì tắt đèn LED:
else if (message =="led_off"){
digitalWrite(ledPin, LOW);
}
Demo dự án
Upload code trên vào mạch ESP32, sau đó mở Serial Monitor ở tốc độ 115200 và nhấn nút Enable trên ESP32.
Sau vài giây, trên màn hình Serial sẽ hiển thị thông báo rằng thiết bị đã sẵn sàng để kết nối Bluetooth.
Khi đó, bạn có thể thử viết led_on và led_off lần lượt trên app để điều khiển bật tắt đèn LED:
Trong ứng dụng, bạn có thể liên kết tin nhắn với các nút M1, M2, M3,… mặc định. Chẳng hạn như liên kết led_on với M1, led_off với M2. Khi đó, bạn có thể nhấn vào các nút này để bật tắt đèn LED dễ dàng hơn:
Ngoài ra, trên app của Smartphone cũng hiển thị nhiệt độ dưới dạng độ C và độ F liên tục, cứ mỗi 10 giây thì app sẽ cập nhật nhiệt độ mới.
Lời kết
Trên đây là hướng dẫn chi tiết về cách kết nối Bluetooth ESP32 với Smartphone (Android) để gửi và nhận dữ liệu. Nhìn chung, cách sử dụng Bluetooth Classic sẽ đơn giản hơn nhiều so với BLE trên ESP32. Hy vọng bài viết trên hữu ích với bạn, chúc bạn thành công!
IoTZone – Chuyên cung cấp thiết bị điện tử & tài liệu cho Makers
- Website: https://www.iotzone.vn/
- Fanpage: https://www.facebook.com/Iotzonemaker
- SDT: 0364174499
- Zalo: https://zalo.me/0364174499