Hướng dẫn ESP32 BLE (Bluetooth Low Energy) cơ bản trên Arduino IDE

ESP32 không chỉ hỗ trợ WiFi mà còn hỗ trợ cả BLE (Bluetooth Low Energy). Dưới đây là bài hướng dẫn cơ bản về ESP32 BLE thông qua Arduino IDE. Cụ thể, mình sẽ hướng dẫn bạn tạo một máy chủ ESP32 và một máy quét ESP32 để tìm và kết nối với máy chủ đó.

Cơ bản về BLE

BLE là viết tắt của Bluetooth Low Energy, giúp truyền tải một lượng nhỏ dữ liệu ở khoảng cách ngắn và tiêu tốn ít điện năng. Chúng có chế độ ngủ nên không làm tiêu thụ nhiều điện năng như Bluetooth Classic.

Bạn có thể tìm hiểu kỹ hơn về BLE qua bài viết sau mà mình đã viết trước đó: BLE là gì? Có nên sử dụng Bluetooth Low Energy không?

Máy chủ BLE và máy khách BLE

Khi kết nối với BLE sẽ có 2 thiết bị chính: máy chủ (Server) và máy khách (Client):

  • Server sẽ phát tín hiệu chứng tỏ nó đang tồn tại để các Client có thể tìm thấy và đọc dữ liệu của Server.
  • Client quét các thiết bị BLE gần nó, thiết lập kết nối và đọc dữ liệu đang được truyền tải.

Kết nối của BLE nói chung và ESP32 BLE nói riêng được gọi là kết nối Point to Point (P2P).

Server BLE và Client BLE giao tiếp theo kết nối Point to Point
Server BLE và Client BLE giao tiếp theo kết nối Point to Point

BLE hỗ trợ 2 chế độ:

  • Broadcast mode: Server truyền thông tin dữ liệu đến các Client đã kết nối
  • Mesh network: Tất cả các thiết bị đều được kết nối

Tuy nhiên, 2 chế độ này chỉ mới phát triển gần đây, nên chúng ta không có quá nhiều ứng dụng ESP32 BLE sử dụng chế độ này.

GATT

GATT là viết tắt của Generic Attributes, chúng giúp xác định cấu trúc dữ liệu phân cấp và hiển thị cho các thiết bị BLE đã được kết nối. Nói cách khách, GATT là giao thức giúp xác định cách mà Server và Client gửi và nhận tin nhắn. 

Giới thiệu về ESP32 và BLE

Trước khi đi vào thực hiện dự án ESP32 BLE, bạn cần cài tiện ích BLE trong Arduino IDE của mình. Tham khảo hướng dẫn: Cách lập trình ESP32 bằng Arduino IDE (Windows, Linux, Mac OS X)

Mạch ESP32 có thể là Server BLE hoặc Client ESP32. Bạn có thể trải nghiệm tính năng BLE trên ESP32 bằng cách cài thư viện ESP32 BLE trong Arduino IDE. Thư viện này sẽ được cài mặc định vào Arduino IDE khi bạn cài tiện ích ESP32.

Để thực hiện, bạn truy cập vào File >> Examples >> ESP32 BLE Arduino và trải nghiệm những chương trình có sẵn xem thử nhé:

Sử dụng các tính năng ESP32 BLE có sẵn
Sử dụng các tính năng ESP32 BLE có sẵn

Và bạn đừng quên chọn đúng board ESP32 trong Arduino IDE, bằng cách chọn Tools >> Board nhe!

Dưới đây, IoTZone sẽ hướng dẫn bạn cách tạo một máy chủ ESP32 và một máy khách ESP32 để quét và kết nối với máy chủ, thông qua BLE nhé!

Tạo máy chủ ESP32 BLE

Chương trình đầy đủ

Chương trình này đã có sẵn trong thư viện, bạn hãy click vào File >> Examples >> ESP32 BLE Arduino >> BLE_server nhé! Chương trình sẽ như sau:

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");

  BLEDevice::init("Long name works now");
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pCharacteristic->setValue("Hello World says Neil");
  pService->start();
  // BLEAdvertising *pAdvertising = pServer->getAdvertising();  // this still is working for backward compatibility
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();
  Serial.println("Characteristic defined! Now you can read it in your phone!");
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(2000);
}
1

Tuy nhiên, để tạo máy chủ ESP32, bạn cần thực hiện thêm một số bước nữa:

  1. Tạo máy chủ BLE
  2. Tạo một dịch vụ BLE
  3. Tạo đặc tính BLE trên dịch vụ
  4. Mô tả BLE và đặc tính
  5. Bắt đầu
  6. Phát tín hiệu để các thiết bị khác tìm thấy nó

Dưới đây, mình sẽ giải thích chi tiết về chương trình:

Giải thích chương trình

Đầu tiên, chúng ta khai báo các thư viện cần thiết:

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

Xác định UUID:

#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

Bạn có thể dùng UUID mặc định hoặc tạo các UUID ngẫu nhiên thông qua trang Web uuidgenerator.net.

Chọn tốc độ truyền 115200:

Serial.begin(115200);

Tạo một ESP32 BLE có tên là MyESP32 hoặc bất kỳ tên nào khác bạn thích:

// Create the BLE Device
BLEDevice::init("MyESP32");

Cấu hình thiết bị BLE này thành máy chủ:

BLEServer *pServer = BLEDevice::createServer();

Tạo một dịch vụ cho máy chủ BLE với UUID đã được cấu hình:

 BLEService *pService = pServer->createService(SERVICE_UUID);

Xác định đặc tính cho các dịch vụ, chuyển thuộc tính của chúng thành đối số (như trong code này là READ và WRITE), như sau:

BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                     CHARACTERISTIC_UUID,
                                     BLECharacteristic::PROPERTY_READ |
                                     BLECharacteristic::PROPERTY_WRITE
                                     );

Đặt giá trị cho đặc tính, như code này thì đang để giá trị nội dung là “Hello World says Neil”.

pCharacteristic->setValue("Hello World says Neil");

Trên thực tế, khi làm các dự án ESP32 BLE, bạn có thể thay đổi giá trị này thành giá trị đọc được từ cảm biến, trạng thái nút nhấn hoặc trạng thái của đèn, quạt,… tùy thích.

Cho phép các thiết bị khác tìm thấy máy chủ ESP32:

BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start()

Máy khách BLE ESP32

Tương tự máy chủ, bạn hãy chọn BLE_scan có sẵn trong thư viện nhé. Đoạn code như sau:

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>

int scanTime = 5; //In seconds
BLEScan* pBLEScan;

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
    void onResult(BLEAdvertisedDevice advertisedDevice) {
      Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
    }
};

void setup() {
  Serial.begin(115200);
  Serial.println("Scanning...");

  BLEDevice::init("");
  pBLEScan = BLEDevice::getScan(); //create new scan
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
  pBLEScan->setInterval(100);
  pBLEScan->setWindow(99);  // less or equal setInterval value
}

void loop() {
  // put your main code here, to run repeatedly:
  BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
  Serial.print("Devices found: ");
  Serial.println(foundDevices.getCount());
  Serial.println("Scan done!");
  pBLEScan->clearResults();   // delete results fromBLEScan buffer to release memory
  delay(2000);
}
1

Chương trình trên giúp máy khách ESP32 có thể quét tìm các thiết bị BLE gần nó và kết nối. Khi nạp chương trình, bạn nên ngắt kết nối của máy chủ ESP32 ra khỏi máy tính để tránh việc nạp chương trình nhầm vào mạch ESP32 khác nhé!

Sau khi nạp chương trình xong, bạn bật 2 mạch ESP32 lên. 1 ESP32 sẽ có sketch “BLE_server”, cái còn lại là “BLE_scan”.

Hướng dẫn ESP32 BLE (Bluetooth Low Energy) cơ bản trên Arduino IDE

Bạn hãy mở Serial Monitor của ESP32, ví dụ như của máy khách (BLE_scan) và nhấn nút ENABLE trên ESP32 để khởi động lại. Chờ vài giây để thiết bị BLE này quét tìm thiết bị xung quanh nó.

Trên Serial Monitor sẽ thông báo rằng đã tìm thấy một thiết bị có tên là MyESP32 (cũng là tên máy chủ lúc nãy mình đặt):

Hướng dẫn ESP32 BLE (Bluetooth Low Energy) cơ bản trên Arduino IDE

Kiểm tra ESP32 BLE Server qua Smartphone

Đa số các điện thoại Smartphone hiện nay đều đã có sẵn khả năng kết nối BLE. Do đó, bạn có thể quét máy chủ ESP32 BLE bằng điện thoại để xem các đặc điểm của chúng.

Để làm được vậy, chúng ta sẽ dùng một app có tên là nRF Connect for Mobile (bạn có thể tải trên Google Play hoặc App Store đều được):

Kiểm tra ESP32 BLE bằng Smart Phone, qua app nRF Connect for Mobile
Kiểm tra ESP32 BLE bằng Smart Phone, qua app nRF Connect for Mobile

Bạn mở ứng dụng, bật Bluetooth Adapter trên điện thoại. Bạn cũng cần hiển thị thiết bị cho các thiết bị khác tìm thấy, để kiểm tra các đoạn sketch khác sau này:

Kiểm tra ESP32 BLE bằng Smart Phone, qua app nRF Connect for Mobile

Tất cả đã sẵn sàng! Trên ứng dụng, bạn hãy nhấn nút SCAN để tìm các thiết bị lân cận. Lúc này, bạn sẽ thấy một thiết bị ESP32 BLE có tên là MyESP32:

Kiểm tra ESP32 BLE bằng Smart Phone, qua app nRF Connect for Mobile

Click vào nút Connect.

Sau đó, bạn sẽ thấy ESP32 có một dịch vụ với UUID mà chúng ta đã xác định trước đó. Nếu bạn click vào dịch vụ, chúng sẽ mở rộng menu và hiển thị các đặc tính trên UUID mà chúng ta đã xác định:

Kiểm tra thuộc tính UUID trên ESP32 BLE
Kiểm tra thuộc tính UUID trên ESP32 BLE

Đặc tính này có các thuộc tính READ và WRITE, và các giá trị của chúng là những giá trị đã xác định trước trong đoạn code chúng ta viết trên Arduino IDE. Vì thế, ta thấy rằng mọi thứ vẫn đang hoạt động ok.

Lời kết

Trong hướng dẫn trên, IoTZone đã hướng dẫn bạn cách làm việc với BLE trên ESP32. Chúng ta có thể sử dụng thư viện ESP32 BLE để trải nghiệm các chương trình có sẵn một cách dễ dàng và nhanh chóng. Dĩ nhiên, trên đây chỉ là một ví dụ đơn giản. Sau này mình sẽ cập nhật thêm các dự án thú vị khác với BLE, chẳng hạn như đọc kết quả dữ liệu thu được từ cảm biến trên một thiết bị khác. Hãy theo dõi blog về ESP32 của IoTZone để đón đọc nhé!

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *