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

Sleep Immediately after Beacon Advertisement

I'm using the following code to make the beacon sleep:

static void on_ble_evt(ble_evt_t * p_ble_evt)
{
    uint32_t        err_code;
    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
        {
            break;
        }
        case BLE_GAP_EVT_TIMEOUT:
        {
            if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING)
            {
                sd_ble_gap_adv_stop();
                ble_fsm_set_state(Ble_Fsm_State_Idle);
            }
            break;
        }
        default:
        {
            break;
        }
    }
}

Once the state is set to idle, the nrf51 chip goes to sleep and the current draw drops to the order of uA. My only problem here is that the minimum timeout value is 1s and this means that the chip is burning power for 1s. Ideally, I would like the beacon to just advertise once and then go to sleep immediately. What is the best way to do this? Adding a synchronous delay of 5 ms? Any callback that I can use instead?

  • Not really. Radio as such (the specific part of nRF5x SoC which does 2.4GHz radio Tx/Rx) is most of the time OFF. The call sd_ble_gap_adv_start is just function call from Soft Device (stack) API and you can be sure that stack isn't stupid to power radio all the time, it just runs RTC timer to wake it put for the shortest time necessary. So yes, by turning the advertisement off will safe some power but it will be only very little for these few missing Tx/Rx bursts of radio (typically up to 1.5ms per whole adv. interval, see charts in Soft Device specification) and the power to run RTC timer. If you want to count single adv. events then you have two options:

    (1/3)

  • (2/3)

    • If there is no other SoftDevice radio activity happening then use radio_notification handler, it will wake you up exactly before and after every adv. event (typically burst of 3 Tx packets and optionally some Rx and more Tx windows if the advertisement is connectable/scannable).
    • If there is more radio activity or if you don't like radio_notification method then you can only run your separate RTC timer in APP code and act accordingly (note that advertising has mandatory jitter from BT SIG specification so each adv. interval isn't the same, only in average it should be at adv. interval period, so you need to run timer with some delay to be sure that particular event happened and be able to accept still some small chance that few intervals will be too short or too long and they will run out of your timer window...)
  • (3/3)

    Also note that you cannot run sd_ble_gap_adv_stop directly in radio_notification handler, you can only make a flag and schedule it for later. Or to be precise you can stop the adv. there but it might have consequences with wrong triggers of radio_notification handler afterwards...

    (and last note: I really believe that your hope in saving power by turning adv, off is too high: yes, it will make a difference but not more than dozens of %, you won't suddenly drop to microAmp region, that's possible only in true POWER OFF...)

  • Super weird, because if I call sd_app_evt_wait() before sd_ble_gap_adv_stop(), then it consumes 20 mA. But if I call the two functions in the opposite order, I get a sleep current of a few uA. Definitely going to give radio_notification a shot. Thanks for the super quick responses! You've been a huge help!

  • Are you sure those are long-term averaged values? In short time of Tx and Rx activity radio can cause PCB to consume dozens of mA as spike values (even that might be good point for redesign if you are having custom HW) but not long-term. That would indicate either wrong measurement method or something terribly wrong in your HW&FW set-up. Note how usual power consumption curve looks like with Nordic Power Profiling Kit (PPK) on nRF52 DK (simple advertising by using exactly the same function as you do).

Related