需求:
1)使用藍芽不停傳送ble廣播,傳送自定義的資料,並每一秒更新自定義資料。
2)設定不同的發射功率、廣播間隔、廣播名稱
1、初始化
使用nordic官方sdk17版本,開啟一個ble串列埠用例。首先在main函式初始化ble,這個sdk已經給我們準備好了。
int main(void) { log_init(); timers_init(); flash_init(); buttons_leds_init(&erase_bonds); power_management_init(); //電源管理 ble_stack_init(); //協議棧初始化 gap_params_init(); //gap配置初始化 gatt_init(); //gatt初始化 advertising_init(); //廣播引數配置 services_init(); //服務初始化 conn_params_init(); // 連線引數初始化 peer_manager_init(); //連線引數更新 tx_power_set(-20); //設定發射功率 application_timers_start(); //開啟定時器 advertising_start(erase_bonds); //開啟廣播 read_flash_sw_mode(); //讀取flash中 儲存的資料 // Enter main loop. for (;;) { idle_state_handle(); } }
2、設定一個軟體定時器,更新資料
建立定時器app_timer_create(),設定為迴圈模式,然後定時1s啟動它。在定時回撥中,我們來更新廣播自定義資料。
需要注意,更新自定義資料需要先停止廣播,然後把自定義資料進去,再重新開始廣播。這裡停止直接呼叫協議棧的
sd_ble_gap_adv_stop()函式。
static void adv_data_update(uint8_t *p_data){ sd_ble_gap_adv_stop(m_advertising.adv_handle); manuf_spec_data.data.p_data=p_data; manuf_spec_data.data.size = 1; init.advdata.p_manuf_specific_data = &manuf_spec_data; ret_code_t err_code = ble_advertising_init(&m_advertising, &init); APP_ERROR_CHECK(err_code); ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG); err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST); APP_ERROR_CHECK(err_code); } static void TIME_timeout_handler1(void * p_context) { UNUSED_PARAMETER(p_context); static uint8_t i=0; i++; switch(i){ case 1: adv_data_update(my_adv_G_data); break; case 2: adv_data_update(my_adv_B_data); break; case 3: i=0; adv_data_update(my_adv_R_data); break; default:break; } }
3、隱藏廠商ID
完成以上步驟後,基本完成了需求1),但是有個廠商的ID會佔有資料位,這不是我們需要的。
通過修改庫函式來把它隱藏。
首先進入到ble_advertising_init(),找到ble_advdata_encode()函式,找到自定義資料的程式碼:
// Encode Manufacturer Specific Data. if (p_advdata->p_manuf_specific_data != NULL) { err_code = manuf_specific_data_encode(p_advdata->p_manuf_specific_data, p_encoded_data, p_len, max_size); VERIFY_SUCCESS(err_code); }
然後,繼續進入manuf_specific_data_encode()函式,去掉它的資料長度:
再去掉廠商資料:
這樣,我們的自定義資料,就不再顯示廠商ID了:
4、傳送功率、廣播間隔和廣播名字
這三個引數修改,不需要停止廣播:
tx_power_set(4); //設定功率 init.config.ble_adv_fast_interval = 35; //設定傳送間隔 ret_code_t err_code = sd_ble_gap_device_name_set(&sec_mode, //修改名字 (const uint8_t *)DEVICE_NAME3, strlen(DEVICE_NAME3));
其中傳送功率是直接呼叫協議棧API
static void tx_power_set(int8_t power) { ret_code_t err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, m_advertising.adv_handle, power); APP_ERROR_CHECK(err_code); }
power的設定範圍為固定值,可以檢視協議棧文件,如下
完成需求。