• nordic——long range测试


    简介:本案例测试了long range,注意nrf52系列芯片中,部分硬件是不支持CADED的,因此也就是不支持long range,如nrf52832就不支持long range。同时协议栈也是部分支持,部分不支持,支持的如S140,不支持的如S113.所以在开发前需要把软件和硬件都确定好。

    测试条件:

    软件:基于nordic的SDK17.1的透传例子(主从机),协议栈选择s140

    硬件:nrf52840DK板

    下面是支持long range的芯片截图,当然除去下面这些,还有nrf5340也是支持的

    在long range的125kbps模式下,最低的灵敏度在-103dBm(1M时为-95dBm)。

    一、从机程序修改

    这里涉及到广播态和连接态两种状态。就是保证广播是long range,链接也是long range。

    把普通的BLE广播修改为long range广播,主要对从机广播包的机构和参数设置进行

    1.1加入广播数据包定义

    使用ble_gap_adv_data_t结构定义一个全局的广播数据变量,注意在long range中是不能有回复包的,所以在定义时要给广播回复包的数据指针设置为NULL,长度设置为零,即如代码(直接加到main.c中):

    static ble_gap_adv_data_t m_adv_data =

    {

        .adv_data =

        {

            .p_data = m_enc_advdata,

            .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX

        },

        .scan_rsp_data =/*对于应答包,在long range(即PHY)下是不能设置的,必须保持为空*/

        {

            .p_data = NULL,

            .len    = 0

        }

    };

    1.2广播初始化参数修改

    修改advertising_init()函数修改配置如下,可以直接复制替换advertising_init函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    static void advertising_init(void)
    {
        uint32_t               err_code;
        ble_advertising_init_t init;
            ble_gap_adv_params_t adv_params;
     
        memset(&init, 0, sizeof(init));
     
        init.advdata.name_type          = BLE_ADVDATA_FULL_NAME;
        init.advdata.include_appearance = false;
        init.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
    #ifndef long_range 
        init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        init.srdata.uuids_complete.p_uuids  = m_adv_uuids;
        #else
            init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        init.advdata.uuids_complete.p_uuids  = m_adv_uuids;
    #endif
        init.config.ble_adv_fast_enabled  = true;
        init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
        init.config.ble_adv_fast_timeout  = APP_ADV_DURATION;
        init.evt_handler = on_adv_evt;
    /*开始定义long range的参数*/
    #ifdef long_range      
            init.config.ble_adv_extended_enabled =1;
            init.config.ble_adv_primary_phy     = BLE_GAP_PHY_CODED;
            init.config.ble_adv_secondary_phy   =   BLE_GAP_PHY_CODED;
             
            memset(&adv_params,0,sizeof(adv_params));
             
            adv_params.properties.type  =  BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;
     
            adv_params.p_peer_addr   = NULL;                                //对端设备地址(无)
            adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;  //扫描策略,现为响应任意设备请求与连接
        adv_params.interval      = APP_ADV_INTERVAL;
            adv_params.duration          = APP_ADV_DURATION;
             
            adv_params.primary_phy      = BLE_GAP_PHY_CODED;
            adv_params.secondary_phy    =   BLE_GAP_PHY_CODED;
            adv_params.scan_req_notification = 1;//允许扫描通知
             
            m_advertising.adv_params    = adv_params;  
     
            m_advertising.adv_mode_current = BLE_ADV_MODE_IDLE;
            m_advertising.adv_modes_config  = init.config;
            m_advertising.conn_cfg_tag          = BLE_CONN_CFG_TAG_DEFAULT;
            m_advertising.evt_handler               = init.evt_handler;
            m_advertising.current_slave_link_conn_handle    =  BLE_CONN_HANDLE_INVALID;
            m_advertising.p_adv_data                = &m_advertising.adv_data;
             
            memset(&m_advertising.peer_address, 0, sizeof(m_advertising.peer_address));
             
            m_advertising.adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
            m_advertising.adv_data.adv_data.p_data = m_advertising.enc_advdata[0];
            m_advertising.adv_data.adv_data.len         = adv_set_data_size_max_get(&m_advertising);
             
            err_code = ble_advdata_encode(&init.advdata, m_advertising.enc_advdata[0], &m_advertising.adv_data.adv_data.len);
        APP_ERROR_CHECK(err_code);
     
        /*
                参数1:指向一个空的对端设备的句柄,便于在发现对端设备后可以把其句柄给到这个指针,可以理解为初始化
                参数2:广播的数据,要放入广播的数据,如果使用NULL,则表示没有任何数据,这里没有设置,会给的m_advertising的广播数据部分在后面的广播开始函数中再次进行设置,
                            主要是为了兼容,是的修改最少
                参数3:广播的设置参数,如果应用需要在广播期间去更改 广播数据 ,那么这个时候必须设置为NULL
        */
            err_code = sd_ble_gap_adv_set_configure(&m_advertising.adv_handle, NULL, &m_advertising.adv_params);
            APP_ERROR_CHECK(err_code);
            /*这一定要设置,否则会导致官方默认驱动检查 m_advertising.initialized的时候没有报错*/
            m_advertising.initialized = true;
    #endif 
     
        ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
    }

    BLE_GAP_PHY_CODED就表示使用125K或者500K的信道,由此牺牲速度的情况下达到远距离传输的需求。

     以上修改完成,我们即完成了对从机程序的修改,编译下载即可。

    1.3、修改结果确定:

    使用带有拓展广播扫描功能的手机,安装nrf connect app后,使用名字过滤后可以看到我们的lonog range广播,特别注意,有些手机不支持拓展广播,可能无法找到

    点击RAW后可以看到详细信息,然后可以看到,广播包为拓展广播,PHY为LE coded,说明主机修改成功。

    点击连接,然后点击右边3个竖着的点,在点击读取 PHY(read PHY),在右向滑动窗口到log显示界面,确定连接是否也是coded,

    在log界面可以看到连接的TX和RX同样为code,说明我们修改没有问题,可以进行long range的通讯:

    二、主机程序修改

     主机程序是基于ble_app_uart_cs140例程进行修改。

    1改变原本的过滤策略

    这一步主要是让我们可以精确的找到我们的设备,不修改也可以,

    1.1、修改sdk_config

    打开工程的sdk_config.h然后找到截图出,按照截图的方式修改,添加使用mac地址过滤:

     

     

    1.2、程序修改

    修改完毕后,我们需要加入我们从机设备的MAC地址

    1
    2
    3
    4
    5
    static ble_gap_addr_t const my_mac=
    {
        .addr_type  =   BLE_GAP_ADDR_TYPE_RANDOM_STATIC,
        .addr               ={0x51,0xAE,0x8D,0xC2,0xF4,0xC6}
    };

    然后再scan_init()函数中修改UUID过滤策略为MAC地址过滤策略:MAC地址过滤策略代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    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, &my_mac.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);

    2改变原本的扫描方式

    这一步关系着是否可以扫描到long range广播,我们需要定义一个ble_gap_scan_params_t类型的变量,具体的设置如下:

    //其中几个宏定义如下:

    #define SCAN_INTERVAL           0x00A0       /**< Determines scan interval in units of 0.625 millisecond. */

    #define SCAN_WINDOW             0x0050   /**< Determines scan window in units of 0.625 millisecond. */

    #define SCAN_TIMEOUT            0x0000       /**< Timout when scanning. 0x0000 disables timeout. */

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    static ble_gap_scan_params_t m_scan_params=
    {
      .extended       = 1,
        .active        = 0x01,
        .interval      = SCAN_INTERVAL,
        .window        = SCAN_WINDOW,
        .timeout       = 0x0000, // No timeout.
        .scan_phys     = BLE_GAP_PHY_CODED,
        .filter_policy = BLE_GAP_SCAN_FP_ACCEPT_ALL,
    };

     对于扫描来说一下两个参数必须如此才可以扫描到long range广播,注意设置好。

    .scan_phys     = BLE_GAP_PHY_CODED,

    .extended       = 1,//开启拓展的意思

    在增加一个扫描buffer给蓝牙协议栈存数据,不然会报内存不足的错误,如下定义即可,

    static ble_data_t m_scan_buffer =

    {

        m_scan_buffer_data,

        BLE_GAP_SCAN_BUFFER_EXTENDED_MIN

    };

    然后需要把以上两个参数都在scan_init()中进行初始化,两个参数分别赋值如下

    m_scan.scan_params= m_scan_params;

    m_scan.scan_buffer=m_scan_buffer;

    然后再次把以上两个参数赋值给扫描实例,在scan_start()中修改

    m_scan.scan_params= m_scan_params;

    m_scan.scan_buffer=m_scan_buffer;

    修改完成后如图所示:

    以上完成了修改,编译下载即可

    三、总结

    完成以上修改了,主从机板子即可扫描对方,并且广播方式是long range,可以通过RTT可以看到主机扫描的从机设备MAC,即为我们前设置的从机MAC地址。

  • 相关阅读:
    极智开发 | CUDA Compiler NVCC编译流程
    stream对list数据进行多字段去重
    基于Java实现的MD5算法实现
    互联网快讯:多地要求商家下架槟榔;多所高校延长专硕学制至3年
    Linux命令--会话断开后不停止程序--方法/实例
    nginx的优先级和匹配方式
    Python软件编程等级考试四级——20220618
    图论岛屿问题DFS+BFS
    电脑桌面怎样设置闹钟提醒?电脑上定闹钟的方法
    PHP foreach 循环跳过本次循环
  • 原文地址:https://www.cnblogs.com/HW-liu/p/17831451.html