2017年8月30日 星期三

nRF5x: change advertising data manually without re-start

unlike other BLE MCU, nRF5X is able to change advertising data without restart .
the example shows how to easily change BLE peripheral advertising data, so the central can watch status of peripheral without connect it.


*
about how to start UART printf
please read this article:
http://gaiger-programming.blogspot.tw/2016/12/nrf51-make-printf-works-well.html


STEP 1. make advertising non-stop
open "ble_app_template" form:
\nRF5x_SDK_11.0.0\examples\ble_peripheral\ble_app_template

change ble device name at about line 63

#define DEVICE_NAME                      "advertising test"  

change APP_ADV_TIMEOUT_IN_SECONDS  at about line 65

#define APP_ADV_TIMEOUT_IN_SECONDS       0                                        

and in advertising_init( ) function
change advdata.flags

    uint32_t      err_code;
    ble_advdata_t advdata;
    
    memset(&advdata, 0, sizeof(advdata));

    advdata.name_type               = BLE_ADVDATA_FULL_NAME;
    advdata.include_appearance      = true;
    advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    advdata.uuids_complete.p_uuids  = m_adv_uuids;

    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, NULL, &options, on_adv_evt, NULL);
  
	
    APP_ERROR_CHECK(err_code);                                       

re-build all and load to your board , you can see its advertising never-stop,
and the adverting raw data will be like:



"6164766572746973696e672074657374" in hex are "advertising test" in string.


STEP 2. add a repeated timer to change advertising data manually

add this definition at about line 95

APP_TIMER_DEF(m_adv_name_change_timer_id);
#define ADV_NAME_CHANGE_INTERVAL            APP_TIMER_TICKS(1*1000, APP_TIMER_PRESCALER)
I set the timer repeated in 1 second interval.

and create timer in timers_init( )


uint32_t err_code;
err_code = app_timer_create(&m_adv_name_change_timer_id,
                            APP_TIMER_MODE_REPEATED,
                            adv_name_change_timeout_handler);

APP_ERROR_CHECK(err_code);

add  adv_name_change_timeout_handler( )

#define DEVICE_NAME_1 "0987654321"
#define DEVICE_NAME_2 "1234567890"
static uint8_t index = 0;
static void adv_name_change_timeout_handler(void * p_context)
{
	UNUSED_PARAMETER(p_context);	
	uint32_t err_code;
	
	printf("change adv name\r\n");	

	ble_gap_conn_sec_mode_t sec_mode;
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
	
	
	if (0==index)
	{
		err_code = sd_ble_gap_device_name_set(&sec_mode,
                 (const uint8_t *)DEVICE_NAME_1,strlen(DEVICE_NAME_1));

		APP_ERROR_CHECK(err_code);
		index = 1;																		
	}
	else if (1==index)
	{
		err_code = sd_ble_gap_device_name_set(&sec_mode,
                 (const uint8_t *)DEVICE_NAME_2,	strlen(DEVICE_NAME_2));

		APP_ERROR_CHECK(err_code);
		index = 0;								
	}
	
	
	ble_advdata_t advdata;
	memset(&advdata, 0, sizeof(advdata));

	advdata.name_type               = BLE_ADVDATA_FULL_NAME;
	advdata.include_appearance      = true;
	advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
	advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
	advdata.uuids_complete.p_uuids  = m_adv_uuids;
																				
	err_code = ble_advdata_set(&advdata,NULL);																			
	APP_ERROR_CHECK(err_code);
	
}


start the timer at application_timers_start( )

uint32_t err_code;
	
err_code = app_timer_start(m_adv_name_change_timer_id, ADV_NAME_CHANGE_INTERVAL, NULL);	
APP_ERROR_CHECK(err_code);

press rebuild-all and load to your board



STEP 3: check advertising data of your device
the adverting raw data will change from



to


in 1 sec interval.


note:
1. in nrf_connect app you can see more detail about the advertising raw data fields:



2. the max length of device name is 29 byte, which can have many usage.
reference : https://devzone.nordicsemi.com/question/121842/max-length-of-the-device-name-in-nrf52832/































沒有留言:

張貼留言