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?

  • Glad to help, marking the right answer will help others;)

  • Hmm.. my suspicion is that sd_ble_gap_adv_start() actually sets the radio into RX on because it will wait for a device to connect (but joke's on them since beacons are unconnectable). So, that's why it draws 20 mA for the time when the radio is ON (measured with a scope.. and verified my other claims with a scope too). You don't buy this explanation, do you?

  • Oh no, you can be sure that by calling thse SD function you would cause radio to be turned ON all the time (and Rx wouldn't make any sense!). That's not how BLE works, the "low energy" is achieved exactly by that trick of time synchronized Tx/Rx events and long times of complete "silence" when MCU is in deep power saving mode unless it does something else then serving BLE radio. You can turn Rx for continuous time but that's only in GAP Central/Observer role where you scan for advertisements. The connection Rx window happens exactly 150us after each connectable ADV_xxx packet and it doesn't need to be longer then few microseconds (if there is nothing detected) so no, SD is not listening for incoming CONNECT_REQ all the time;)

  • Oh man, I did not know that! Can you share what awesome resources you have read to learn about the finer details of BLE? Also, this means that my mystery isn't solved yet.. I don't think the CPU spinning in a while (true) {} will take 20 mA, would it?

  • Yes, you will need to do some more debugging and make sure HW is correct (probably trying some basic loop scenarios with special FWs and measure that characteristic) and then check SW (you probably run some busy-loop or similar heavy activity somewhere and it's most probably triggered by your code...) The guide from Nordic I've linked in one previous answer up this thread is answering many details, I have nothing to add to it.

    When it comes to general BLE knowledge I can recommend two sources:

    • original BLE training presentation from BT SIG (it's from 2010 so you need to understand that it covers only 4.0/4.1 but most of new features added in 4.2 and 5.0 are just expanding not changing the basic principles). I use it as quick reference till today.

    (1/2)

Related