Начало работы с ESP32 Bluetooth Low Energy (BLE) в Arduino IDE
ESP32 поставляется не только с Wi-Fi, но также с Bluetooth и Bluetooth Low Energy (BLE). Эта статья представляет собой краткое введение в BLE с ESP32. Сначала мы рассмотрим, что такое BLE и для чего он может использоваться, а затем рассмотрим несколько примеров с ESP32, используя Arduino IDE. Для простого введения мы создадим BLE-сервер на ESP32 и BLE-сканер на ESP32 для поиска этого сервера.
Обновлено 11 июня 2024
Введение в Bluetooth Low Energy
Для быстрого ознакомления с BLE вы можете посмотреть видео ниже или прокрутить вниз для текстового объяснения.
Рекомендуемое чтение: узнайте, как использовать ESP32 Bluetooth Classic с Arduino IDE для обмена данными между ESP32 и смартфоном Android.
Что такое Bluetooth Low Energy?
Bluetooth Low Energy, сокращенно BLE, является энергосберегающим вариантом Bluetooth. Основное применение BLE – передача небольших объемов данных на короткие расстояния (низкая пропускная способность). В отличие от Bluetooth, который постоянно включен, BLE постоянно находится в спящем режиме, за исключением моментов, когда инициируется соединение.
Это обеспечивает очень низкое энергопотребление. BLE потребляет примерно в 100 раз меньше энергии, чем Bluetooth (в зависимости от сценария использования).
Кроме того, BLE поддерживает не только связь «точка-точка», но также режим широковещания и ячеистую сеть (mesh network).
Взгляните на таблицу ниже, которая более подробно сравнивает BLE и Bluetooth Classic.
Благодаря своим свойствам BLE подходит для приложений, которым необходимо периодически обмениваться небольшими объемами данных, работая от батарейки типа «таблетка». Например, BLE широко используется в здравоохранении, фитнесе, отслеживании, маяках, безопасности и индустрии домашней автоматизации.
BLE-сервер и клиент
В Bluetooth Low Energy существует два типа устройств: сервер и клиент. ESP32 может выступать как в роли клиента, так и в роли сервера.
Сервер объявляет о своем существовании, чтобы его могли найти другие устройства, и содержит данные, которые клиент может прочитать. Клиент сканирует ближайшие устройства, и когда находит нужный сервер, устанавливает соединение и прослушивает входящие данные. Это называется связью «точка-точка».
Как упоминалось ранее, BLE также поддерживает режим широковещания и ячеистую сеть:
Режим широковещания: сервер передает данные множеству подключенных клиентов;
Ячеистая сеть (Mesh network): все устройства соединены между собой, это связь «многие ко многим».
Несмотря на то, что настройки широковещания и ячеистой сети возможны для реализации, они были разработаны совсем недавно, поэтому на данный момент для ESP32 не так много реализованных примеров.
GATT
GATT расшифровывается как Generic Attributes (общие атрибуты) и определяет иерархическую структуру данных, которая доступна подключенным BLE-устройствам. Это означает, что GATT определяет способ, которым два BLE-устройства отправляют и получают стандартные сообщения. Понимание этой иерархии важно, поскольку оно облегчит использование BLE и написание ваших приложений.
BLE-сервис
Верхний уровень иерархии – это профиль, который состоит из одного или нескольких сервисов. Обычно BLE-устройство содержит более одного сервиса.
Каждый сервис содержит как минимум одну характеристику или может также ссылаться на другие сервисы. Сервис – это просто набор информации, например, показания датчиков.
Существуют предопределенные сервисы для различных типов данных, определенных SIG (Bluetooth Special Interest Group), таких как: уровень заряда батареи, кровяное давление, частота сердечных сокращений, весы и т.д. Вы можете посмотреть другие определенные сервисы здесь.
BLE-характеристика
Характеристика всегда принадлежит сервису, и именно в ней содержатся фактические данные в иерархии (значение). Характеристика всегда имеет два атрибута: объявление характеристики (которое предоставляет метаданные о данных) и значение характеристики.
Кроме того, за значением характеристики могут следовать дескрипторы, которые дополнительно расширяют метаданные, содержащиеся в объявлении характеристики.
Свойства описывают, как можно взаимодействовать со значением характеристики. По сути, они содержат операции и процедуры, которые можно использовать с характеристикой:
Broadcast (Широковещание)
Read (Чтение)
Write without response (Запись без ответа)
Write (Запись)
Notify (Уведомление)
Indicate (Индикация)
Authenticated Signed Writes (Аутентифицированная подписанная запись)
Extended Properties (Расширенные свойства)
UUID
Каждый сервис, характеристика и дескриптор имеют UUID (Universally Unique Identifier – универсальный уникальный идентификатор). UUID – это уникальное 128-битное (16 байт) число. Например:
55072829-bc9e-4c53-938a-74a6d4c78776
Существуют сокращенные UUID для всех типов, сервисов и профилей, указанных в SIG (Bluetooth Special Interest Group).
Но если вашему приложению нужен собственный UUID, вы можете сгенерировать его с помощью этого веб-сайта генератора UUID.
В итоге UUID используется для уникальной идентификации информации. Например, он может идентифицировать конкретный сервис, предоставляемый Bluetooth-устройством.
BLE с ESP32
ESP32 может выступать в роли BLE-сервера или BLE-клиента. Существует несколько примеров BLE для ESP32 в библиотеке ESP32 BLE для Arduino IDE. Эта библиотека устанавливается по умолчанию при установке ESP32 в Arduino IDE.
Примечание: вам необходимо установить дополнение ESP32 в Arduino IDE. Следуйте следующему руководству для подготовки Arduino IDE к работе с ESP32, если вы этого еще не сделали.
В Arduino IDE вы можете перейти в File > Examples > BLE и изучить примеры, поставляемые с библиотекой BLE.
Примечание: чтобы увидеть примеры ESP32, необходимо выбрать плату ESP32 в Tools > Board.
Для краткого введения в ESP32 с BLE в Arduino IDE мы создадим BLE-сервер на ESP32, а затем BLE-сканер на ESP32 для поиска этого сервера. Мы будем использовать и объяснять примеры, поставляемые с библиотекой BLE.
Для выполнения этого примера вам потребуются две платы разработки ESP32. Мы будем использовать ESP32 DOIT DEVKIT V1 Board.
BLE-сервер ESP32
Чтобы создать BLE-сервер на ESP32, откройте Arduino IDE и перейдите в File > Examples > BLE и выберите пример Server. Должен загрузиться следующий код:
/*
Complete Getting Started Guide: https://RandomNerdTutorials.com/esp32-bluetooth-low-energy-ble-arduino-ide/
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleServer.cpp
Ported to Arduino ESP32 by Evandro Copercini
*/
#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("MyESP32");
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);
}
Для создания BLE-сервера код должен выполнить следующие шаги:
Создать BLE-сервер. В данном случае ESP32 выступает в роли BLE-сервера.
Создать BLE-сервис.
Создать BLE-характеристику для сервиса.
Создать BLE-дескриптор для характеристики.
Запустить сервис.
Начать рекламирование (advertising), чтобы устройство могло быть найдено другими устройствами.
Как работает код
Давайте кратко рассмотрим, как работает код примера BLE-сервера.
Он начинается с импорта необходимых библиотек для работы с BLE.
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
Затем необходимо определить UUID для сервиса и характеристики.
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
Вы можете оставить UUID по умолчанию или перейти на uuidgenerator.net для создания случайных UUID для ваших сервисов и характеристик.
В setup() инициализируется последовательная связь на скорости 115200 бод.
Serial.begin(115200);
Затем создается BLE-устройство с именем «MyESP32». Вы можете изменить это имя на любое другое.
// Create the BLE Device
BLEDevice::init("MyESP32");
В следующей строке BLE-устройство настраивается как сервер.
BLEServer *pServer = BLEDevice::createServer();
После этого создается сервис для BLE-сервера с ранее определенным UUID.
BLEService *pService = pServer->createService(SERVICE_UUID);
Затем задается характеристика для этого сервиса. Как видите, здесь также используется ранее определенный UUID, и в качестве аргументов передаются свойства характеристики. В данном случае это: READ (чтение) и WRITE (запись).
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
После создания характеристики можно установить её значение с помощью метода setValue().
pCharacteristic->setValue("Hello World says Neil");
В данном случае мы устанавливаем значение в текст «Hello World says Neil». Вы можете изменить этот текст на любой другой. В будущих проектах этот текст может быть показанием датчика или состоянием лампы, например.
Наконец, можно запустить сервис и рекламирование, чтобы другие BLE-устройства могли сканировать и найти это BLE-устройство.
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
Это лишь простой пример создания BLE-сервера. В этом коде ничего не происходит в loop(), но вы можете добавить обработку подключения нового клиента (ознакомьтесь с примером Notify для получения рекомендаций).
BLE-сканер ESP32
Создать BLE-сканер на ESP32 очень просто. Возьмите другой ESP32 (пока на первом работает скетч BLE-сервера). В Arduino IDE перейдите в File > Examples > BLE и выберите пример Scan. Должен загрузиться следующий код.
/*
Complete Getting Started Guide: https://RandomNerdTutorials.com/esp32-bluetooth-low-energy-ble-arduino-ide/
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp
Ported to Arduino ESP32 by Evandro Copercini
*/
#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);
}
Этот код инициализирует ESP32 как BLE-устройство и сканирует ближайшие устройства. Загрузите этот код на ваш ESP32. Возможно, стоит временно отключить другой ESP32 от компьютера, чтобы убедиться, что вы загружаете код на правильную плату ESP32.
После загрузки кода обе платы ESP32 должны быть включены:
Один ESP32 со скетчем «BLE_server»;
Другой ESP32 со скетчем «BLE_scan».
Откройте монитор порта с ESP32, на котором запущен пример «BLE_scan», нажмите кнопку ENABLE на ESP32 (со скетчем «BLE_scan») для перезагрузки и подождите несколько секунд, пока выполняется сканирование.
Сканер нашел два устройства: одно из них – ESP32 (с именем «MyESP32»), а другое – умные часы.
Тестирование BLE-сервера ESP32 с помощью смартфона
Большинство современных смартфонов должны поддерживать BLE. Автор использовал OnePlus, но большинство смартфонов также должны работать.
Вы можете просканировать ваш BLE-сервер ESP32 с помощью смартфона и просмотреть его сервисы и характеристики. Для этого мы будем использовать бесплатное приложение nRF Connect for Mobile от Nordic, которое работает на Android (Google Play Store) и iOS (App Store).
Перейдите в Google Play Store или App Store и найдите «nRF Connect for Mobile». Установите приложение и откройте его.
Не забудьте зайти в настройки Bluetooth и включить адаптер Bluetooth на вашем смартфоне. Вы также можете сделать его видимым для других устройств, чтобы позже протестировать другие скетчи.
Когда все готово на вашем смартфоне и ESP32 запущен со скетчем BLE-сервера, в приложении нажмите кнопку сканирования для поиска ближайших устройств. Вы должны найти ESP32 с именем «MyESP32».
Нажмите кнопку «Connect».
Как видно на рисунке ниже, ESP32 имеет сервис с UUID, который вы определили ранее. Если вы нажмете на сервис, меню развернется и покажет характеристику с UUID, который вы также определили.
Характеристика имеет свойства READ и WRITE, а значение – то, которое вы ранее задали в скетче BLE-сервера. Итак, все работает правильно.
Заключение
В этом руководстве мы показали вам основные принципы Bluetooth Low Energy и продемонстрировали несколько примеров с ESP32. Мы рассмотрели скетч BLE-сервера и скетч BLE-сканера. Это простые примеры для начала работы с BLE.
Идея заключается в использовании BLE для отправки или получения показаний датчиков от других устройств.
Другие руководства, связанные с Bluetooth, которые могут вам понравиться:
ESP32 с Bluetooth и Bluetooth Low Energy: полное руководство
ESP32 Wi-Fi Provisioning через BLE (Bluetooth Low Energy) – Arduino IDE
Источник: Getting Started with ESP32 Bluetooth Low Energy (BLE) on Arduino IDE