ESP32 BLE Server Mengirim Data ke ESP32 BLE Client

T. Ezandi Trinanda
3 min readAug 30, 2021

Pada Bluetooth Low Energy (BLE), pegiriman data secara terus menerus disebut dengan notify. Perangkat ESP32 digunakan sebagai server atau slave BLE untuk mengirim data ke client atau master. Pada program ini client yang juga menggunakan ESP32 akan mengolah data yang dikirim oleh server untuk menghidupkan lampu LED. Untuk kode program client dapat dilihat pada Program ESP32 Menerima Data Untuk Menghidupkan LED Melalui Bluetooth Low Energy.

Kode yang digunakan merupakan modifikasi dari kode example yang tersedia pada library ESP32 BLE Arduino yang ditulis oleh Neil Kolban dan Dariusz Krempa sebagai maintener-nya. Library ini sudah termasuk dalam dalam paket saat menginstal board ESP32 pada Arduino IDE, jika belum library dapat diinstal pada ESP32 BLE Arduino.

Kode ESP32 Client Menerima Data Melalui BLE

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
bool deviceConnected = false;
bool oldDeviceConnected = false;
uint32_t value = 250;
// 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"
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
void setup() {
//Serial.begin(115200);
// Create the BLE Device
BLEDevice::init("ESP32");
// Create the BLE Server
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create a BLE Characteristic
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_NOTIFY
);
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
// Create a BLE Descriptor
pCharacteristic->addDescriptor(new BLE2902());
// Start the service
pService->start();
// Start advertising
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(false);
pAdvertising->setMinPreferred(0x0); // set value to 0x00 to not advertise this parameter
BLEDevice::startAdvertising();
// Serial.println("Waiting a client connection to notify...");
}
void loop() {
// notify/mengirim data ke client
if (deviceConnected) {
pCharacteristic->setValue((uint8_t*)&value, 1);
pCharacteristic->notify();
delay(250); // data pada bluetooth akan menumpuk jika terlalu banyak paket yang dikirim
}
// disconnecting
if (!deviceConnected && oldDeviceConnected) {
delay(500); // give the bluetooth stack the chance to get things ready
pServer->startAdvertising(); // restart advertising
// Serial.println("start advertising");
oldDeviceConnected = deviceConnected;
}
// connecting
if (deviceConnected && !oldDeviceConnected) {
// do stuff here on connecting
oldDeviceConnected = deviceConnected;
}
}

Penjelasan Kode

Untuk menggunakan protokol BLE, mulai dengan memasukkan library yang diperlukan. Jika perangkat digunakan sebagai server, import juga BLEServer.h .

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

Kemudian tentukan UUID yang digunakan. UUID dapat menggunakan UUID yang disediakan pada contoh kode library atau bisa di-generate melalui Online UUID Generator Tool.

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

Inisialisasi nama server dengan nama ESP32.

BLEDevice::init("ESP32");

Membuat server dengan nama yang telah dibuat sebelumnya.

pServer = BLEDevice::createServer();

Fungsi dibawah ini digunakan untuk membuat Service dengan UUID yang telah ditentukan sebelumnya pada server.

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

Kemudian buat dan tentukan properti atau fungsi karakterisitik yang telah ditentukan. Fungsi server yang digunakan kali ini adalah untuk mengirim data ke client secara terus menerus dengan delay 250 ms. Pada BLE fungsi ini dikenal dengan Notify.

pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_NOTIFY
);

Untuk menjalakan fungsi notify, perlu ditambahkan descriptor untuk karakteristiknya. Perangkat server harus mengaktifkan notifikasi karakteristik saat membuat karakteristik. Setelah Notify diaktifkan , server akan memiliki deskriptor dengan handle 0x2902 .

pCharacteristic->addDescriptor(new BLE2902());

Mulai jalankan service agar dapat dideteksi oleh client

pService->start();

Perintah di bawah ini untuk memulai mengirimkan paket adverstising. sementara kode utama dapat ditulis pada bagian loop.

BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(false);
pAdvertising->setMinPreferred(0x0); // set value to 0x00 to not advertise this parameter
BLEDevice::startAdvertising()

Jika ada perangkat yang tersambung, ubah isi karakteristik dengan value dan kemudian notify atau kirim data ke perangkat yang tersambung dengan server. Setelah itu tunggu selama 250 millisecond agar data yang dikirim tidak menumpuk pada client yang menerima data. Jika data yang diterima menumpuk naikkan nilai delay-nya.

if (deviceConnected) {
pCharacteristic->setValue((uint8_t*)&value, 1);
pCharacteristic->notify();
delay(250); // data pada bluetooth akan menumpuk jika terlalu banyak paket yang dikirim

Jika perangkat baru dan perangkat lama teroneksi, tunggu selama 500ms untuk mempersiapkan bluetooth sebelum memluai untuk advertising kembali.

if (!deviceConnected && oldDeviceConnected) {
delay(500); // give the bluetooth stack the chance to get things ready
pServer->startAdvertising(); // restart advertising
// Serial.println("start advertising");
oldDeviceConnected = deviceConnected;
}

Jika perangkat yang tersambung bukan perangkat yang seelumnya tersambung dengan server, maka lakukan proses koneksi terlebih dahulu.

if (deviceConnected && !oldDeviceConnected) {
// do stuff here on connecting
oldDeviceConnected = deviceConnected;
}

--

--