如何实现扫码连接BLE 设备的功能(以nRF5 为例)?

您所在的位置:网站首页 彩票二维码扫描怎么弄 如何实现扫码连接BLE 设备的功能(以nRF5 为例)?

如何实现扫码连接BLE 设备的功能(以nRF5 为例)?

2024-05-29 12:42| 来源: 网络整理| 查看: 265

文章目录 前言 一、nRF5 SDK 开发环境搭建 1.1 nRF5 SDK和SoftDevice 版本选择 1.2 IDE 和J-Link 版本选择 二、扫码连接功能开发 2.1 ble_app_uart_c 工程简介 2.2 GAP(目标设备发现和连接过程) 2.2.1 设置并启用过滤器 2.2.2 启用匹配即连接功能 2.2.3 设置扫描与连接参数 2.2.4 为扫描过程注册事件处理函数 2.3 GATT(NUS服务发现和交互过程) 2.3.1 BLE 协议栈初始化 2.3.2 配置MTU 交换过程 2.3.3 NUS 服务发现过程 2.3.4 NUS 服务访问过程 2.4 UART(串口外设初始化和访问过程) 2.4.1 UART 模块初始化 2.4.2 处理UART 接收到的地址信息 三、扫码连接功能验证 3.1 扫码连接功能验证 3.2 新增获取RSSI 功能 更多文章:

前言

现在大部分蓝牙设备都不具备输入输出功能,主要靠蓝牙主机扫描发现周围的蓝牙从机,蓝牙从机需要处于广播模式才能被主机发现。蓝牙主机会将扫描发现的从机设备展示在一个列表中,你可以根据设备名称、类型和图标等信息,选择要连接哪一个从机设备。

如果周围有多个设备名称、类型和图标等信息都相同的从机设备,该怎么区分彼此呢?这种情况在物联网设备普及的当下也是经常遇到的。如果多个从机设备与蓝牙主机的距离有明显差异,可以通过扫描发现的设备列表先后排序区分彼此。蓝牙主机发现的设备列表是按照相对距离排序的,根据接收到广播报文的信号强度和报文中包含的发射功率等信息,蓝牙主机可以计算出每个蓝牙从机到主机的路径损耗,进而计算出每个蓝牙从机到主机的相对距离,距离蓝牙主机越近的从机设备,在扫描设备列表中的排序越靠前。

如果周围多个设备名称、类型和图标等信息都相同的从机设备到蓝牙主机的距离也相差无几,按照扫描设备列表排序来区分彼此可能就不准确了,这时候又该如何区分彼此呢?我们知道蓝牙设备的MAC 地址可以作为其唯一身份标识,每个蓝牙设备的MAC 地址都是不同的,我们可以通过蓝牙设备的MAC 地址来区分彼此。

目前市场上已经有很多蓝牙设备在其说明书中附带了该设备的MAC 二维码,我们只需要打开手机摄像头扫描该MAC 码即可连接该蓝牙设备,即便周围有很多同类设备,彼此的MAC 码也是不同的,因此可以将MAC 码作为区分彼此的依据,而且一扫即连(扫描MAC 码)、一碰即连(NFC 感应)等方式对使用者也更友好。

上述情况最常出现在工厂批量测试中,工厂在进行蓝牙设备测试时,首先需要连接到蓝牙设备才能进行后续的通信,旁边有很多同类型设备,这时就需要通过MAC 地址来区分彼此了。工厂生产的蓝牙设备大多是作为从机对外提供服务的,可以把PC 作为蓝牙主机,在PC 上连接一个摄像头或扫码枪来获取MAC 码信息,在PC 上开发一个通过MAC 地址自动连接蓝牙从机的程序,就可以实现蓝牙从设备与PC 之间一扫即连的进行通讯了。

本文以nRF52 BLE 芯片为例,使用nRF52 开发板作为蓝牙主机,来完成连接指定BLE 目标设备并进行通讯的任务。NRF52 开发板与PC 之间通过UART 协议通讯,PC 将获取到的从机MAC 地址通过UART 传给开发板,开发板根据获取到的MAC 地址连接指定的从机设备,建立连接后的通信数据也通过UART 在开发板与PC 之间传输。

BLE Nordic UART Service

一、nRF5 SDK 开发环境搭建 1.1 nRF5 SDK和SoftDevice 版本选择

Nodic 半导体为nRF52 BLE 芯片提供了nRF5 SDK 开发工具,SDK 内包含一些蓝牙应用示例,我们可以在此基础上开发我们需要的功能,比如我们可以在蓝牙透传示例代码基础上开发一扫即连的功能。

NRF52 芯片的BLE 驱动程序被封装为softdevice.hex 文件提供给用户了,开发者根据需要直接调用相应的API 就可以了,读者可以参考博文:Nordic nRF5 SDK和softdevice介绍了解nRF5 开发环境搭建。

本文选用nRF52832 芯片作为从机设备的蓝牙模块,选用nRF52 DK board作为蓝牙主机,选择最新的nRF5_SDK_17.0.2 版本来开发应用。一扫即连功能主要是在蓝牙主机上实现的,选用的蓝牙协议栈softdevice 应支持ble_central (master) 角色,本文选用S132 类型最新版本s132_nrf52_7.2.0_softdevice,这也是nRF5_SDK_17.0.2 为nRF52 DK board PCA10040 默认提供的蓝牙协议栈版本。

nRF5 softdevice 架构

1.2 IDE 和J-Link 版本选择

Nordic 支持的IDE 开发工具主要有四种:Segger Embedded Studio、Keil MDK-ARM、IAR for ARM、ARM GCC 等,用户可以根据自己的使用习惯选择IDE 工具。考虑到Nordic 对Segger Embedded Studio 的支持更友好,且Nordic 已经购买了Segger Embedded Studio for Nordic 的License,用户不需要再为License 付费,Segger Embedded Studio 更有跨平台的便利(支持windows、Linux、MAC OS 等开发平台,方便跨平台移植),本文选择最新版的SeggerEmbeddedStudio_ARM_v520 开发Nordic 应用。

Nordic nRF52 DK 板载J-Link 模块,J-Link 仿真器也是Segger 公司开发的,因此Segger Embedded Studio 对J-Link 仿真功能的支持也更完善强大。为方便nRF52 BLE 芯片下载调试,还需要安装J-Link 驱动程序,本文选择最新版的 JLink_Windows_V684a。Nordic 对J-Link 驱动程序进行了封装,提供了nrfjprog 命令行工具,本文选择Nordic 封装的命令行工具版本 nRF-Command-Line-Tools_10_10_0_Installer。

本文选择的nRF5 开发工具版本汇总如下(可参考博文:Nordic nRF52开发环境搭建):

IDE Toolchain:Setup_EmbeddedStudio_ARM_v5.20_win_x64 J-Link Driver:nRF-Command-Line-Tools_10_10_0_Installer_64 nRF5 SDK:nRF5_SDK_17.0.2_d674dde SoftDevice(BLE protocol stack):s132_nrf52_7.20 Development platform:Windows 10_x64 二、扫码连接功能开发

前言部分已经简单介绍了实现一扫即连功能的原理,一扫即连功能主要在BLE Central 端(也即nRF52 DK)实现,nRF52 DK 一端通过UART 与PC 通信,另一端通过BLE 与从机设备通信,这是典型的蓝牙串口透明传输应用,Nordic 也提供了相应的示例.\nRF5_SDK\examples\ble_central\ble_app_uart_c。

我们可以在ble_app_uart_c 示例的基础上,新增我们需要的一扫即连功能。Nordic 提供的蓝牙透传示例工程主要包括两个部分:UART 应用和BLE NUS (Nordic UART Service),前者对应上图中的App-Specific peripheral drivers 及其Application,后者对应上图中的nRF SoftDevice 及其Profiles / Services。

NUS与UART App 通信方式

我们打开ble_app_uart_c 示例工程文件 .\nRF5_SDK_15.3.0_59ac345\examples\ble_central\ble_app_uart_c\pca10040\s132\ses\ble_app_uart_c_pca10040_s132.emProject,开始了解该示例工程的业务逻辑,并在此基础上新增我们需要的一扫即连功能。在此之前,我们先编译该工程项目,编译无错误,然后通过J-Link 连接nRF52 DK 并将编译文件烧录到开发板中,烧录验证均未报错,说明示例工程代码没问题。

2.1 ble_app_uart_c 工程简介

Nordic 提供的ble_app_uart_c 示例工程并没有使用RTOS 实时操作系统,只是一个前后台系统,主要靠中断或事件触发来保证程序的实时性。我们先浏览该示例工程入口主函数的代码:

// .\nRF5_SDK_17.0.2_d674dde\examples\ble_central\ble_app_uart_c\main.c int main(void) { // Initialize. log_init(); // Initializes the nrf log module timer_init(); // Initializes the app timer uart_init(); // Initializes the UART buttons_leds_init(); // Initializes buttons and leds db_discovery_init(); // Initializes the database discovery module power_management_init(); // Initializes power management module ble_stack_init(); // Initializes the SoftDevice and the BLE event interrupt(BLE stack) gatt_init(); // Initializes the GATT library nus_c_init(); // Initializes the Nordic UART Service (NUS) client scan_init(); // Initializes the scanning and setting the filters // Start execution. printf("BLE UART central example started.\r\n"); NRF_LOG_INFO("BLE UART central example started."); scan_start(); // starting scanning // Enter main loop. for (;;) { idle_state_handle(); // Handles any pending log operations, then sleeps until the next event occurs. } }

该工程main 函数的前半部分是相关模块的初始化,待涉及的资源初始化完成后,开始执行扫描过程(或设备发现过程),发现周围正在广播的蓝牙从机设备,若发现的从机设备符合蓝牙主机设置的过滤条件,则蓝牙主机向该从机设备发起连接。双方建立连接后,蓝牙主机开始执行服务发现过程,发现从机设备提供的服务(该示例工程中指的是Nordic Uart Service)后,蓝牙主机就可以作为客户端访问从机设备提供的服务了。

最后,main 函数进入主循环,处理空闲状态idle_state_handle,也即当前任务处理完成后进入睡眠状态节省功耗,当检测到有中断或事件触发时,唤醒设备并执行中断服务程序或事件处理程序。

BLE 协议栈比较复杂,涉及的状态也较多,Nordic 使用有限状态机模型来管理蓝牙设备的当前状态及状态切换,当特定事件触发后,根据当前所处的状态,执行相应的事件处理程序。下面给出一个状态机单元供参考(可参考博文:有限状态机和BLE事件回调机制解析):

有限状态机模型

2.2 GAP(目标设备发现和连接过程) 2.2.1 设置并启用过滤器

蓝牙主机上电初始化后,先执行设备发现过程(Discovery modes and procedures)以发现周围处于广播状态的从机设备(从机设备上电初始化后,执行advertising_start 过程开始对外广播),如果周围有多个处于可发现模式的从机设备,蓝牙主机将扫描出一个设备列表。工程ble_app_uart_c 初始化并执行设备发现过程的代码如下:

// .\nRF5_SDK_17.0.2_d674dde\examples\ble_central\ble_app_uart_c\main.c /**@brief Function for initializing the scanning and setting the filters. */ static void scan_init(void) { ret_code_t err_code; nrf_ble_scan_init_t init_scan; memset(&init_scan, 0, sizeof(init_scan)); init_scan.connect_if_match = true; init_scan.conn_cfg_tag = APP_BLE_CONN_CFG_TAG; err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler); APP_ERROR_CHECK(err_code); err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_UUID_FILTER, &m_nus_uuid); APP_ERROR_CHECK(err_code); err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_UUID_FILTER, false); APP_ERROR_CHECK(err_code); } /**@brief NUS UUID. */ static ble_uuid_t const m_nus_uuid = { .uuid = BLE_UUID_NUS_SERVICE, .type = NUS_SERVICE_UUID_TYPE }; /**@brief Function to start scanning. */ static void scan_start(void) { ret_code_t ret; ret = nrf_ble_scan_start(&m_scan); APP_ERROR_CHECK(ret); ...... } // .\nRF5_SDK_17.0.2_d674dde\components\ble\nrf_ble_scan\nrf_ble_scan.h /**@brief Types of filters. */ typedef enum { SCAN_NAME_FILTER, /**< Filter for names. */ SCAN_SHORT_NAME_FILTER, /**< Filter for short names. */ SCAN_ADDR_FILTER, /**< Filter for addresses. */ SCAN_UUID_FILTER, /**< Filter for UUIDs. */ SCAN_APPEARANCE_FILTER, /**< Filter for appearances. */ } nrf_ble_scan_filter_type_t;

在执行扫描过程前,蓝牙主机可以设置过滤条件,抛弃不符合过滤条件的从机设备,在蓝牙主机的发现设备列表中只保留符合过滤条件的设备,比如只保留给定设备名、设备MAC地址、设备服务UUID 等条件的从机设备。原示例工程中选择SCAN_UUID_FILTER(也即BLE_UUID_NUS_SERVICE)作为过滤条件,也即提供NUS 的从机设备都可以被发现,这并不是我们需要的,我们应怎样借助过滤器实现一扫即连功能呢?

我们期望通过扫描MAC 地址自动连接到目标设备,且设备的MAC 地址具有唯一性,我们可以设置过滤条件为SCAN_ADDR_FILTER,也即只有符合给定MAC 地址的从机设备才会被发现。由于符合该过滤条件的目标设备至多一个,可以设置当发现目标设备后,自动连接到该目标设备,这就实现了我们期望的一扫即连功能。因此,我们将上述scan_init 函数的代码修改如下:

// .\nRF5_SDK_17.0.2_d674dde\examples\ble_central\ble_app_uart_c\main.c /**@brief NUS ADDR. */ uint8_t m_ble_addr[BLE_GAP_ADDR_LEN] = { 0x00}; /**@brief Function for initializing the scanning and setting the filters. */ static void scan_init(uint8_t * p_addr) { ret_code_t err_code; nrf_ble_scan_init_t init_scan; memset(&init_scan, 0, sizeof(init_scan)); init_scan.connect_if_match = true; init_scan.conn_cfg_tag = APP_BLE_CONN_CFG_TAG; err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler); APP_ERROR_CHECK(err_code); err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_ADDR_FILTER, p_addr); APP_ERROR_CHECK(err_code); err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_ADDR_FILTER, false); APP_ERROR_CHECK(err_code); } int main(void) { // Initialize. ...... scan_init(m_ble_addr); // 设备地址通过参数传入 // Start execution. printf("Start scanning the MAC address of the target BLE device.\r\n"); NRF_LOG_INFO("Start scanning the MAC address of the target BLE device."); scan_start(); ...... }

我们将扫描过滤条件设置为SCAN_ADDR_FILTER,由于我们初始时不知道目标设备的MAC 地址,新增地址变量m_ble_addr 的初始值设为零。目标设备的地址是PC通过UART 协议传给蓝牙主机的,待蓝牙主机接收到目标设备地址时,其已经完成初始化过程,因此需要使用目标设备地址重新设置过滤条件,上述代码借助函数scan_init 参数传入目标设备地址。

继续看过滤条件设置函数nrf_ble_scan_filter_set 和nrf_ble_scan_filters_enable 实现代码,要添加并使能设备地址过滤条件,还需要配置宏定义NRF_BLE_SCAN_ADDRESS_CNT 大于0,我们只传入一个设备地址,因此将sdk_config.h 文件中定义的宏NRF_BLE_SCAN_ADDRESS_CNT 设置为1。我们不需要添加并使能UUID,因此将宏NRF_BLE_SCAN_UUID_CNT 设置为0,修改后的代码如下:

// .\nRF5_SDK_17.0.2_d674dde\components\ble\nrf_ble_scan\nrf_ble_scan.c ret_code_t nrf_ble_scan_filter_set(nrf_ble_scan_t * const p_scan_ctx, nrf_ble_scan_filter_type_t type, void const * p_data) { VERIFY_PARAM_NOT_NULL(p_scan_ctx); VERIFY_PARAM_NOT_NULL(p_data); switch (type) { #if (NRF_BLE_SCAN_NAME_CNT > 0) case SCAN_NAME_FILTER: { char * p_name = (char *)p_data; return nrf_ble_scan_name_filter_add(p_scan_ctx, p_name); } #endif ...... #if (NRF_BLE_SCAN_ADDRESS_CNT > 0) case SCAN_ADDR_FILTER: { uint8_t * p_addr = (uint8_t *)p_data; return nrf_ble_scan_addr_filter_add(p_scan_ctx, p_addr); } #endif #if (NRF_BLE_SCAN_UUID_CNT > 0) case SCAN_UUID_FILTER: { ble_uuid_t * p_uuid = (ble_uuid_t *)p_data; return nrf_ble_scan_uuid_filter_add(p_scan_ctx, p_uuid); } #endif ...... default: return NRF_ERROR_INVALID_PARAM; } } // .\nRF5_SDK_17.0.2_d674dde\examples\ble_central\ble_app_uart_c\pca10040\s132\config\sdk_config.h // NRF_BLE_SCAN_FILTER_ENABLE - Enabling filters for the Scanning Module. //========================================================== #ifndef NRF_BLE_SCAN_FILTER_ENABLE #define NRF_BLE_SCAN_FILTER_ENABLE 1 #endif // NRF_BLE_SCAN_UUID_CNT - Number of filters for UUIDs. #ifndef NRF_BLE_SCAN_UUID_CNT #define NRF_BLE_SCAN_UUID_CNT 0 #endif // NRF_BLE_SCAN_NAME_CNT - Number of name filters. #ifndef NRF_BLE_SCAN_NAME_CNT #define NRF_BLE_SCAN_NAME_CNT 0 #endif ...... // NRF_BLE_SCAN_ADDRESS_CNT - Number of address filters. #ifndef NRF_BLE_SCAN_ADDRESS_CNT #define NRF_BLE_SCAN_ADDRESS_CNT 1 #endif ......

到这里,蓝牙主机扫描过程的过滤条件配置完成。接下来需要解决的问题有两个:一个是如何将目标设备的MAC 地址传给蓝牙主机;另一个是如何配置为扫描到符合过滤条件的目标设备后自动向其发起连接。前一个问题在下文谈到UART 时解决,这里先解决后一个问题。

2.2.2 启用匹配即连接功能

在函数scan_init 代码中,为变量 init_scan.connect_if_match 赋值为 true,看字面意思是如果符合过滤条件就发起连接,这个判断是否准确需要我们到数据结构的定义中确认,我们查询结构体类型nrf_ble_scan_init_t 和nrf_ble_scan_t 的数据结构声明如下:

// .\nRF5_SDK_17.0.2_d674dde\components\ble\nrf_ble_scan\nrf_ble_scan.h /**@brief Structure for Scanning Module initialization. */ typedef struct { ble_gap_scan_params_t const * p_scan_param; /**< BLE GAP scan parameters required to initialize the module. Can be initialized as NULL. If NULL, the parameters required to initialize the module are loaded from the static configuration. */ bool connect_if_match; /**< If set to true, the module automatically connects after a filter match or successful identification of a device from the whitelist. */ ble_gap_conn_params_t const * p_conn_param; /**< Connection parameters. Can be initialized as NULL. If NULL, the default static configuration is used. */ uint8_t conn_cfg_tag; /**< Variable to keep track of what connection settings will be used if a filer match or a whitelist match results in a connection. */ } nrf_ble_scan_init_t; /**@brief Scan module instance. Options for the different scanning modes. * @details This structure stores all module settings. It is used to enable or disable scanning modes and to configure filters. */ typedef struct { #if (NRF_BLE_SCAN_FILTER_ENABLE == 1) nrf_ble_scan_filters_t scan_filters; /**< Filter data. */ #endif bool connect_if_match; /**< If set to true, the module automatically connects after a filter match or successful identification of a device from the whitelist. */ ble_gap_conn_params_t conn_params; /**< Connection parameters. */ uint8_t conn_cfg_tag; /**< Variable to keep track of what connection settings will be used if a filer match or a whitelist match results in a connection. */ ble_gap_scan_params_t scan_params; /**< GAP scanning parameters. */ nrf_ble_scan_evt_handler_t evt_handler; /**< Handler for the scanning events. Can be initialized as NULL if no handling is implemented in the main application. */ uint8_t scan_buffer_data[NRF_BLE_SCAN_BUFFER]; /**< Buffer where advertising reports will be stored by the SoftDevice. */ ble_data_t scan_buffer; /**< Structure-stored pointer to the buffer where advertising reports will be stored by the SoftDevice. */ } nrf_ble_scan_t; // .\nRF5_SDK_17.0.2_d674dde\components\ble\nrf_ble_scan\nrf_ble_scan.c ret_code_t nrf_ble_scan_init(nrf_ble_scan_t * const p_scan_ctx, nrf_ble_scan_init_t const * const p_init, nrf_ble_scan_evt_handler_t evt_handler) { VERIFY_PARAM_NOT_NULL(p_scan_ctx); p_scan_ctx->evt_handler = evt_handler; #if (NRF_BLE_SCAN_FILTER_ENABLE == 1) // Disable all scanning filters. memset(&p_scan_ctx->scan_filters, 0, sizeof(p_scan_ctx->scan_filters)); #endif // If the pointer to the initialization structure exist, use it to scan the configuration. if (p_init != NULL) { p_scan_ctx->connect_if_match = p_init->connect_if_match; p_scan_ctx->conn_cfg_tag = p_init->conn_cfg_tag; if (p_init->p_scan_param != NULL) { p_scan_ctx->scan_params = *p_init->p_scan_param; } else { // Use the default static configuration. nrf_ble_scan_default_param_set(p_scan_ctx); } if (p_init->p_conn_param != NULL) { p_scan_ctx->conn_params = *p_init->p_conn_param; } else { // Use the default static configuration. nrf_ble_scan_default_conn_param_set(p_scan_ctx); } } // If pointer is NULL, use the static default configuration. else { nrf_ble_scan_default_param_set(p_scan_ctx); nrf_ble_scan_default_conn_param_set(p_scan_ctx); p_scan_ctx->connect_if_match = false; } // Assign a buffer where the advertising reports are to be stored by the SoftDevice. p_scan_ctx->scan_buffer.p_data = p_scan_ctx->scan_buffer_data; p_scan_ctx->scan_buffer.len = NRF_BLE_SCAN_BUFFER; return NRF_SUCCESS; }

从上述结构体变量connect_if_match 的注释中可以了解到,该成员变量赋值为true 就可以实现扫描到匹配过滤条件的目标设备后,自动向其发起连接,原工程代码的配置已经实现了我们期望的功能,因此不需要再对其修改。

2.2.3 设置扫描与连接参数

在函数nrf_ble_scan_init 中,也完成了扫描参数和连接参数的初始化,ble_app_uart_c 工程直接使用了默认的扫描参数与连接参数,通过查看函数nrf_ble_scan_default_param_set 和nrf_ble_scan_default_conn_param_set 的实现代码,发现使用的扫描参数和连接参数来源于sdk_config.h 文件中的宏定义,本文也沿用如下的扫描参数与连接参数(可参考博文:链路层广播通信与连接通信):

// .\nRF5_SDK_17.0.2_d674dde\examples\ble_central\ble_app_uart_c\pca10040\s132\config\sdk_config.h // NRF_BLE_SCAN_SCAN_INTERVAL - Scanning interval. Determines the scan interval in units of 0.625 millisecond. #ifndef NRF_BLE_SCAN_SCAN_INTERVAL #define NRF_BLE_SCAN_SCAN_INTERVAL 160 #endif // NRF_BLE_SCAN_SCAN_DURATION - Duration of a scanning session in units of 10 ms. Range: 0x0001 - 0xFFFF (10 ms to 10.9225 ms). If set to 0x0000, the scanning continues until it is explicitly disabled. #ifndef NRF_BLE_SCAN_SCAN_DURATION #define NRF_BLE_SCAN_SCAN_DURATION 0 #endif // NRF_BLE_SCAN_SCAN_WINDOW - Scanning window. Determines the scanning window in units of 0.625 millisecond. #ifndef NRF_BLE_SCAN_SCAN_WINDOW #define NRF_BLE_SCAN_SCAN_WINDOW 80 #endif // NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL - Determines minimum connection interval in milliseconds. #ifndef NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL #define NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL 7.5 #endif // NRF_BLE_SCAN_MAX_CONNECTION_INTERVAL - Determines maximum connection interval in milliseconds. #ifndef NRF_BLE_SCAN_MAX_CONNECTION_INTERVAL #define NRF_BLE_SCAN_MAX_CONNECTION_INTERVAL 30 #endif // NRF_BLE_SCAN_SLAVE_LATENCY - Determines the slave latency in counts of connection events. #ifndef NRF_BLE_SCAN_SLAVE_LATENCY #define NRF_BLE_SCAN_SLAVE_LATENCY 0 #endif // NRF_BLE_SCAN_SUPERVISION_TIMEOUT - Determines the supervision time-out in units of 10 millisecond. #ifndef NRF_BLE_SCAN_SUPERVISION_TIMEOUT #define NRF_BLE_SCAN_SUPERVISION_TIMEOUT 4000 #endif

这里先假设目标设备地址已经传入并设置为过滤条件,且配置匹配即连接选项(也即connect_if_match = t



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3