Bluetooth Low Energy is a slightly different protocol than traditional Bluetooth. BLE “servers” (like the ESP32 reading sensor data) can “notify” clients (like your smartphone) periodically to send them bits of data. Therefore, BLE is more suitable for low-power IoT applications where large amounts of data aren’t required. The BLE devices are detected through a procedure based on broadcasting advertising packets.
Now in order to know which server and client to connect to, both the server and clients use a “service UUID” which describes the overarching service. Inside this service, there can be several “characteristics” which are defined by characteristic UUID’s. Communicating with a BLE device is performed so-called Characteristics in which some characteristics are read-only and others are write-only.
We use two different characteristics, TX and RX under the overarching “service” to send data to and receive data from a client (Android device) via these two channels. The ESP32 (acting as the server) “notifies” the client via the TX characteristic UUID and data is sent to the ESP32 and received via the RX characteristic UUID. However, since there is sending and receiving, TX on the ESP32 is actually RX on the Android app.
Code snippet
So we using the libraries are
#include <BLEDevice.h> #include <BLEUtils.h> #include <BLEServer.h>
Next, we define the service and characteristic UUIDs for both TX and RX (two-way communication).
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" #define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
Similarly, there’s another callback function callback function that handles receiving data being sent from the client(phone). please remember that you should call back, before starting the write operations.
class MyCallbacks: public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { std::string value = pCharacteristic->getValue();
Initialize the ESP32 as a BLE device and set its name.
BLEDevice::init("MyESP32");
Create BLE server
BLEServer *pServer = BLEDevice::createServer(); pCharacteristic->setCallbacks(new MyCallbacks());
Create BLE service using the service UUID.
BLEService *pService = pServer->createService(SERVICE_UUID);
And add characteristics, that will allow Clients to send a message to the Server.
BLECharacteristic *pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE ); pCharacteristic->setCallbacks(new MyCallbacks()); pCharacteristic->setValue("Hello World");
Start BLE service. Starting a service also means that we can create the corresponding characteristics.
pService->start();
And start advertising.
BLEAdvertising *pAdvertising = pServer->getAdvertising(); pAdvertising->start();
So, to create a UUID for your custom services and characteristics you would:
- Use a website such as https://www.uuidgenerator.net to generate a UUID (or multiple UUIDs)
- Make sure it does not conflict with a reserved UUID (avoid any containing XXXXXXXX-0000-1000-8000-00805F9B34FB where XXXXXXXX is any number).