Bluetooth Low Energy с ESP32 на Arduino

ESP32 поставляется не только с Wi-Fi, но также с Bluetooth и Bluetooth Low Energy (BLE). Этот пост представляет собой краткое введение в BLE с использованием ESP32. Сначала мы рассмотрим, что такое BLE и для чего он может быть использован, а затем посмотрим на некоторые примеры использования ESP32 с Arduino IDE. Для простого ознакомления мы создадим BLE-сервер на ESP32 и BLE-сканер на ESP32, чтобы найти этот сервер.

Введение в Bluetooth Low Energy

Для быстрого ознакомления с BLE вы можете посмотреть видео ниже или пролистать вниз для письменного объяснения.

Рекомендуемое чтение: узнайте, как использовать ESP32 Bluetooth Classic с Arduino IDE для обмена данными между ESP32 и смартфоном на Android.

Содержание

  1. Что такое Bluetooth Low Energy?

  2. BLE-сервер и клиент

  3. GATT

  4. BLE-сервис

  5. Тестирование BLE-сервера ESP32 с помощью смартфона

Что такое Bluetooth Low Energy?

Bluetooth Low Energy, сокращенно BLE, является энергосберегающим вариантом Bluetooth. Основное применение BLE заключается в передаче небольших объемов данных на короткие расстояния (низкая пропускная способность). В отличие от Bluetooth, который всегда включен, BLE постоянно находится в спящем режиме, за исключением момента, когда устанавливается соединение.

Это делает его потребление энергии очень низким. BLE потребляет примерно в 100 раз меньше энергии, чем Bluetooth (в зависимости от случая использования).

Содержимое файла в Serial Monitor

Кроме того, BLE поддерживает не только точечную связь, но и режим вещания, а также mesh-сети.

Взгляните на таблицу ниже, которая более подробно сравнивает BLE и Bluetooth Classic.

  • Оптимизировано для: Передача данных короткими импульсами

  • Частотный диапазон: 2,4 ГГц ISM диапазон (2,402 – 2,480 ГГц используется)

  • Каналы: 40 каналов с интервалом 2 МГц (3 рекламных / 37 рабочих)

  • Использование каналов: Спектральное уплотнение с частотным скачком (FHSS)

  • Модуляция: GFSK

  • Потребление энергии: ~0,01x до 0,5x от эталона (в зависимости от использования)

  • Скорость передачи данных: - LE 2M PHY: 2 Мбит/с - LE 1M PHY: 1 Мбит/с - LE Coded PHY (S=2): 500 Кбит/с - LE Coded PHY (S=8): 125 Кбит/с

  • Максимальная мощность Tx: - Класс 1: 100 мВт (+20 дБм) - Класс 1.5: 10 мВт (+10 дБм) - Класс 2: 2,5 мВт (+4 дБм) - Класс 3: 1 мВт (0 дБм)

  • Сетевые топологии: - Точка-точка (включая пикоcеть) - Вещание - Сеточная сеть

Благодаря своим свойствам, BLE подходит для приложений, которые нуждаются в периодическом обмене небольшими объемами данных и работают на батарейке типа «монета». Например, BLE широко используется в здравоохранении, фитнесе, отслеживании, маяках, безопасности и домашней автоматизации.

Содержимое файла в Serial Monitor

BLE-сервер и клиент

С Bluetooth Low Energy существует два типа устройств: сервер и клиент. ESP32 может выступать как клиентом, так и сервером.

Сервер рекламирует свое существование, чтобы его могли найти другие устройства, и содержит данные, которые клиент может прочитать. Клиент сканирует близлежащие устройства, и когда находит нужный сервер, устанавливает соединение и слушает входящие данные. Это называется точечной связью.

Содержимое файла в Serial Monitor

Как уже упоминалось, BLE также поддерживает режим вещания и mesh-сети:

  • Режим вещания: сервер передает данные многим подключенным клиентам;

  • Mesh-сеть: все устройства подключены друг к другу, это связь «многие ко многим».

Хотя режим вещания и mesh-сети возможно реализовать, они были разработаны совсем недавно, поэтому в настоящее время существует не так много примеров их использования с ESP32.

GATT

GATT означает Generic Attributes и определяет иерархическую структуру данных, которая доступна подключенным BLE-устройствам. Это означает, что GATT определяет способ, которым два устройства BLE отправляют и получают стандартные сообщения. Понимание этой иерархии важно, так как это упростит использование BLE и написание ваших приложений.

Содержимое файла в Serial Monitor

BLE-сервис

На самом верхнем уровне иерархии находится профиль, который состоит из одного или нескольких сервисов. Обычно устройство BLE содержит более одного сервиса.

Каждый сервис содержит по крайней мере одну характеристику или может ссылаться на другие сервисы. Сервис — это просто набор информации, например, показания сенсоров.

BLE-характеристика

Характеристика всегда принадлежит сервису, и именно в ней содержатся фактические данные в иерархии (значение). Характеристика всегда имеет два атрибута: объявление характеристики (которое предоставляет метаданные о данных) и значение характеристики.

Кроме того, значение характеристики может сопровождаться дескрипторами, которые дополнительно расширяют метаданные, содержащиеся в объявлении характеристики.

Свойства описывают, как можно взаимодействовать со значением характеристики. В основном, они содержат операции и процедуры, которые можно использовать с характеристикой:

-Broadcast - Чтение - Запись без ответа - Запись - Уведомление - Указание - Подписанные записи с аутентификацией - Расширенные свойства

UUID

Каждый сервис, характеристика и дескриптор имеют UUID (универсально уникальный идентификатор). 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, если вы еще этого не сделали.

Установка платы ESP32 в Arduino IDE 2 (Windows, Mac OS X, Linux)

В вашем Arduino IDE вы можете перейти в Файл> Примеры> BLE и исследовать примеры, которые идут с библиотекой BLE.

Содержимое файла в Serial Monitor

Примечание: чтобы увидеть примеры ESP32, вы должны выбрать плату ESP32 в меню Инструменты> Плата.

Для краткого введения в ESP32 с BLE на Arduino IDE мы создадим BLE-сервер на ESP32, а затем BLE-сканер на ESP32, чтобы найти этот сервер. Мы будем использовать и объяснять примеры, которые идут с библиотекой BLE.

Чтобы следовать этому примеру, вам понадобятся две платы разработки ESP32. Мы будем использовать плату ESP32 DOIT DEVKIT V1.

ESP32 BLE-сервер

Чтобы создать BLE-сервер на ESP32, откройте ваш Arduino IDE и выберите Файл> Примеры> BLE и выберите пример Server. Следующий код должен загрузиться:

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

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

void setup() {
  Serial.begin(115200); // Инициализация последовательной связи с скоростью 115200 бод
  Serial.println("Запуск работы с BLE!");

  BLEDevice::init("MyESP32"); // Инициализация BLE устройства с именем "MyESP32"

  BLEServer *pServer = BLEDevice::createServer(); // Создание BLE сервера
  BLEService *pService = pServer->createService(SERVICE_UUID); // Создание BLE сервиса

  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       ); // Создание BLE характеристики с возможностями чтения и записи

  pCharacteristic->setValue("Hello World says Neil"); // Установка значения характеристики

  pService->start(); // Запуск сервиса

  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); // Получение рекламы BLE
  pAdvertising->addServiceUUID(SERVICE_UUID); // Добавление UUID сервиса в рекламу
  pAdvertising->setScanResponse(true); // Установка ответа на сканирование
  pAdvertising->setMinPreferred(0x06);  // Функции для решения проблем с подключением к iPhone
  pAdvertising->setMinPreferred(0x12);

  BLEDevice::startAdvertising(); // Начало рекламы BLE
  Serial.println("Характеристика определена! Теперь вы можете читать её на своем телефоне!");
}

void loop() {
  delay(2000); // Основной код повторяется каждые 2 секунды
}

Как работает код

Давайте быстро рассмотрим, как работает пример кода BLE-сервера.

Он начинается с импорта необходимых библиотек для возможностей BLE.

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

Определение UUID и настройка BLE-сервера

Определение UUID

Сначала необходимо определить UUID для BLE-сервиса и характеристики:

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

Вы можете оставить эти UUID по умолчанию или сгенерировать собственные, например на сайте https://uuidgenerator.net.

Инициализация в setup()

1. Инициализация последовательной связи:

Serial.begin(115200);

2. Инициализация BLE-устройства:

BLEDevice::init("MyESP32");

Вы можете заменить строку "MyESP32" на любое имя BLE-устройства.

3. Создание BLE-сервера:

BLEServer *pServer = BLEDevice::createServer();

4. Создание сервиса с ранее определённым UUID:

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

5. Создание характеристики с возможностями чтения и записи:

BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                       CHARACTERISTIC_UUID,
                                       BLECharacteristic::PROPERTY_READ |
                                       BLECharacteristic::PROPERTY_WRITE
                                     );

6. Установка значения характеристики:

pCharacteristic->setValue("Hello World says Neil");

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

7. Запуск BLE-сервиса и рекламирования:

pService->start();
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->start();

Теперь ваше устройство доступно для обнаружения по BLE.

Дополнительно

  • В этой реализации функция loop() остаётся пустой.

  • В более продвинутых проектах вы можете реализовать обработчики подключения клиентов, использовать уведомления (Notify) или динамически менять значение характеристики.

  • См. пример Notify из библиотеки ESP32 BLE Arduino для расширения логики.

ESP32 BLE-сканер

Создание BLE-сканера на ESP32 очень просто. Для этого потребуется вторая плата ESP32, пока первая работает как BLE-сервер.

В Arduino IDE перейдите: File > Examples > BLE > Scan Загрузится следующий пример скетча:

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>

int scanTime = 5; // время сканирования в секундах
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("Сканирование...");
  BLEDevice::init("");
  pBLEScan = BLEDevice::getScan(); // создать новое сканирование
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setActiveScan(true); // активное сканирование использует больше энергии, но быстрее
  pBLEScan->setInterval(100);
  pBLEScan->setWindow(99);  // должно быть <= interval
}

void loop() {
  BLEScanResults *foundDevices = pBLEScan->start(scanTime, false);
  Serial.print("Найдено устройств: ");
  Serial.println(foundDevices->getCount());
  Serial.println("Сканирование завершено!");
  pBLEScan->clearResults(); // очистка результатов из буфера
  delay(2000);
}

Объяснение

  • Код инициализирует ESP32 как BLE-устройство в режиме сканера.

  • В течение 5 секунд (scanTime) устройство ищет BLE-рекламы поблизости.

  • Все найденные устройства выводятся через Serial.printf.

Примечание

Метод pBLEScan->clearResults() освобождает память, очищая буфер сканирования — это важно при многократном вызове start().

Подключение двух плат

Когда код загружен и обе ESP32 включены:

  • Одна ESP32 с эскизом «BLE_server»;

  • Другая с эскизом «BLE_scan».

Важно

При загрузке кода убедитесь, что к компьютеру подключена только одна ESP32, чтобы избежать ошибок загрузки.

Содержимое файла в Serial Monitor

Перейдите в Серийный монитор с ESP32, выполняющей эскиз «BLE_scan», нажмите кнопку ENABLE на ESP32 (с эскизом «BLE_scan»), чтобы перезагрузить и подождать несколько секунд, пока она сканирует.

Содержимое файла в Serial Monitor

Сканер нашел два устройства: одно из них — это ESP32 (оно имеет имя «MyESP32»), а другое — смарт-часы.

Содержимое файла в Serial Monitor

Тестирование 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». Установите приложение и откройте его.

Содержимое файла в Serial Monitor

Не забудьте зайти в настройки Bluetooth и включить адаптер Bluetooth на вашем смартфоне. Вы также можете сделать его видимым для других устройств, чтобы позже протестировать другие эскизы.

Содержимое файла в Serial Monitor

Когда все готово на вашем смартфоне, и ESP32 работает с эскизом BLE-сервера, в приложении нажмите кнопку сканирования для поиска ближайших устройств. Вы должны найти ESP32 с именем «MyESP32».

Содержимое файла в Serial Monitor

Нажмите кнопку «Connect» (Подключиться).

Как видно на рисунке ниже, ESP32 имеет сервис с UUID, который вы определили ранее. Если нажать на сервис, меню развернется и покажет характеристику с UUID, которую вы также определили.

Содержимое файла в Serial Monitor

Характеристика имеет свойства READ и WRITE, и значение — это то, которое вы ранее определили в эскизе BLE-сервера. Итак, все работает исправно.

Заключение

В этом уроке мы показали вам основные принципы работы с Bluetooth Low Energy и привели несколько примеров использования ESP32. Мы изучили эскиз BLE-сервера и BLE-сканера. Это простые примеры, чтобы начать работу с BLE.