This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Can I change nRF5 bluetooth advertising interval dynamically?

I would like to dynamically change bluetooth LE advertising interval. I am using nRF51 and nRF52, with SDK's 8 and 12. Is that possible and how to do it?

Our application has kind of "interactive demo" mode needing short interval, but it dynamically changes into the real operating mode when time passes. To save power, advertising interval should then be made longer.

  • Hi,

    The advertising module have two different modes you can use for this. ADV_MODE_FAST and ADV_MODE_SLOW, and you can specify the advertising interval you want for each mode. The advertising will start in ADV_MODE_FAST, and switch to ADV_MODE_SLOW after a specified timeout period(APP_ADV_FAST_TIMEOUT_IN_SECONDS). The ADV_MODE_SLOW also has a timeout period, and when expired it will switch to ADV_MODE_IDLE and stop advertising.

    ble_adv_modes_config_t options;
    memset(&options, 0, sizeof(options));
    
    options.ble_adv_fast_enabled  = true;
    options.ble_adv_fast_interval = APP_ADV_FAST_INTERVAL;
    options.ble_adv_fast_timeout  = APP_ADV_FAST_TIMEOUT_IN_SECONDS;
    
    options.ble_adv_slow_enabled  = true;
    options.ble_adv_slow_interval = APP_ADV_SLOW_INTERVAL;
    options.ble_adv_slow_timeout  = APP_ADV_SLOW_TIMEOUT_IN_SECONDS;
    

    With limited discoverable mode(BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE) it is not allowed to advertise longer than the timeout period. But if you don't want the advertising to stop in the ADV_MODE_SLOW mode, you can switch to general discoverable mode(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE), and set the timeout to 0 to do unlimited advertising:

    advdata.flags                 = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    options.ble_adv_slow_timeout  = 0;
    
  • Okay, thanks for that. However, the code from SDK8 doesn't seem to support that.

    Also, if I want to get bak from slow mode to fast mode, how to do that?

  • If you want to go back to fast mode, you have to first temporarily stop the advertising, and then start in fast mode again.

    err_code = sd_ble_gap_adv_stop();
    err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
    
  • Jarmo, We developed our product in SDK11 and there wasn't support for this built in. However, you can do the same thing by just tying the advertising interval to a variable.

    So you init like this:

    static void advertising_init(uint32_t adv_interval )
    { ...
    		m_adv_params.interval = adv_interval;
    ...}
    

    As Sigurd said you must first stop advertising:

    						err_code = sd_ble_gap_adv_stop();
    						APP_ERROR_CHECK(err_code);
    

    Then init with whatever period you choose (here it is 3200*.625usec or 2second interval):

    						advertising_init(3200);
    

    And finally start advertising:

    						err_code = sd_ble_gap_adv_start(&m_adv_params);
    						APP_ERROR_CHECK(err_code);
    

    I should caution you that the power requirements to re-init and re-start advertising are substantial. If your coin cell is already mostly depleted the device may well brown out and reboot.

  • Okay, thank you very much about those hints! I think I can now implement the thing :)

Related