【筆記】nrf52832廣播使用--廠商自定義資料應用

Tomas_L發表於2020-11-13

  需求:

  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的設定範圍為固定值,可以檢視協議棧文件,如下

 

 

完成需求。

相關文章