Bluetooth® Low Energy
Bluetooth® Low Energy — это технология беспроводной связи, разработанная для короткодиапазонного обмена данными между электронными устройствами.
Введение
Bluetooth® Low Energy®, нередко называемый Bluetooth® LE, — это технология беспроводной связи, разработанная для короткодиапазонного обмена данными между электронными устройствами. Она появилась как ответ на потребность в энергоэффективной беспроводной связи в самых разных областях применения, особенно там, где потребление энергии является критически важным фактором.
В отличие от своего предшественника — Bluetooth® Classic, оптимизированного для непрерывной передачи данных с относительно высокой скоростью, Bluetooth® LE ориентирован на минимизацию энергопотребления при сохранении связи. Это делает Bluetooth® LE особенно подходящим для приложений, требующих длительного срока службы батареи: фитнес-трекеров, медицинских устройств, интеллектуальных датчиков и устройств Интернета вещей (IoT).
Цель данной статьи — осветить базовые концепции Bluetooth® Low Energy и объяснить, как использовать библиотеку ArduinoBLE для создания Bluetooth® LE-проектов на совместимых платах Arduino.
Поддерживаемые платы с Bluetooth®
Ниже приведён список всех поддерживаемых плат с Bluetooth®:
Важно
Для работы с материалами этой статьи вам понадобится совместимая плата и библиотека ArduinoBLE.
Харальд Блотан (Bluetooth)
Харальд Блотан был датским королём X века, правившим приблизительно с 958 по 986 год н.э., и именно он дал первоначальное вдохновение названию Bluetooth®. Он наиболее известен своей ролью в объединении различных датских племён и своим принятием христианства, что оказало значительное влияние на историю Дании. Его прозвище «Blåtand» (в переводе — Синезуб) считается связанным с его мёртвым или обесцвеченным зубом, который мог казаться синим или чёрным.
Подобно тому, как Харальд Блотан объединил Данию, протокол Bluetooth® был создан для объединения различных устройств и протоколов передачи данных.
Технические характеристики
В следующих разделах рассматриваются основные концепции и технические характеристики Bluetooth® Low Energy.
Частотные диапазоны и дальность
Bluetooth® Low Energy работает в диапазоне ISM (промышленный, научный и медицинский) 2,4 ГГц, который широко используется различными беспроводными технологиями. Этот частотный диапазон разделён на несколько каналов, которые Bluetooth®-устройства используют для обмена данными.
Дальность связи
Дальность соединения Bluetooth® Low Energy может варьироваться в зависимости от ряда факторов, однако в типичных условиях она достигает приблизительно 50 метров (около 164 футов) в условиях прямой видимости. На эту дальность влияют несколько факторов:
Препятствия: физические препятствия — стены, мебель и другие объекты — могут существенно сокращать дальность Bluetooth® LE-соединения. Толстые стены и такие материалы, как бетон, особенно сложно преодолеть для сигналов Bluetooth® LE.
Помехи: как уже упоминалось, диапазон 2,4 ГГц используется совместно многими беспроводными устройствами. Помехи от других устройств, работающих в том же диапазоне частот, могут влиять на дальность и надёжность Bluetooth® LE-соединений.
Конструкция антенны: конструкция и качество антенн как центрального, так и периферийного устройства оказывают влияние на дальность. Устройства с грамотно спроектированными антеннами, как правило, обеспечивают лучшее покрытие.
Ориентация: относительная ориентация центрального и периферийного устройств также влияет на дальность. Прямая видимость между устройствами обычно обеспечивает наилучшую дальность, тогда как препятствия на пути сигнала её уменьшают.
Центральное / периферийное устройство
Bluetooth® Low Energy-устройства работают в разных ролях и режимах, определяющих принципы их взаимодействия.
Центральное устройство (Central Device): центральное устройство в Bluetooth® LE — это, как правило, более мощное устройство с более высокой вычислительной мощностью, большим объёмом памяти или ёмкой батареей. Центральные устройства инициируют соединения с периферийными. Например, ваш смартфон часто является центральным устройством при подключении к Bluetooth® LE-периферии — фитнес-трекерам, интеллектуальным датчикам или плате Arduino.
Периферийное устройство (Peripheral Device): периферийные устройства, как правило, имеют меньше ресурсов по сравнению с центральными (например, плата Arduino в сравнении со смартфоном). Периферийные устройства оповещают о своём присутствии и данных центральные устройства. В отличие от Bluetooth® Classic, Bluetooth® LE-устройства не поддерживают постоянное соединение с центральным устройством, чтобы экономить заряд батареи.
Режим рекламы / режим соединения
Режим рекламы (Advertising Mode): режим рекламы используется прежде всего для того, чтобы сделать Bluetooth® LE периферийное устройство обнаруживаемым другими устройствами, в частности центральными. В режиме рекламы периферийное устройство периодически рассылает рекламные пакеты. Эти пакеты содержат информацию об идентификаторе периферийного устройства, его сервисах и характеристиках. Центральные устройства непрерывно сканируют эти рекламные пакеты, чтобы обнаружить соседние периферийные устройства. В режиме рекламы периферийное устройство не подключено ни к одному центральному устройству. Оно находится в состоянии пониженного энергопотребления, транслируя рекламные пакеты. Оно «ожидает», пока центральное устройство не установит соединение.
Режим соединения (Connection Mode): режим соединения активируется после того, как центральное устройство успешно устанавливает соединение с периферийным. В этом режиме устройства могут обмениваться данными в обоих направлениях. Центральные устройства могут считывать данные с периферийного устройства и записывать данные на него. Режим соединения критически важен для постоянной связи между Bluetooth® LE-устройствами.
Сервисы и характеристики
В Bluetooth® LE сервисы и характеристики — это фундаментальные концепции, организующие и описывающие данные, которыми обмениваются устройства. Рассмотрим эти концепции подробнее:
Сервисы
В Bluetooth® LE сервис можно представить как логическую группировку связанных измерений данных или функций, предоставляемых периферийным устройством. Эти измерения данных могут отражать различные аспекты возможностей устройства или собираемой им информации.
Например, представьте датчик мониторинга погоды. У него может быть сервис «Данные о погоде», охватывающий такие измерения, как температура, влажность и скорость ветра. Другой сервис — «Информация об энергии» — мог бы включать данные об уровне заряда батареи и энергопотреблении.
Характеристики
Внутри каждого сервиса есть характеристики. Характеристики — это отдельные точки данных или атрибуты, предоставляющие конкретную информацию или результаты измерений.
Например, в упомянутом ранее сервисе «Данные о погоде» характеристики могут включать «Температуру», «Влажность» и «Скорость ветра». Эти характеристики непрерывно фиксируют данные и обновляются по мере поступления новых измерений.
Аналогично, сервис «Информация об энергии» может содержать такие характеристики, как «Уровень заряда батареи» и «Потребление энергии».
Универсальные уникальные идентификаторы (UUID)
Для различения сервисов и характеристик Bluetooth® LE опирается на уникальный идентификатор — UUID (Универсальный уникальный идентификатор).
UUID — это 128-битное значение, служащее универсально уникальным именем для сервиса или характеристики. Он действует как метка или идентификатор, с помощью которого центральные устройства находят конкретные сервисы и характеристики и взаимодействуют с ними.
UUID играет ключевую роль в Bluetooth® LE-коммуникации, поскольку гарантирует точное определение центральными устройствами нужных точек данных на периферийных устройствах. Они устраняют неоднозначность и обеспечивают точное получение и управление данными.
На практике понимание сервисов и характеристик необходимо при проектировании Bluetooth® LE-устройств или работе с ними. Сервисы обеспечивают высокоуровневую организацию данных, тогда как характеристики представляют отдельные точки данных внутри этих сервисов. UUID служат ключами, позволяющими центральным устройствам получать доступ к данным периферийных устройств и использовать их.
По мере освоения Bluetooth® LE вы будете встречать различные стандартизированные сервисы и характеристики, применяемые в распространённых приложениях. Эти стандартизированные профили упрощают процесс разработки, облегчая создание Bluetooth® LE-проектов и приложений.
Профили
Bluetooth® LE профили — это заранее определённые наборы сервисов и характеристик, которые стандартизируют взаимодействие Bluetooth® LE-устройств между собой. Эти профили определяют поведение и возможности Bluetooth® LE-устройств, что упрощает беспрепятственную связь между различными устройствами. Рассмотрим Bluetooth® LE профили подробнее:
Определение Bluetooth® LE профилей
Bluetooth® LE профили служат чертежами, определяющими, как данные должны быть организованы и передаваться между устройствами стандартизированным образом. Они задают роли, сервисы и характеристики, которые устройства могут использовать для эффективного обмена данными.
Каждый профиль адаптирован к конкретному сценарию использования или приложению, что гарантирует совместную работу устройств разных производителей при использовании одного и того же профиля.
Распространённые стандартные профили
Bluetooth® LE включает ряд стандартных профилей, упрощающих разработку Bluetooth® LE-приложений. Среди наиболее известных стандартных профилей:
Battery Service (Сервис батареи): сервис Battery Service предоставляет информацию об уровне заряда батареи устройства. Как правило, он включает характеристику Battery Level, которую центральные устройства могут считывать для контроля состояния батареи периферийного устройства, например беспроводной гарнитуры или умных часов.
Heart Rate Service (Сервис частоты сердечных сокращений): сервис Heart Rate Service широко используется в фитнес- и медицинских приложениях. Он включает характеристики, предоставляющие данные о частоте сердечных сокращений в реальном времени, что позволяет центральным устройствам — смартфонам или фитнес-трекерам — контролировать пульс пользователя во время тренировки.
Generic Access Profile (GAP — Профиль общего доступа): хотя GAP сам по себе не является сервисом, он определяет роли и процедуры для обнаружения устройств и установления соединений в Bluetooth® LE. Он играет ключевую роль в обеспечении возможности устройств обнаруживать друг друга и подключаться.
Совет
Подробнее о Bluetooth® профилях можно прочитать здесь.
Создание пользовательских профилей
Помимо стандартных профилей, разработчики могут создавать пользовательские профили, адаптированные к требованиям конкретного приложения. Эти пользовательские профили задают уникальные сервисы и характеристики, соответствующие требованиям конкретного проекта.
Используя Bluetooth® LE профили, разработчики могут задействовать стандартизированные профили для распространённых приложений или создавать пользовательские профили для специализированных проектов. Такой стандартизированный подход упрощает разработку, повышает совместимость и позволяет создавать разнообразные Bluetooth® LE-приложения — от мониторинга здоровья до домашней автоматизации.
По мере дальнейшего освоения Bluetooth® LE вы будете обнаруживать широкий спектр профилей, предназначенных для поддержки различных сценариев использования. Эти профили играют ключевую роль в обеспечении беспрепятственного обмена данными Bluetooth® LE-устройств и предоставления ценной информации центральным устройствам.
Bluetooth® Classic
Bluetooth® Low Energy существенно отличается от Bluetooth® Classic. Bluetooth® Classic работает аналогично последовательному порту или UART (универсальному асинхронному приёмопередатчику), который обычно используется для связи точка-точка.
Ключевые различия:
Энергопотребление
Bluetooth® Classic: разработан для непрерывной передачи данных с относительно высокой скоростью. Вследствие этого он потребляет больше энергии, что делает его менее подходящим для устройств с батарейным питанием и ограниченными источниками энергии.
Bluetooth® Low Energy: оптимизирован для энергоэффективности. Специально разработан для приложений, где потребление энергии является критически важным фактором: фитнес-трекеры, IoT-датчики и носимые устройства. BLE-устройства могут работать в течение длительного времени от небольших батарей или даже от источников энергии на основе харвестинга.
Скорость передачи данных
Bluetooth® Classic: обеспечивает более высокую скорость передачи данных, подходящую для таких задач, как потоковая передача аудио или передача файлов между устройствами.
Bluetooth® Low Energy: жертвует скоростью передачи данных в пользу энергоэффективности. Идеально подходит для приложений, требующих нерегулярной или небольшой порции данных, — например, отправки показаний датчиков или команд управления.
Типы соединений
Bluetooth® Classic: устанавливает непрерывное соединение с относительно высоким энергопотреблением, что делает его подходящим для приложений, требующих обмена данными в реальном времени.
Bluetooth® Low Energy: поддерживает два основных режима — рекламу и соединение. В режиме рекламы BLE-периферийное устройство периодически транслирует своё присутствие, не поддерживая постоянного соединения, что позволяет экономить энергию. При необходимости центральное устройство может установить соединение для обмена данными.
Библиотека ArduinoBLE
Библиотека ArduinoBLE — это основная библиотека, обеспечивающая работу Bluetooth® Low Energy на совместимых платах Arduino. Сначала необходимо скачать и установить библиотеку ArduinoBLE. Инструкции по установке библиотеки смотрите здесь.
В следующем разделе представлен обзор и описание наиболее важных методов библиотеки и способов их использования:
BLE.begin()
Инициализация библиотеки.
Центральное устройство
BLE.scan()
Сканирование периферийных устройств.
BLE.available()
Проверка наличия доступных периферийных устройств.
BLE.scanForUuid("UUID")
Начало сканирования периферийных устройств с конкретным UUID.
bleDevice.address()
Получение адреса периферийного устройства.
bleDevice.localName()
Получение имени периферийного устройства.
bleDevice.advertisedServiceUuid()
Получение UUID рекламируемого сервиса периферийного устройства.
bleDevice.connect()
Подключение к Bluetooth® Low Energy-устройству.
BLE.connected()
Проверка успешности соединения.
bleDevice.discoverAttributes()
Обнаружение атрибутов периферийного устройства.
BLE.stopScan()
Остановка сканирования.
BLE.disconnect()
Отключение от периферийного устройства.
Периферийное устройство
BLE.setLocalName(name)
Задание имени устройству.
BLEService newService(service)
Создание объекта сервиса.
Примечание
Подробнее о стандартных сервисах можно прочитать в документе Assigned Numbers.
BLEUnsignedCharCharacteristic customCharacteristic("UUID_here", Properties_here);
Создание объекта характеристики.
BLE.setAdvertisedService(bleService)
Установка рекламируемого сервиса.
bleService.addCharacteristic(bleCharacteristic)
Добавление характеристик в сервис.
bleCharacteristic.writeValue()
Запись значения характеристики.
BLE.advertise()
Начало рекламы.
Совет
Здесь перечислены лишь некоторые из наиболее важных методов. Полную информацию обо всех методах и их деталях можно найти в справочнике ArduinoBLE.
Примеры
Ниже приведены примеры, показывающие, как передавать данные между двумя платами Arduino и как подключиться к плате Arduino со смартфона, считывая и записывая значения.
Дистанционное управление светодиодом
Этот пример можно использовать с двумя платами Arduino с поддержкой Bluetooth® LE: одна с кнопкой, другая — со светодиодом. При нажатии кнопки будет транслироваться соответствующее значение (высокое/низкое), которое будет получено платой со светодиодом.
Центральное устройство
Этот пример сканирует Bluetooth® Low Energy-периферийные устройства с определённым UUID (в данном случае — другую плату Arduino), подключается к ним и позволяет управлять встроенным светодиодом с помощью кнопки, подключённой к контакту 4.
В схеме ниже используется Arduino UNO R4 WiFi. Вы можете использовать любую из совместимых с Bluetooth® плат из этого списка.
Затем загрузите приведённый ниже код:
#include <ArduinoBLE.h>
// переменные для кнопки
const int buttonPin = 4;
int oldButtonState = LOW;
void setup() {
Serial.begin(9600);
while (!Serial);
// настройка пина кнопки как входа
pinMode(buttonPin, INPUT);
// инициализация оборудования Bluetooth® Low Energy
BLE.begin();
Serial.println("Bluetooth® Low Energy Central - LED control");
// начало сканирования периферийных устройств
BLE.scanForUuid("19b10000-e8f2-537e-4f6c-d104768a1214");
}
void loop() {
// проверка, обнаружено ли периферийное устройство
BLEDevice peripheral = BLE.available();
if (peripheral) {
// обнаружено периферийное устройство — вывод адреса, локального имени и UUID рекламируемого сервиса
Serial.print("Found ");
Serial.print(peripheral.address());
Serial.print(" '");
Serial.print(peripheral.localName());
Serial.print("' ");
Serial.print(peripheral.advertisedServiceUuid());
Serial.println();
if (peripheral.localName() != "LED") {
return;
}
// остановка сканирования
BLE.stopScan();
controlLed(peripheral);
// периферийное устройство отключилось — повторный запуск сканирования
BLE.scanForUuid("19b10000-e8f2-537e-4f6c-d104768a1214");
}
}
void controlLed(BLEDevice peripheral) {
// подключение к периферийному устройству
Serial.println("Connecting ...");
if (peripheral.connect()) {
Serial.println("Connected");
} else {
Serial.println("Failed to connect!");
return;
}
// обнаружение атрибутов периферийного устройства
Serial.println("Discovering attributes ...");
if (peripheral.discoverAttributes()) {
Serial.println("Attributes discovered");
} else {
Serial.println("Attribute discovery failed!");
peripheral.disconnect();
return;
}
// получение характеристики светодиода
BLECharacteristic ledCharacteristic = peripheral.characteristic("19b10001-e8f2-537e-4f6c-d104768a1214");
if (!ledCharacteristic) {
Serial.println("Peripheral does not have LED characteristic!");
peripheral.disconnect();
return;
} else if (!ledCharacteristic.canWrite()) {
Serial.println("Peripheral does not have a writable LED characteristic!");
peripheral.disconnect();
return;
}
while (peripheral.connected()) {
// пока периферийное устройство подключено
// считывание состояния кнопки
int buttonState = digitalRead(buttonPin);
if (oldButtonState != buttonState) {
// состояние кнопки изменилось
oldButtonState = buttonState;
if (buttonState) {
Serial.println("button pressed");
// кнопка нажата — запись 0x01 для включения светодиода
ledCharacteristic.writeValue((byte)0x01);
} else {
Serial.println("button released");
// кнопка отпущена — запись 0x00 для выключения светодиода
ledCharacteristic.writeValue((byte)0x00);
}
}
}
Serial.println("Peripheral disconnected");
}
Периферийное устройство
Этот пример является парным к приведённому выше: он настраивает вашу плату Arduino как периферийное устройство с правильным UUID и транслирует характеристику встроенного светодиода. Поскольку используется только встроенный светодиод, подключать какие-либо компоненты не требуется.
LED_BUILTIN работает на всех платах Arduino.
#include <ArduinoBLE.h>
BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // Bluetooth® Low Energy LED Service
// Bluetooth® Low Energy LED Switch Characteristic — пользовательский 128-битный UUID, доступный для чтения и записи центральным устройством
BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
const int ledPin = LED_BUILTIN; // пин для светодиода
void setup() {
Serial.begin(9600);
while (!Serial);
// установка пина светодиода в режим выхода
pinMode(ledPin, OUTPUT);
// начало инициализации
if (!BLE.begin()) {
Serial.println("starting Bluetooth® Low Energy module failed!");
while (1);
}
// установка рекламируемого локального имени и UUID сервиса:
BLE.setLocalName("LED");
BLE.setAdvertisedService(ledService);
// добавление характеристики в сервис
ledService.addCharacteristic(switchCharacteristic);
// добавление сервиса
BLE.addService(ledService);
// установка начального значения характеристики:
switchCharacteristic.writeValue(0);
// начало рекламы
BLE.advertise();
Serial.println("BLE LED Peripheral");
}
void loop() {
// ожидание подключения Bluetooth® LE центральных устройств:
BLEDevice central = BLE.central();
// если центральное устройство подключилось к периферийному:
if (central) {
Serial.print("Connected to central: ");
// вывод MAC-адреса центрального устройства:
Serial.println(central.address());
// пока центральное устройство остаётся подключённым к периферийному:
while (central.connected()) {
// если удалённое устройство записало в характеристику —
// используем значение для управления светодиодом:
if (switchCharacteristic.written()) {
if (switchCharacteristic.value()) { // любое значение, кроме 0
Serial.println("LED on");
digitalWrite(ledPin, HIGH); // включение светодиода
} else { // значение 0
Serial.println(F("LED off"));
digitalWrite(ledPin, LOW); // выключение светодиода
}
}
}
// при отключении центрального устройства — вывод сообщения:
Serial.print(F("Disconnected from central: "));
Serial.println(central.address());
}
}
Управление платой Arduino со смартфона
Этот пример позволяет управлять встроенным светодиодом на плате Arduino с помощью смартфона. Рекомендуем использовать приложение LightBlue, доступное для Android и iOS, для подключения к плате. После установки загрузите код и следуйте шагам, показанным на изображении ниже.
Шаг 1 — Загрузка кода
#include <ArduinoBLE.h>
BLEService newService("180A"); // создание сервиса
BLEUnsignedCharCharacteristic randomReading("2A58", BLERead | BLENotify); // создание характеристики аналогового значения
BLEByteCharacteristic switchChar("2A57", BLERead | BLEWrite); // создание характеристики светодиода
const int ledPin = 2;
long previousMillis = 0;
void setup() {
Serial.begin(9600); // инициализация последовательного соединения
while (!Serial); // запуск программы при открытии монитора порта
pinMode(LED_BUILTIN, OUTPUT); // инициализация встроенного пина светодиода для индикации подключения
pinMode(ledPin, OUTPUT); // инициализация пина светодиода для индикации подключения
// инициализация библиотеки ArduinoBLE
if (!BLE.begin()) {
Serial.println("starting Bluetooth® Low Energy failed!");
while (1);
}
BLE.setLocalName("<My Board Name>"); // установка имени, которое будет отображаться при сканировании Bluetooth®-устройств
BLE.setAdvertisedService(newService);
newService.addCharacteristic(switchChar); // добавление характеристик в сервис
newService.addCharacteristic(randomReading);
BLE.addService(newService); // добавление сервиса
switchChar.writeValue(0); // установка начального значения характеристик
randomReading.writeValue(0);
BLE.advertise(); // начало рекламы сервиса
Serial.println(" Bluetooth® device active, waiting for connections...");
}
void loop() {
BLEDevice central = BLE.central(); // ожидание Bluetooth® Low Energy центрального устройства
if (central) { // если центральное устройство подключилось к периферийному
Serial.print("Connected to central: ");
Serial.println(central.address()); // вывод BT-адреса центрального устройства
digitalWrite(LED_BUILTIN, HIGH); // включение светодиода для индикации соединения
// проверка уровня заряда батареи каждые 200 мс
// пока центральное устройство подключено:
while (central.connected()) {
long currentMillis = millis();
if (currentMillis - previousMillis >= 200) { // если прошло 200 мс — проверяем уровень заряда
previousMillis = currentMillis;
int randomValue = analogRead(A1);
randomReading.writeValue(randomValue);
if (switchChar.written()) {
if (switchChar.value()) { // любое значение, кроме 0
Serial.println("LED on");
digitalWrite(ledPin, HIGH); // включение светодиода
} else { // значение 0
Serial.println(F("LED off"));
digitalWrite(ledPin, LOW); // выключение светодиода
}
}
}
}
digitalWrite(LED_BUILTIN, LOW); // при отключении центрального устройства — выключение светодиода
Serial.print("Disconnected from central: ");
Serial.println(central.address());
}
}
Шаг 2 — Запуск приложения LightBlue
Итог
В этой статье мы рассмотрели основы Bluetooth® Low Energy и способы его настройки на плате Arduino с помощью библиотеки ArduinoBLE. Мы выделили различия между Bluetooth® LE и Bluetooth® Classic, а также привели примеры, демонстрирующие, как передавать данные между двумя платами Arduino или как использовать смартфон для подключения к плате Arduino.