BLE с использованием nRF51: создание периферийного устройства BLE
Как создать настраиваемое периферийное устройство BLE с помощью nRF51, создав службу и характеристики.
обзор
Это часть серии статей о nRF51. NRF51 - это система на кристалле с Cortex M0 и радиочипом BLE, все в одном. В этой статье показано, как создать периферию, настроив службу BLE и две характеристики.
Предыдущая статья: BLE с использованием nRF51: среда сборки ARM-GCC
Требования
- Устройство, которое имеет nRF51
Используется в статье: nRF-Dongle
- Создайте среду, учебник здесь.
- Мобильное приложение: Master Control Panel от Nordic
Используется в статье: Android v5.1.1
Обзор BLE
Все предопределенные периферийные устройства BLE имеют определенные свойства, связанные с ними. Например, все мониторы сердечного ритма должны поддерживать поле данных, которое содержит данные о частоте сердечных сокращений. Эти свойства составляют профиль BLE. Таким образом, все устройства, созданные разными компаниями, могут быть совместимы. Профиль содержит определения сервисов и характеристик. Профиль имеет одну или несколько служб, и каждая служба имеет одну или несколько характеристик.
Сервисы
Служба представляет собой логическую группировку с аналогичными возможностями или функциями устройства. Служба определяется с помощью UUID или уникального номера, который позволяет другим устройствам получать доступ. Сервис может иметь несколько характеристик внутри него.
Характеристика
Характерной особенностью является фактическая передача данных. Характеристика может быть длиной до 20 байтов и может быть настроена на чтение, запись или чтение / запись. Атрибут также может быть установлен для уведомления, когда данные были изменены. Таким образом, новые данные немедленно отправляются на телефон / планшет.
Программного обеспечения
Скачать код
Программное обеспечение состоит из двух исходных файлов и полагается на SDK softdevice для подключения BLE. SDK необходимо загрузить отдельно по лицензионному соглашению Nordic SDK. Инструкции о том, как это сделать, приведены в статье о среде сборки. Структура папок для этого проекта будет выглядеть следующим образом:

custom_peripheral_service.c
Этот файл имеет две функции. Один из них называется custom_service_init, который отвечает за запуск настраиваемой службы и двух характеристик. Вторая - custom_service_update_data, которая обновляет данные в характеристике, чтобы ее можно было прочитать мобильным устройством. В функции init новая служба создается с помощью UUID «BLE_UUID_CUSTOM_SERVICE» (определяется в «custom_peripheral_service.h») с помощью функции sd_ble_gatts_service_add:
/*create custom service*/ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_CUSTOM_SERVICE); err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &service_handle); if (err_code != NRF_SUCCESS) { return err_code; }
Затем создаются две характеристики с UUID «BLE_UUID_CUSTOM_CHAR1» и «BLE_UUID_CUSTOM_CHAR2», которые оба определены в файле заголовка. Размер данных характеристик устанавливается не более 20 байтов с определением «CHARACTERISTIC_SIZE».
#define BLE_UUID_CUSTOM_SERVICE 0x1110 #define BLE_UUID_CUSTOM_CHAR1 0x0001 #define BLE_UUID_CUSTOM_CHAR2 0x0002 #define CHARACTERISTIC_SIZE 20
Чтобы создать новую характеристику, вы должны заполнить определенные свойства для характеристики. К ним относятся, можно ли читать и записывать данные, сколько байтов доступно и можно ли отправлять уведомления. В приведенном ниже коде CHAR1 настраивается для записи путем изменения параметров «write_wo_resp» и «write» в переменной «ble_gatts_char_md_t». Данные инициализируются цифрами 0-19, указывая на переменную «initial_char_values» в свойстве «p_value».
/*char1 will be for writing*/ memset(&char_md, 0, sizeof(char_md)); char_md.char_props.write_wo_resp = 1; char_md.char_props.write = 1; char_md.p_char_user_desc = NULL; char_md.p_char_pf = NULL; char_md.p_user_desc_md = NULL; char_md.p_cccd_md = NULL; char_md.p_sccd_md = NULL; BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_CUSTOM_CHAR1); memset(&attr_md, 0, sizeof(attr_md)); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&dis_attr_md.read_perm); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&dis_attr_md.write_perm); attr_md.read_perm = dis_attr_md.read_perm; attr_md.write_perm = dis_attr_md.write_perm; attr_md.vloc = BLE_GATTS_VLOC_STACK; attr_md.rd_auth = 0; attr_md.wr_auth = 0; attr_md.vlen = 0; memset(&attr_char_value, 0, sizeof(attr_char_value)); attr_char_value.p_uuid = &ble_uuid; attr_char_value.p_attr_md = &attr_md; attr_char_value.init_len = CHARACTERISTIC_SIZE; attr_char_value.init_offs = 0; attr_char_value.max_len = CHARACTERISTIC_SIZE; attr_char_value.p_value = initial_char_values; err_code = sd_ble_gatts_characteristic_add(service_handle, &char_md, &attr_char_value, &char1_handles); if (err_code != NRF_SUCCESS) { return err_code; }
То же самое делается для CHAR2, за исключением того, что свойства записи не установлены в 1. Вместо этого свойство read установлено в 1 со следующей строкой:
char_md.char_props.read = 1;
Функция custom_service_update_data использует функцию softdevice sd_ble_gatts_value_set для обновления данных, которые может считывать мобильное устройство.
uint32_t custom_service_update_data(uint16_t conn_handle, uint8_t *new_data) { uint32_t err_code = NRF_SUCCESS; ble_gatts_value_t gatts_value; memset(&gatts_value, 0, sizeof(gatts_value)); gatts_value.len = CHARACTERISTIC_SIZE; gatts_value.offset = 0; gatts_value.p_value = new_data; if(conn_handle!=BLE_CONN_HANDLE_INVALID) { err_code = sd_ble_gatts_value_set(conn_handle, char2_handles.value_handle, &gatts_value); } return err_code; }
main.c
Основное приложение настраивает терминал отладки UART, запускает стек BLE в softdevice и записывает характеристики во время соединения. Если телефон / планшет записывается в CHAR1, он отображается в консоли отладки.
ble_stack_init
Эта функция инициализирует softdevice и включает BLE.
gap_params_init
Параметры GAP - это такие вещи, как имя устройства и интервал подключения. Интервал подключения - это скорость обмена мобильным устройством и периферией. Более быстрое соединение позволяет увеличить пропускную способность данных и снизить задержку за счет потребления энергии.
advertising_init
Реклама - это то, что делает периферийное устройство, когда оно хочет найти мобильное устройство. Эта функция определяет, как часто рекламируется устройство и как скоро отказаться от рекламы, если соединение не производится. Этот пример никогда не истекает.
services_init
Службы инициируются. В этом примере инициируется только пользовательская услуга, вызывая custom_service_init.
ble_advertising_start
Ничего на самом деле не происходит, пока устройство не начнет рекламу. Мобильное устройство не сможет найти периферийное устройство, пока оно не будет рекламироваться.
Остальная часть приложения - это просто бесконечный цикл, который обновляет данные в CHAR2. Сила может быть сохранена с помощью функции sd_app_evt_wait, но обновление данных должно быть перенесено на какой-то фоновый таймер. Эта функция отключает устройство до тех пор, пока не произойдет событие.
while(1) { nrf_delay_ms(1000); for(i=0; i < CHARACTERISTIC_SIZE; i+) { char2_data(i) = char2_data(i)+1; } err_code = custom_service_update_data(m_conn_handle, char2_data); APP_ERROR_CHECK(err_code); }
Здание
Создайте приложение, набрав make в консоли. Вспышка устройства, набрав make flash. Предполагается, что вы уже загрузили программное обеспечение S110 на устройство.
делать

сделать вспышку

Выход терминала
После программирования вы должны увидеть следующее на терминале при подключении к мобильному приложению Nordic и записи некоторых данных. Были предприняты следующие шаги:
- Открытая скандинавская заявка
- Откройте «Сканер»
- Найдите устройство «Пользовательский BLE»
- Нажмите «Подключить»
- Нажмите «Неизвестная служба».
- Нажмите стрелку вверх рядом с Неизвестной харатеристикой.
- Теперь вы можете ввести данные, используя «Новое значение» и «Добавить значение».

Вывод
Далее в серии будет описано, как создать приложение Android для чтения и записи данных характеристик. Затем, используя приложение Android и знания из этой статьи в качестве шаблона, мы можем создавать приложения для управления другими устройствами и считывания данных датчиков!
Следующая статья в серии: Введение в FreeRTOS на nRF51
Попробуйте этот проект сами! Получить спецификацию.