Bluetooth Low Energy (BLE) работает только когда связь активна и остается включенной. Остальное время модуль BLE проводит в режиме сна. Учитывая это, маячки (Beacon) – отличный вариант использования BLE. Для использования BLE можно задействовать недорогой популярный контроллер ESP32.

В этой статье мы поговорим об использовании ESP32 в качестве сервера BLE.
Если рассматривать BLE телефона, наши умные часы или смартфон сначала идентифицируют его как аудиоустройство. Как правило, он также отображает уровень заряда батареи. Это вопрос понимания того, как конкретный используемый UUID может предоставить подробную информацию об устройстве и организовать иерархию для предоставления уровня заряда батареи с помощью Service UUID. Каждый из параметров может иметь свой собственный UUID, и они называются Characteristic UUID. Важно понимать возможности чтения, записи, уведомления и указания, читая официальную техническую документацию.
Далее приведен пример кода для ESP32 в среде Arduino IDE, который создает сервер BLE, который при получении соединения будет периодически отправлять уведомления. В данном коде хорошо показано, как обрабатываются сервер BLE (BLE Server), служба BLE (BLE Service), характеристика BLE (BLE Characteristic) и дескриптор BLE (BLE Descriptor).
#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 = 0;
// 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;
BLEDevice::startAdvertising();
};
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_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_INDICATE
);
// 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 changed value
if (deviceConnected) {
pCharacteristic->setValue((uint8_t*)&value, 4);
pCharacteristic->notify();
value++;
delay(10); // bluetooth stack will go into congestion, if too many packets are sent, in 6 hours test i was able to go as low as 3ms
}
// 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;
}
}
Приведенный выше код основан на примере Нила Колбана, портирование на Arduino было осуществлено Evandro Copercini и дальнейшее обновление от chegewara.

Чтобы получить готовый пример использования приложения Android и кода ESP32, сначала установите приложение Android под названием «BatON» из Google Play. Тогда вы можете использовать приведенный далее код.
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h> //Library to use BLE as server
#include <BLE2902.h>
bool _BLEClientConnected = false;
#define BatteryService BLEUUID((uint16_t)0x180F)
BLECharacteristic BatteryLevelCharacteristic(BLEUUID((uint16_t)0x2A19), BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
BLEDescriptor BatteryLevelDescriptor(BLEUUID((uint16_t)0x2901));
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
_BLEClientConnected = true;
};
void onDisconnect(BLEServer* pServer) {
_BLEClientConnected = false;
}
};
void InitBLE() {
BLEDevice::init("BLE Battery");
// Create the BLE Server
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pBattery = pServer->createService(BatteryService);
pBattery->addCharacteristic(&BatteryLevelCharacteristic);
BatteryLevelDescriptor.setValue("Percentage 0 - 100");
BatteryLevelCharacteristic.addDescriptor(&BatteryLevelDescriptor);
BatteryLevelCharacteristic.addDescriptor(new BLE2902());
pServer->getAdvertising()->addServiceUUID(BatteryService);
pBattery->start();
// Start advertising
pServer->getAdvertising()->start();
}
void setup() {
Serial.begin(115200);
Serial.println("Battery Level Indicator - BLE");
InitBLE();
}
uint8_t level = 57;
void loop() {
BatteryLevelCharacteristic.setValue(&level, 1);
BatteryLevelCharacteristic.notify();
delay(5000);
level++;
Serial.println(int(level));
if (int(level)==100)
level=0;
}
После загрузки кода откройте приложение Android под названием «BatON». Выполните сопряжение с устройством Bluetooth с именем «BLE Battery». Вы заметите, что «BatON» выдаст вам (ложный) уровень заряда батареи, как и предусмотрено кодом.
К сожалению, проблема со многими проприетарными устройствами BLE заключается в обеспечении безопасности на уровне операционной системы. Например, вы не можете соединить все виды устройств с часами Samsung Galaxy. По этой причине вам понадобятся два ESP32 (один в качестве сервера и один в качестве клиента), чтобы все заработало правильно. Любое универсальное приложение станет похожим на приложение «BatON».
В этой статье была представлена всего лишь идея создания приложения для Android BLE, когда ESP32 используется в качестве сервера BLE, которая может вдохновить на создание действительно полезных и функциональных устройств.
© digitrode.ru