NORDIC广播小结

使用nordic 51422开发板 sdk11.0

转载:http://blog.sina.com.cn/s/articlelist_3009267553_0_3.html

1、使用串口通信时,默认是使用rts和cts功能开启的,使用usb转ttl时候,需要将该功能关闭APP_UART_FLOW_CONTROL_DISABLED,并检查在c/c++选项板中是否需要添加头文件以选择是uart还是rtt功能

2、广播数据都在ble_advdata_t advdata结构体中实现,需要自定义数据时候,需在advdata.ble_advdata_manuf_data_t中添加,注意结构体中含有指针的时候,该指针需要初始化才能使用。

3、实现无限非连接广播

Advertising_init()àBLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE改为BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE,广播超时后,仍能继续发送

 

在ble_evt_dispatchàble_advrtisign_on_ble_evtàBLE_ADV_MODE_FASTàBLE_ADV_MODE_SLOWà 改为BLE_ADV_MODE_FAST 防止在超时后,广播由fast模式转换到slow模式,然后在转换到idle模式,这样会导致停止广播,或者直接将APP_ADV_TIMEOUT_IN_SECONDS设置为0也可以(注:不会进入ble_evt_dispatch函数,此例程不用)。

4、将ble_advertising_start()àadv_params.type= BLE_GAP_ADV_TYPE_ADV_INDà改为BLE_GAP_ADV_TYPE_ADV_SCAN_IND,只准扫描,不可以连接

5、设置发射功率

 int8_t tx_power                 = 0;

advdata.p_tx_power_level        = &tx_power;

6、广播中的厂商自定义数据可以提供给用户使用,目前只能发送最大为10个字节的数据。

 

ble_advdata_manuf_data_t        manuf_data;

uint8_t data[]= {0xa1,0xb2,0xc3,0xd4,0xe5,0xa6,0xb7,0xc8,0xd9,0xab};

//uint8_t data[]                      = "SomeDataa";

manuf_data.company_identifier       = 0x0059; // Nordics company ID

manuf_data.data.p_data              = data;    

manuf_data.data.size                = sizeof(data);

.

.

.

advdata.p_manuf_specific_data   = &manuf_data;

 

备注:广播包最多为31个字节,且先发送小端。无连接的广播最小间隔为100ms

 

 

From: http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=28852942&id=5753308

首先了解 4.0中链路层的包格式如下:

       PDU即协议数据单元,即链路层的负载数据。应用层用户发送的数据就是在这里面,但是并不全是用户数据。

Ble有分广播态和连接态。所以上面的这个链路层帧可能是广播数据也可能是连接后的数据。 所以就有两种情况,一种为 广播通道中的PDU,另一种为数据通道中的PDU。我们主要讨论的是连接态下的数据通道中的数据帧,这里广播通道下简单介绍下。

广播态下,广播帧中的PDU如下图所示,包含2字节的头,其后的payload即为广播数据,比如通常我们设置的设备名,厂商自定义数据等都在这里面,广播数据肯定包含设备的地址,所以payload中的前6字节为设备地址

nrf51822广播小结

nrf51822广播小结
nrf51822广播小结

 

在ble_evt_dispatch超时分配函数中,使用advertising_init()和ble_advertising_start()重新启动广播的方式会导致广播不能被扫描,采取下面的方式。

ble_advertising_start由广播超时ble_evt_dispatch函数中的ble_advertising_on_ble_evt启动,添加

 

case BLE_ADV_MODE_FAST:

adv_params.timeout  = m_adv_modes_config.ble_adv_fast_timeout;

adv_params.interval = m_adv_modes_config.ble_adv_fast_interval;

for(uint32_t i = 0; i < m_advdata.p_manuf_specific_data->data.size; i++)

{

    m_manuf_data_array[i] = my_count++;

}

err_code               = ble_advdata_set(&m_advdata, NULL);

VERIFY_SUCCESS(err_code);

能实现10个字节的动态传送,如果不够可参考:https://devzone.nordicsemi.com/tutorials/5/

 

Scan response data

But what if you really, really want to advertise more than 31 bytes? Then there is a solution for you and that is the Scan response data. This is an optional "secondary" advertising payload which allows scanning devices that detect an advertising device to request a second advertising packet. This allows you to send two advertising frames with a total payload of 62 bytes.

 

Challenge: In your code, immediately above the line err_code = ble_advdata_set(&advdata, NULL), do the following:

  1. Declare a new "ble_advdata_manuf_data_t" type variable called "manuf_data_response".
  2. Populate "manuf_data_response" with data as we did with the first advertising packet.
  3. Declare a new "ble_advdata_t" type variable called "advdata_response".
  4. Populate "advdata_response" with name type "BLE_ADVDATA_NO_NAME".
  5. Populate "advdata_response" with your new manufacturer specific data.
  6. Change the line

    err_code = ble_advertising_init(&advdata, NULL, &options, on_adv_evt, NULL);

    to

    err_code = ble_advertising_init(&advdata, advdata_response, &options, on_adv_evt, NULL);
  7. Compile, download and see what happens.

This should make your device look something like this in MCP: Advertising with Scan response

In case you need help your advertising_init() function should now look similar to this:

static void advertising_init(void)
{
    uint32_t      err_code;
    ble_advdata_t advdata;  // Struct containing advertising parameters

    ble_advdata_manuf_data_t        manuf_data; // Variable to hold manufacturer specific data
    uint8_t data[]                      = "SomeData!"; // Our data to adverise
    manuf_data.company_identifier       = 0x0059; // Nordics company ID
    manuf_data.data.p_data              = data;     
    manuf_data.data.size                = sizeof(data);

    // Build advertising data struct to pass into @ref ble_advertising_init.
    memset(&advdata, 0, sizeof(advdata));

    advdata.name_type               = BLE_ADVDATA_SHORT_NAME;
    advdata.short_name_len          = 3;
    advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    advdata.p_manuf_specific_data   = &manuf_data;
    int8_t tx_power                 = -4;
    advdata.p_tx_power_level        = &tx_power;
    advdata.include_appearance      = true;

    // Prepare the scan response Manufacturer specific data packet
    ble_advdata_manuf_data_t                manuf_data_response;
    uint8_t                                 data_response[] = "Many_bytes_of_data"; // Remember there is a 0 terminator at the end of string
    manuf_data_response.company_identifier       = 0x0059;               
    manuf_data_response.data.p_data              = data_response;        
    manuf_data_response.data.size                = sizeof(data_response);

    ble_advdata_t   advdata_response;// Declare and populate a scan response packet

    // Always initialize all fields in structs to zero or you might get unexpected behaviour
    memset(&advdata_response, 0, sizeof(advdata_response));
    // Populate the scan response packet
    advdata_response.name_type               = BLE_ADVDATA_NO_NAME; 
    advdata_response.p_manuf_specific_data   = &manuf_data_response;

    ble_adv_modes_config_t options = {0};
    options.ble_adv_fast_enabled  = BLE_ADV_FAST_ENABLED;
    options.ble_adv_fast_interval = APP_ADV_INTERVAL;
    options.ble_adv_fast_timeout  = APP_ADV_TIMEOUT_IN_SECONDS;

    err_code = ble_advertising_init(&advdata, &advdata_response, &options, on_adv_evt, NULL);
    APP_ERROR_CHECK(err_code);
}

猜你喜欢

转载自blog.csdn.net/Z_HUALIN/article/details/81510317
今日推荐