Реалиазция стандартного GATT-BLE профиля на RSoC фирмы Cypress

Эта статья является продолжением моей статьи [1]. Здесь речь пойдёт о программной реализации стандартного GATT (Generic Attribute Profile) профиля ESP (Environmental Sensing Profile), включающего два также стандартных сервиса: ESS (Environmental Sensing Service) и BAS (Battery Service). К описанному серверу можно будет подключиться с любого устройства, поддерживающего протокол BLE (Bluetooth Low Energy), например смартфон или планшет, для мониторинга температуры и относительной влажности воздуха, а также состояния батареи. Помимо этого будут представлены некоторые программные и аппаратные средства для разработки и отладки BLE приложений.

Устройство наше основано на том-же радиомодуле CYBLE-022001-00 фирмы Cypress Semiconductor, подробнее о нем см. в первой части статьи [1]. В состав модуля входит микроконтроллер с архитектурой ARM Cortex-M0, в который помимо стека BLE можно загрузить программу пользователя. В схему добавлена пара резисторов для измерения напряжения батареи встроенным в RSoC АЦП.

схема

Изменение коснулось и сенсора параметров среды. С момента написания прошлой статьи ТИ выпустила модификацию прежнего сенсора HDC1050, который сейчас уже не рекомендуется для новых разработок. Новый сенсор на схеме функционально идентичен старому, но имеет бóльшую точность измерения влажности (±2%) и лучшую временную стабильность. Напомню, что резисторы сопротивлением около 5.6К на линиях I2C связи с сенсором встроены в RSoC и подключаются в схему программно. Схема по-прежнему собрана на безпаячной макетке для тестирования.

плата

Разрабатывать программное обеспечение мы будем в последней на момент написания версии 3.3 системы PSoC Creator, которая доступна для свободной загрузки с вебсайта фирмы. Нам потребуются 5 периферийных модулей: модуль BLE, модуль интерфейса I2C, модуль АЦП, цифровой пин для выхода, и аналоговый пин для входа. Подтянем их мышкой из каталога выбора компонентов на панель устройства. Компоненты, показанные синим цветом выбираются из панели Off-Chip внешних для RSoC компонентов. На функционирование программы они не влияют и выводить их на панель не обязательно. Я сделал это исключительно для удобства и наглядности. Однако, следует соединить аналоговый пин со входом АЦП после его конфигурирования.



Модуль I2C конфигурируется как и ранее буквально за пару кликов мышкой. В нем следует установить режим Master и выбрать Data rate в 100kbps. Обратимся к более сложному модулю BLE. В закладке General можно выбрать один из стандартных профилей, регламентируемых Bluetooth SIG, а также сконфигурировать свой собственный профиль. Мы выберем Environmental Sensing. При этом любое приложение на приёмном конце, знакомое с этим профилем, сможет автоматически форматировать принимаемые данные для показа пользователю.



Перейдя к закладке Profiles увидим, что система уже создала для нас шаблон конфигурации для выбранного профиля Environmental Sensing. Аттрибуты профиля, показанные в засинённых кружках являются обязательными для включения в проект. Это касается в первую очередь сервисов Generic Access, Generic Attribute, и Environmental Sensing, а также некоторых их характеристик и дескрипторов. Спецификацией Bluetooth SIG предоставляется возможность включения нескольких сенсоров среды в сервис, из которых у нас задействованы только два: Humidity и Temperature. Удалим из профиля все остальные сервисы и дескрипторы, кликнув на них правой кнопкой мышки, оставив только показанные ниже. Кликнув на характеристику Humidity разрешим её нотификацию. То-же самое сделаем с характеристикой Temperature. Это позволит стеку BLE сервера отправлять нотификации (notifications) об изменении этих величин клиенту.

Далее, щёлкнув правой кнопкой мышки по роли Environmental Sensing сервера, добавим к нему другой стандартный сервис Battery из списка. Кликнув на характеристику Battery Level этого сервиса, разрешим её нотификацию. Bluetooth SIG не рекомендует это делать из-за соображений повышения экономичности устройств. Даже без разрешения нотификации мы будем иметь возможность читать состояние батареи по запросу клиента. Однако, разрешив серверу посылать нотификации этой величины, он сможет делать это даже без специального запроса клиента, что в некоторых случаях удобно для мониторинга параметров.



Наконец, в закладке GAP Settings установим имя HDC1080 Sensor для нашего устройства и выберем уровень мощности сервера для режимов Advertising и после соединения с клиентом. Остальные параметры модуля в закладке GAP Settings устанавливаем также, как и в первой части статьи. На этом конфигурацию модуля BLE можно считать законченной.

Следующим этапом сконфигурируем цифровой и аналоговый пины. Помимо установки их имён (у меня RES_Pin и ADC_Pin, соответственно) у цифрового пина следует снять галку у HW connection (т.к. этот пин не подключён к другим модулям системы) и у обоих пинов выставить галку на External terminal если мы хотим задействовать их совместно с внешними компонентами (резисторы и пр.) на панели проекта. После этого выберем выводы корпуса под интерфейс I2C и выводы резисторов. Для этого нажимаем на закладку конфигуратора hardware и в ней внизу выбираем опцию Pins. В правой панели выбираем подходящие выводы корпуса. Для I2C и аналогового входа там имеется несколько возможностей.



Займёмся теперь модулем АЦП. У него имеется встроенный опорник на 1.024В а также несколько дифференциальных входов с мультиплексером. Подключив вывод “-“ канала 0 АЦП на выход опорника, мы сможем измерять напряжения в интервале 0..2.048В относительно общего провода. Поскольку устройство предназначается для питания от 3.6В батареи, этого интервала для непосредственного измерения её напряжения недостаточно. Проблема решается введением в схему резистивного делителя, напряжение в средней точке которого не превысит 1.8В в наших условиях. Для экономии энергии батареи подача питания на резистивный делитель осуществляется с цифрового пина RSoC только на время измерения напряжения. В закладке General конфигуратора АЦП следует выбрать Single ended negative input как показано ниже и формат данных Unsigned для недифференциального входа.



Так как внутренний опорник не дополнен у меня в схеме внешним конденсатором, частота тактирования АЦП получается низкой (всего 1.2 мгц), однако достаточной для редкого измерения напряжения батареи. Обратите внимание на установку Clock frequency на этой закладке. Далее, в закладке Channels оставим только канал 0 и разрешим усреднение двух измерений для повышения точности. Конфигурация частоты тактирования 12мгц всей системы производится также как и в первой части статьи. На этом предварительное конфигурирование RSoC с помощью GUI закончено и мы наконец-то переходим к написанию кода.

Драйвер сенсора в этом проекте аналогичен предыдущему (см. детали в [1]). Всё отличие состоит в строчках 23-24 метода getTempHumi() при вычислении значений температуры и влажности по сырым данным сенсора. Они добавлены вместо строчек 21-22. В профиле ESS под каждое них отводится по 16 бит, и software на устройстве клиентов, поддерживающее этот профиль, автоматически форматирует их с двумя знаками после запятой при показе. Поэтому в драйвере вычисляются эти значения умноженные на 100 и без отброса (всей) дробной части. Аналогично, характеристика Battery Level сервиса Battery трактуется в процентах, что учтено в программе при её вычислении.



Касательно основного файла приложения main.c, синхронизация работы приложения с BLE стеком подробнее описана в первой части статьи [1], поэтому здесь я останавливаться на этом не буду. Отмечу лишь некоторые новые моменты. Прежде всего в начале файла (строки 45-46) устанавливаются callback функции обработчика прерываний стека для соответствующих сервисов, подробнее о них ниже. Далее, в строках 49-59 производится настройка двух 16-битных таймеров на периодические прерывания. Таймеры эти входят в состав watchdog-ов и могут быть сконфигурированы в цепь. Именно, таймер Watchdog0 тактируется от часового кристалла, настроен на переполнение по подсчёту 32768 импульсов (1 сек), и фактически является прескейлером для таймера Watchdog1.



Это позволяет легко организовать повторение событий с большим периодом. В нашем случае нотификации об изменении параметров среды и их измерение производятся не чаще одного раза в 3 сек, а напряжение батареи – раз в 300 секунд (5 минут). Разрешение на производство новых измерений определяется переменной advUpdate, устанавливаемой в обработчике прерываний таймера Watchdog1 с периодом 3 сек. Если параметры среды изменились, производится обновление значения соответствующей характеристики и запрос на передачу соответствующей нотификации установкой флага в переменной notifRequired (строки 142-160).



Сама передача опевещений производится в строках кода 98-112 только если они разрешены клиентом посредством установки флага в переменной notifEnable в обработчике прерываний соответствующего сервиса.



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

Отладку BLE приложений можно производить с помощью смартфона или другого устройства, поддерживающего протокол BLE. Однако, удобнее для этого воспользоваться, например, следующими USB донглами (dongle). Верхний из них — CY5670 – производства Cypress Semiconductor входит во многие BLE Киты фирмы и также доступен для приобретения отдельно (цена около 20 USD).



Перед началом работы с CY5670 на компьютере следует установить систему CySmart, а в донгл загрузить последнюю версию firmware с помощью системы PSoC Programmer. Обе системы находятся в свободном доступе на вебсайте фирмы. Firmware для донгла содержится в одной из папок установки системы CySmart на компе, см. описание процедуры в [2]. После запуска CySmart и выборе донгла нажимаем на Start Scan и видим в окне среди других устройств наш сервер, ожидающий соединения с ним.



Выбираем его и нажимаем на Connect и далее на Discover All Attributes. При этом все аттрибуты сервера будут показаны в левом окне системы. На этом этапе уже можно прочитать значения любой характеристики сервера, кликнув на неё и далее на кнопку Read Value в правой части окна системы.



Однако, для начала автоматических нотификаций (в нашем приложении) следует их явно разрешить, например кликнув на Enable All Notifications. Можно и разрешить нотификации отдельных характеристик, записав значение 01:00 в их CCCD дескриптор в поле Value с последующим нажатием на Write Value в правом столбце системы. В результате увидим значения интересующих нас характеристик в шестнадцатеричной системе (в подсвеченных полях). Например, показанное ниже значение 01:18 аттрибута Humidity следует трактовать как 0x1801 = 61.45% (*100; эта система не принимает во внимание специальный формат значений характеристик сервисов). Система CySmart также доступна для свободной загрузки из Apple/Google Store для смартфонов.



Средний из показанных выше донглов – NFR51-DONGLE — производства Nordic Semiconductor также доступен в составе Китов NRF51-DK фирмы или отдельно (за ~50 USD). Перед началом работы следует также залить в него соответствующее firmware. Что именно и как заливать, к сожалению, не описано достаточно ясно в документации. Мне пришлось изрядно покликать по их сайту прежде чем я обнаружил внятный tutorial с детальным описанием процедуры [3]. Можно залить firmware и на на саму плату NRF51-DK, для чего следует замкнуть перемычкой выводы P0.30 и GND на её коннекторе P4. В любом случае, отладка производится с помощью системы Master Control Panel, свободно доступной с вебсайта фирмы. Выбираем в ней BLE устройство для соединения, затем нажимаем Discover services и, наконец, Enable services для начала посылки нотификаций. При приёме новой нотификации она регистритуется в логе в нижней части экрана и кратковременно подсвечивается зелёным цветом, как показано ниже.



Эта система, также как и CySmart, имеется и для смартфонов, и работа с обоими системами аналогична и интуитивна. Однако, приложение Mater Control Panel на моём Android-планшете выглядит несколько иначе и автоматически производит форматирование данных характеристик известных ему сервисов. Ниже показано как выглядит окно системы после соединения с устройством. В левой части окна отображается лог событий, а в правом – обнаруженные сервисы нашего устройства.



При нажатии, например, на Envorinmental Sensing в правой панели появляются органы управления аттрибутами. Ещё раз отмечу, что планшетная версия этой системы распознаёт известные ей форматы данных характеристик. В частности, она нормально показала температуру и влажность как десятичные числа с двумя знаками после запятой, а также состояние батареи как целое число в процентах по отношению к 3.6В. Помимо этого она добавила к данным символы градусов Цельсия и процентов.



Очень интересным является другое применение этого донгла совместно с системой Wireshark для визуализации работы протокола в режиме реального времени. При этом донгл работает в режиме сниффера, для чего в него следует загрузить соответствующее firmware с вебсайта фирмы. Загрузка, производится системой nRFgo Studio и процесс подробно описан в документации. Следует упомянуть, что документация гарантирует работу с nRF51-версией демо-платы или донгла на основе чипа nRF51822. Однако, у меня она нормально работает и с версией платы/донгла на основе чипов nRF51422. Архив с firmware помимо документации также содержит и само приложение – Sniffer.exe.

Первый запуск приложения сниффера следует производить с привелегиями администратора, чтобы оно смогло установить нужный плагин для Wireshark (предполагается, что сама система Wireshark установлена заранее). Однако, и тут не обошлось без икоты: оказалось, что плагин этот не работает с последней версией 2.х Wireshark. Пришлось установить её предыдущую стабильную версию 1.12, и все пошло как по маслу. После запуска программы следует выбрать BLE устройство, например по его номеру в списке (у нас номер 1), и нажать «w» на клавиатуре. Это приведёт к запуску Wireshark и началу логгирования.



Как видно из приведённого ниже лога, сначала наше устройство посылало извещения (advertisements) тройками (на каждом из предназначенных для этого каналов 37,38,39 в соответствии с конфигурацией (номера каналов появятся в нижней части экрана после кликания на соответствующие строки). Каждая тройка извещений посылалась примерно раз в секунду (строки 16-18 и 19-20) до тех пор пока не произошло соединение с устройством. Затем в течении нескольких сеансов (строки 21-39) планшет определял какие сервисы поддерживаются нашим устройством и каким характеристикам и дескрипторам соответствуют какие адреса (handles). Далее в строке 302 я записал 01:00 в аттрибут по адресу 0х0012 (Humidity Client Characteristic Configuration – см. адреса в окне CySmart выше), что разрешило отсылку нотификаций влажности нашим устройством. Первое посланная нотификация — она выделено синей полоской — содержит значение влажности умноженное на 100 (шестнадцатиричное число 381а следует читать в порядке от младшего к старшему байту – little-endian), что соответствует значению 0x1a38 = 67.12% после деления на 100. При работе BLE приложения после соединения с ним между устройствами посылается масса пустых, т.е. не содержаших данных, фреймов для поддержания соединения активным. Для исключения их из лога Wireshark следует применить фильтр. Мой фильтр показан на жёлтом фоне ниже.



Наконец, третий донгл из показанных выше – это Texas Instruments CC2540EMK-USB. Он доступен отдельно за 50 USD, а также в составе нескольких китов фирмы, например популярного CC2541-Mini. Донгл готов к использованию в режиме сниффера BLE пакетов сразу из коробки. Нужно только установить TI Packet Sniffer приложение и, конечно, драйвер. Приложение поддерживает несколько протоколов, например ZigBee и протокол SimpliciTI фирмы. Вставляем донгл в USB порт компьютера, запускаем приложение сниффера, в открывшемся окне выбираем протокол BLE, и нажимаем на Start.



Необходимо учесть, что после запуска сниффер настроен на прослушивание только одного из advertising каналов 37, 38, или 39 (на выбор), дефолтно 37-го. Наш сервер производит advertising на всех трёх каналах по очереди. Если запрос на соединение с ним будет произведён на канале 38 в то время как сниффер настроен на канал 37, то он не будет регистрировать пакеты соединения. Поэтому для настройки следует переконфигурировать наш сервер на посылку advertising только на одном канале и выбрать его в приложении сниффера.



Как следует из диаграмм выше, верхний advertising пакет послан нашим сервером на канале 37 непосредственно перед запросом планшета на соединение с ним. Последующие пакеты посылаются на разных каналах в соответствии с параметром Hop (в нашем случае 0х0А). Далее начинается долгий процесс определения поддерживаемых нашим сервером сервисов, их характеристик, и пр. В нижней части окна при выборе закладки Time line показан приём пакетов во времени. Вертикальная синяя полоска там соответствует в данном случае верхнему выбранному пакету. Выбор пакета позволяет просмотреть его детали в закладке Packet details. Отмечу, что опускаться на уровень полей пакетов при отладке BLE приложений приходится нечасто. Однако, иметь такую опцию очень полезно, например, для поиска возможных проблем или изучения/демонстрации работы протоколов.

Литература
  1. Bluetooth Smart Broadcaster на RSoC фирмы Cypress
  2. Cypress KBA96152: Updating CYKIT-042-BLEKitProg and CySmart USB Dongle Firmware
  3. Nordic tutorial: Testing and using a simple BLE application
  • +3
  • 08 июня 2016, 09:31
  • Ser60

Комментарии (9)

RSS свернуть / развернуть
Однако, разрешив серверу посылать нотификации этой величины, он сможет делать это даже без специального запроса клиента, что в некоторых случаях удобно для мониторинга параметров.
Ты с деепричастным оборотом накосячил (довольно типичная ошибка). YS на эту тему даже мини-тутор пилил.
Для экономии энергии батареи подача питания на резистивный делитель осуществляется с цифрового пина RSoC только на время измерения напряжения.
А можно опереть АЦП на питание МК, а на вход его подать опорное напряжение? Тогда внешний делитель не нужен.
0
  • avatar
  • Vga
  • 08 июня 2016, 14:02
Спасибо за ссылку на тутор, прочитал с удовольствием. По-моему с этим предложением всё нормально, т.к. сервер может разрешить самому себе посылку нотификаций. Про опорник на питании думал. Однако, в этой модели если поставить VDDA в качестве опорника АЦП, то нельзя будет вывести штатный опорник наружу. Также АЦП не может быть сконфигурирован на измерение напряжения опорника внутренне. Согласен, что странно, но пришлось с этим помириться.
0
Ser60 , подскажите пожалуйста, в каком режиме работы BLE есть возможность отправлять динамически изменяемые данные (payload), чтобы другие BLE устройства имели возможность получить эти данные не устанавливая соединения друг с другом.
P.S. Сейчас использую Bluenrg-MS от ST. Многих вещей с BLE еще не понял.
0
  • avatar
  • Zov
  • 08 июня 2016, 16:49
Это можно сделать в режиме Advertisement. Посмотрите на первую часть статьи — там именно так и сделано. ST — это интересно. Я уже приобрёл их их плату расширения для Nucleo с установленным на ней SPBTLE-RF модулем и планирую заняться как время позволит. Напишите впечатления как что у Вас получится, предпочтительнее на емайл. В данный момент занят другими вещами.
0
А не приходилось ли запускать свой сервис на чипах Нордика? дело в том, что имею опыт работы с ними не большой, воновном делал широковещательные устройства для передачи подобных вашим данных. Так же работал с их примерами. Дело дошло до реализации своего сервиса, но вот не могу разобраться с этим вопросом.
0
С Nordic-ами много не работал, хотя попробовал несколько примеров на вебсайте. Там, кстати есть пример создания своего сервиса, может он ответит на Ваш вопрос.
0
У меня есть задумка организовать авторизацию например в автомобиле по наличию зарегестрированного телефона с включенным блютузом, причем для этого даже не нужно делать спаривание, вот здесь описан процесс на примере ардуино
и нордик модуля
www.raspberrypi.org/forums/viewtopic.php?t=47466
Можно ли сделать тоже самое на BLE PSoC? То есть я понимаю что стандартный блютуз 2.0 и этот микропотребляющий это совсем разные протоколы, но возможно на этапе сопряжения разницы нет, и она появляются уже после?.. Тогда вероятно эо возможно…
0
Конечно, возможно. Однако, как это конкретно сделать не вытекает из статьи. Bluetooth Classic и BLE совершенно разные устройства, включая частоты каналов и другие радио-параметры. Поэтому распознавание Bluetooth Classic смартфона модулем на BLE PSoC на настоящий момент невозможно. Бывают модули, поддерживающие оба Bluetooth протокола, но пока это не PSoC.
0
Понял, спасибо… Я просто надеялся что у BLE какой-то стандартный стартовый пакет, которым оно дает телефону знать что оно не просто блютуз а BLE, и потом уже переходит на свои подчастоты… Иначе получится что телефон поочередно сканирует частоты стандартного и нового протоколов, что как-то не логично…
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.