РадиоКот :: Разработка Bluetooth приложений на модулях фирмы Silicon Labs. Часть IV.
Например TDA7294

РадиоКот >Статьи >

Теги статьи: Добавить тег

Разработка Bluetooth приложений на модулях фирмы Silicon Labs. Часть IV.

Автор: Сергей Безруков (aka Ser60)
Опубликовано 29.06.2021
Создано при помощи КотоРед.

Эта часть цикла статей посвящена четырём приложениям, которые я время от времени использую в своей практике. Исходные коды всех проектов содержатся в прилагаемом к статье архиве. Хотя описание первого и последнего из них находится на сайте Silicon Labs, они разработаны под старой версией Simplicity Studio v4 и под старые API, и под современной версией 5 эти программы даже не скомпилируются. Более того, целый ряд современных Bluetooth модулей фирмы не поддерживаются старой версией системы, и возврата к ней нет, поскольку она более не развивается. Все проекты в этой статье разработаны в Simplicity Studio v5 под демо-плату BGM22 Explorer Kit (BGM220-EK4314A) и с моими (надеюсь) улучшениями и комментариями. Помимо низкой стоимости платы, из-за того, что она не перегружена излишними деталями, созданные на ней проекты очень удобно непосредственно переносить на Bluetooth модули фирмы семейства BG22.

Начнём с проектов связи Bluetooth приложений с программами на компьютере или смартфоне. Хотя для последних имеются специальные средства разработки как для iOS, так и для Android, в некоторых случаях требуется связать устройства с уже имеющимися приложениями, разработанные под беспроводную мышь или клавиатуру. Особенно это касается компьютеров. Для них и проводных клавиатур/мышей и прочих устройств для интерактива с пользователем имеется специальный USB класс Human Interface Device (HID). Поскольку наблюдается современная тенденция перехода на беспроводные устройства интерактива с пользователями, группой Bluetooth SIG разработан специальный Bluetooth GATT профиль для передачи HID данных, который называется “HID over GATT”. При этом на стороне компьютера не нужно устанавливать никаких специальных драйверов, поскольку драйверы для HID входят в состав любой современной ОС. Следует лишь позаботиться о наличии в компьютере адаптера Bluetooth, способного работать с версией Bluetooth не ниже 4, т.е. с Bluetooth LE, а не только с Bluetooth Classic (BR/EDR). Во многие современные компьютеры, в особенности лэптопы, такие адаптеры уже встроены на фабрике. Однако, если это не так, как это было в случае моего старого лэптопа, то всегда можно приобрести недорогой внешний Bluetooth USB адаптер наподобие показанного ниже.

При этом необязательно, чтобы адаптер поддерживал версию Bluetooth 5. Однако, при такой поддержке появляется возможность задействовать новые классы физических уровней Bluetooth радио (PHY), и, в частности, существенно увеличить дальность связи по сравнению с Bluetooth 4, правда за счёт снижения скорости передачи. Именно так мы и поступим в первом проекте. Сразу оговорюсь, что Bluetooth адаптеры смартфонов и компьютеров (а также USB адаптеры) не предназначены для «сверхдальней» связи и имеют гораздо худшие характеристики по чувствительности и выходной мощности по сравнению с отдельными Bluetooth модулями. Однако, даже с нашим модулем при мощности передатчика +8 dBm удалось становить устойчивую связь с современным Samsung смартфоном, поддерживающим режим “125K Coded PHY (S=8)”, на расстоянии в 200 м. на открытой местности и в условиях прямой видимости.


BLE HID клавиатура

Этот проект создан на основе опубликованного на сайте Silicon Labs проекта [2]. Отличие состоит в адаптации его под современную версию Simplicity Studio и под версию Bluetooth 5.х, и в организации двусторонней связи между устройствами. Разработка любого Bluetooth приложения на модуле начинается с конфигурирования Bluetooth профиля. При этом устройству на другом конце следует указать как воспринимать наше устройство. Для этого служат стандартизированные Bluetooth SIG коды, часть которых, имеющих отношение к HID устройствам, показана ниже.

Этот код (в нашем случае клавиатуры 961 = 0х03C1) в порядке байтов от младшего к старшему следует указать в характеристике Appearance сервиса Generic Access, который должен присутствовать в профиле любого Bluetooth устройства. В характеристику Device Name этого сервиса поместим название нашего устройства “SL Keyboard” (SL = Silicon Labs), под которым оно будет видно компьютеру. Как следует из профиля, помимо Generic Access сервиса в нашем устройстве имеются ещё 3 стандартных SIG сервиса: Human Interface Device, Battery Service, и Device Information. В первом из них содержится информация о дескрипторах контрольных точек, передаваемых USB драйверу, а в последнем (среди всего прочего) информация о VID/PID нашего устройства, что поможет компьютеру отличить его от других HID устройств, как будет показано ниже. Сервис Battery Service также должен присутствовать в любом BLE HID устройстве, но в нашем проекте он не задействован для простоты и состояние батареи не мониторится. Обсуждение многих аббревиатур и терминов связанных с USB выходит за рамки настоящей статьи, но массу информации по ним легко найти в сети.

Полный Bluetooth GATT профиль нашего устройства представлен ниже, и здесь я коснусь только некоторых его характеристик, важных для понимания кода. Клавиатура, с точки зрения компьютера, представляет собой устройство, поддерживающее двунаправленную связь. Клавиатура передаёт скан-коды нажатых клавиш как массив длиной 8 байт соответствующий нажатию до 6 клавиш одновременно (подробнее см. в [1]), из которых в нашем случае используется только один элемент в этом массиве под индексом 2. Принимаемая клавиатурой информация состоит из одного байта, показывающего состояние лампочек NumLock/CapsLock/ScrollLock на ней. Если у компьютера уже имеется (проводная) штатная клавиатура, при подключении к нему Bluetooth клавиатуры будут восприниматься коды клавиш с обоих. Нажатие, скажем, клавиши CapsLock на штатной клавиатуре приводит к загоранию соответствующей лампочки на ней и дублированию этого сигнала на внешнюю Bluetooth клавиатуру (многие экранные клавиатуры на смартфонах и планшетах, однако, не дублируют сигналы для лампочек на внешнюю клавиатуру). Данные посылаемые и принимаемые клавиатурой передаются в характеристиках профиля Report In и Report Out, соответственно. Направление передачи данных In/Out имеется в виду относительно компьютера. Обе эти характеристики имеют одинаковый UUID и их имена могут быть любыми, но назначение их описано в дескрипторе Report Reference, значение которого должно быть 0х0001 и 0х0002, соответственно. Для характеристики Report In, согласно стандарту, должны быть разрешены нотификации.

Следует обратить особое внимание на характеристику Report Map, в которой закодирован дескриптор HID устройства клавиатуры, необходимый для работы стандартного драйвера клавиатуры на компьютере. Дескриптор содержит информацию о количестве конечных точек (endpoints в терминологии USB), объёме данных, пересылаемых через них, и некоторые сведения об их структуре. В нашем проекте я добавил в GATT профиль характеристику Report Out и, соответственно, дополнил дескриптор из [2] информацией о контрольной точке типа OUTPUT. Значения байтов из колонки Bytes следующей таблицы перенесены в строку значения этой характеристики в направлении слева направо и сверху вниз.

Наконец, важно определиться с характеристикой PnP ID сервиса Device Information длиной в 7 байт, поля которой я разделил пробелами: 02 10c4 0001 0001. Первые 2 поля определяют тип и значение VID (Vendor ID), а следующие 2 – PID (Product ID) и версию устройства. Байты последних 3-х полей должны быть записаны в порядке от младшего к старшему, т.о. для нашего устройства VID=0xC410 (Silicon Labs) и PID=0x0100.

Обратимся теперь к функционалу и коду программы. Поскольку наша демо-плата имеет всего одну кнопку (исключая кнопку Reset), приложение посылает скан код лишь одной клавиши (как нотификацию) при каждом нажатии на кнопку. Если кнопку нажать и не отпускать, то дополнительные нотификации посылаться не будут, однако HID драйвер компьютера включит функцию автоповтора нажатия клавиши. Для прекращения автоповтора драйверу следует сказать, что кнопка отпущена, послав нотификацию со скан-кодом равным нулю (подробнее см. в [1]). Таким образом, в программе следует сконфигурировать пин порта кнопки на прерывания по обоим фронтам. Отмечу, что драйверу HID следует посылать не ASCII коды клавиш, а специальные scan codes. В нашем приложении они внесены в таблицу reducedKeyArray, соответственно для 26 строчных латинских букв a – z. При каждом нажатии кнопки выбирается одна буква из этой таблицы по индексу counter, после чего индекс увеличивается на 1 по модулю 26.

Далее, замечу, что BLE HID драйверы компьютеров предполагают спаривание с соответствующими устройствами, хотя алгоритм спаривания при этом не регламентирован и допускается любым. В нашем случае применён простейший алгоритм спаривания Just Works (см. подробнее в моей статье [3]), при котором не производится идентификация устройств, а просто производится обмен сгенерированных ключей шифрования данных, которые записываются в энергонезависимой памяти модуля. Выбор алгоритма спаривания в коде производится конфигурированием Bluetooth SM (Security Manager) с опцией sm_io_capability_noinputnoputput (строка 76 кода в файле app.c проекта). При этом наше приложение запоминает лишь одно спаривание, и при установке нового спаривания предыдущее автоматически удаляется. Поэтому после спаривания нашего устройства с одним компьютером, для спаривания его с другим (или нового спаривания с прежним после удаления его из списка устройств) следует предпринять попытку спаривания как минимум 2 раза. Первая попытка при этом будет неуспешной из-за использования модулем старых шифров для связи, а вторая после стирания их должна закончиться успехом.

Наконец, для обеспечения как можно более широкой совместимости с Bluetooth адаптерами компьютеров, после инициализации модуль начинает передавать оповещения (advertisements) в формате Bluetooth 4, используя PHY с битрейтом 1 Мbps. После установки соединения с компьютером модуль запрашивает о возможности перейти на один из PHY спецификации Bluetooth 5, указывая при этом предпочтениe типу “125K Coded PHY (S=8)”, при котором достигается наибольшая дальность связи. Таким образом, в результате переговоров между модулем и компьютером производится выбор поддерживаемого обеими сторонами типа PHY и Bluetooth стек модуля генерирует событие sl_bt_evt_connection_phy_status, в обработчике которого я просто выдаю в окно терминала результирующий тип PHY (терминал компьютера должен быть настроен с опциями 115200 8N1).

При первоначальном спаривании компьютера с модулем на Windows-10 компьютере следует открыть окно Bluetooth and Other Devices, кликнуть на Add Bluetooth or Other Device, и выбрать наше устройство.

 

Затем следует согласиться на спаривание, после чего наше устройство появится в списке Bluetooth устройств как клавиатура и будет готово к работе.

 

При кликании мышкой в окно приложения, способного принимать коды клавиш (например, текстовый редактор или строка URL в браузере), и нажатия кнопки на демо-плате увидим новые символы в окне приложения. Для демонстрации передачи данных в обратном направлении (от компьютера к Bluetooth модулю), каждое нажатие клавиши NumLock на штатной (проводной) клавиатуре приведёт к смене состояния светодиода LED0 на демо-плате. В окне терминальной программы на компьютере показывается принятая версия PHY и состояние кнопки при каждом её нажатии и отпускании.

 

BLE HID мышь

Разработка Bluetooth приложения для HID мыши аналогична таковой для клавиатуры. Отметим, что (стандартная) мышь предполагает коммуникацию с компьютером лишь в одном направлении, поэтому следует оставить в профиле только Input Report длиной в 3 байта. В первом байте передаётся состояние кнопок мыши, а во втором и третьем – относительные перемещения курсора мыши на экране в пикселях по осям Х и Y, соответственно, в диапазоне -127…127. При этом начало координат находится в левом верхнем углу экрана с осью Y направленной вниз. Помимо этого, следует скорректировать значение характеристики Appearance как 0xc203, чтобы наше устройство воспринималось компьютером как мышь, в соответствии с вышеизложенным. И последнее, и главное – необходимо скорректировать дескриптор в характеристике Report Map как показано ниже. Все надлежащие изменения уже сделаны в прилагаемом проекте BLE_Mouse.

Программа МК для мыши также мало отличается от клавиатуры. Основное отличие в использовании светодиода на плате, который сконфигурирован на индикацию соединения с компьютером. Кнопка на демо-плате в этом проекте не задействована. Для демонстрации работы «мыши» введён таймер, определяющий скорость передвижения курсора мыши по экрану. При этом курсор движется по траектории квадрата со стороной 100×100 пикселей. Интеграция нашей мыши в систему компьютера также подразумевает спаривание как описано выше. В случае успеха мышь появляется в списке устройств под именем SL Mouse.

 

Работа с BLE HID модулем из программы компьютера

Для этого имеется несколько возможностей, я опишу лишь одну из них, основанную на кроссплатформенной библиотеке Signal11. В файле README.txt на Github по ссылке выше имеется достаточно подробная инструкция по компиляции этой библиотеки для разных платформ. Я использую её в проекте под Visual Studio 2019 (free Community Edition) и Windows-10. На всякий случай скомпилированная библиотека hidapi.dll находится в приложении. Продемонстрируем работу этой библиотеки на примере соединения с BLE HID устройством, а также принятием данных из него и отсылкой данных в него. Мы не собирается здесь взаимодействовать со стандартной BLE HID клавиатурой или мышью, т.к. соответствующие драйверы компьютера уже дефолтно соединены с ними и подсоединиться к ним из стороннего устройства так просто не удастся. Вместо этого создадим специальное двунаправленное Bluetooth HID (Appearance = 960 = 0x03C0) устройство с двумя конечными точками, предназначенными для передачи пакетов длиной до 8 байт в каждом из направлений. Полный код проекта содержится в файле BLE_HID_TEST.sls в приложении. Прежде всего, нам потребуется новый дескриптор, все 27 байтов которого следует прописать в характеристике Report Map.

После загрузки кода в Bluetooth модуль и спаривания его с компьютером, наше устройство отобразится в нём под именем BLE HID.

В самом приложении тестовый массив длины 8 (0х01 0х02 0хAA 0xBB 0xCC 0xDD 0xEE 0xFF) отправляется на компьютер по нажатию кнопки на демо-плате, а приложение на компьютере в свою очередь после приёма этих байтов отправит на наше устройство другой тестовый массив длины 8 (0х01 0х02 0х03 0х04 0х05 0х06 0х07 0х08). Принятые данные программой на компьютере отображаются в окне консоли Visual Studio. В верхней части окна появятся все подключённые к компьютеру BLE HID устройства, в числе которых будет и наше с VID/PID = 0xc410/0x0001 (последнее на скриншоте ниже).

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

Программа для компьютера создана на основе тестового кода hidtest.cpp, находящегося в папке hidtest на Github по ссылке выше, его исходный код находится в прилагаемом архиве. Сканирование Bluetooth HID устройств производится вызовом функции hid_enumerate() в строке 33. Возвращаемый ей список обнаруженных BLE HID устройств печатается в экране консоли.

Для соединения с нашим Bluetooth устройством по VID/PID служит функция hid_open() библиотеки signal11 (строка 52). В случае успешного соединения для ожидания приёма данных используется блокирующая функция hid_read() с последующей выдачей принятых данных в окно консоли (строки 65 – 69). Режим приёма данных (блокирующий с ожиданием, или неблокирующий без ожидания) регламентируется строкой 60 кода.

Наконец, для передачи данных на наше Bluetooth устройство используется библиотечная функция hid_write() в строке 81. Для отсылки массива данных в первом элементе его следует указать номер конечной точки (1 для Report Out). Несмотря на то, что мы отсылаем 9 байтов данных на наше устройство, им будет принято лишь 8 первых в соответствии с конфигурацией профиля.

 

Передача данных последовательного порта через BLE

Этот проект, а-ля беспроводный UART, создан на основе прототипа [4], опубликованного на сайте Silicon Labs. Мой вклад в этот проект минимален и сводится к переводу его под демо-плату выше, современные API, и Simplicity Studio v5. Ранее я уже рассказывал здесь как организовать беспроводный UART на модулях AMS001. Однако, сейчас они уже не актуальны и после поглощения Silicon Labs фирмы Zentri на их смену были выпущены модули семейства BGX13/22, специально предназначенные для подобных приложений. Тем не менее, исходя из многочисленных приложений беспроводного UART, во многих случаях представляет интерес как дополнить имеющийся проект таким функционалом. Этого можно добиться добавлением к профилю Bluetooth устройства реализации стандартного SIG профиля SPP (Serial Port Profile). Проект последовательного порта включает два Bluetooth проекта – SPP Server и SPP Client. Начнём с первого из них.

Одна из проблем приложения сервера – это не допускать ухода МК в глубокий сон, при котором тактирования ядра прекращается и вся периферия, включая UART блок, перестаёт работать. До соединения с клиентом уход в глубокий сон допустим в целях экономии энергии. Запрет/разрешение ухода в глубокой сон реализовано вызовом двух API функций в строках 111, 122, и 127 в файле app.c. Кроме того, пришлось модифицировать основной цикл приложения в файле main.c закомментированием строки 47 и переводом всех действий функции, вызываемой в этой строке, в метод app_process_action() в файле app.c. Смысл этих действий в синхронизации приёма данных по UART и отсылки их клиенту с работой Bluetooth стека.

В проекте клиента применён такой-же подход к синхронизации с Bluetooth стеком. По подаче питания программа клиента начинает сканирование Bluetooth устройств в радиусе приёма на предмет поиска устройства, предлагающего SPP сервис с определённым UUID 4880c12c-fdcb-4077-8920-a450d7f9b907. Как только такое устройство будет обнаружено, производится соединение с ним и поиск handle характеристики SPP_data (также с определённым UUID) на стороне сервера. Как только она будет обнаружена, приложение клиента будет знать как в неё послать данные.

 

При работе с кодом следует открыть окно терминала для каждой из демо-плат. Текст, печатаемый в одном из окон, отобразится в другом. Для перехода курсора на новую строку по нажатии Enter следует установить опцию CR+LF в настройках New-line → Transmit терминала. Для лучшего понимания функционирования приложения служит анимация, заимствованная с сайта фирмы [4]. В нашем случае повтор вводимого текста в окне источника (эхо на терминал) не производится.

 

Литература

1. USB Human Interface Devices
2. BLE HID Keyboard
3. Разработка Bluetooth приложений на модулях фирмы Silicon Labs. Часть 2.
4. SPP (Serial Port Profile) over BLE
5. О работе с Bluetooth модулями AMS001/002 фирмы Zentri

 


Файлы:
Архив ZIP


Все вопросы в Форум.




Как вам эта статья?

Заработало ли это устройство у вас?

12 1 4