цифровая электроника
вычислительная техника
встраиваемые системы

 

ESP32 в качестве сервера Bluetooth (BLE)

Автор: Mike(admin) от 29-04-2020, 05:55

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


ESP32 в качестве сервера Bluetooth (BLE)

В этой статье мы поговорим об использовании 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.


ESP32 в качестве сервера Bluetooth (BLE)

Чтобы получить готовый пример использования приложения 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


Теги: ESP32, Bluetooth




Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Комментарии:

Оставить комментарий