使用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字节为设备地址
在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/
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:
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);
This should make your device look something like this in MCP:
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);
}