This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Wake on any Event Low Power Mode Using a timed event

I am really new at working with Bluetooth and the various protocols contained within.

I am using SDK 17.0 and drivers 2.7.  I am working on a DK-52 board.

I am working with the HRM Demo.  In particular with the battery service timed event.  I came across the place in the code where the device will go in to sleep mode.  The comments say it should not come back until a button is pushed to wake it up or a reset / powerup occurs.

//---------------------------------------------------------------------------
/**@brief Function for putting the chip into sleep mode.
*
* @note This function will not return.
*/
//---------------------------------------------------------------------------
static void sleep_mode_enter(void)
{
ret_code_t err_code;

err_code = bsp_indication_set(BSP_INDICATE_IDLE);
APP_ERROR_CHECK(err_code);

// Prepare wakeup buttons.
err_code = bsp_btn_ble_sleep_mode_prepare();
APP_ERROR_CHECK(err_code);

// Go to system-off mode (this function will not return; wakeup will cause a reset).
err_code = sd_power_system_off();
APP_ERROR_CHECK(err_code);
}

I never use the buttons on the DK board and from what I am seeing the battery service sends out battery information every couple of seconds.  After so many bursts of information, it appears the device somehow just resets itself and continues the process all over again.

If I wanted to keep the system on, full ram retention and wake on any event, which sd function would I need to call so that I could go into Ultra-low power mode and not lose the bonding information with the client app?  Is there a demo that demonstrates this type of low power mode that I could look at?

Is there a good method that I could use to determine if the client app was bonded with the device and not send battery level info but wait until a bond occurs and then send that battery info across so as not to waste much battery power as well?

Thanks in advance.

Allen Shea

Parents
  • Hello Edvin,

    After some more testing, I am realizing that when the unit is connected to the nRFConnect utility app on the phone, I no longer seem to be going through the main Idle handler anymore.  Below is the code that I expected it to run while connected as well:

    //---------------------------------------------------------------------------
    /**@brief Function for handling the idle state (main loop).
    *
    * @details If there is no pending log operation, then sleep until next the next event occurs.
    */
    //---------------------------------------------------------------------------
    static void idle_state_handle(void)
    {
    ret_code_t err_code;

    err_code = nrf_ble_lesc_request_handler();

    APP_ERROR_CHECK(err_code);

    if (NRF_LOG_PROCESS() == false)
    {
    #ifdef dbg_Time_Idle_Dly

    bsp_board_led_on(3);

    #endif

    nrf_pwr_mgmt_run();

    #ifdef dbg_Time_Idle_Dly

    bsp_board_led_off(3);

    #endif
    }
    }

    It seems to only run this when not connected because it is advertising.  Once connected, it appears the full running of the device occurs until a disconnect and then it goes back into an idle advertising sleep mode of operation.

    Is it possible that sleep / idle mode can be accomplished during the timer event to go read the battery and then go into a low power mode like it does in the advertising mode to conserve more power but have the battery reporting timer control the low power mode?

    Thanks,

    Allen Shea

  • AllenS said:
    It seems to only run this when not connected because it is advertising.  Once connected, it appears the full running of the device occurs until a disconnect and then it goes back into an idle advertising sleep mode of operation.

    In the unmodified example, it reaches idle_state_handle() even if you are connected. 

    AllenS said:
    Is it possible that sleep / idle mode can be accomplished during the timer event to go read the battery and then go into a low power mode like it does in the advertising mode to conserve more power but have the battery reporting timer control the low power mode?

    I am a bit confused about your use of "low power mode". Can we please use the terms "system on mode" and "system off mode"?

    So you want to be connected, use a timer to generate the battery reading and send it over BLE, and be in system on mode. Is that correct?

  • When I spoke of low power mode, I was referring to what is happening during the advertising mode cycling between 1.8 sec off and 200 ms. active times.  On page 77 of the Nordic Datasheet nRF52832 Product Spec v1.4, under the heading Current consumption: Ultra-low power, I was trying to achieve the mode of ultra low power described as: System ON, Full RAM retention, Wake on any event because the consumption amount is 1.5 uA.  When you come out of Ultra low power mode and have already connected with the phone app, the battery reporting timer service would send out the updated battery status and then go back into the previously described Ultra low power mode until the next timed interval occurs to transmit another updated battery status.

    Once the phone app disconnects, then the remote device would need to go back into the advertising cycling mode as I described earlier.

    To answer your question, I do want to be in a system on mode because the design I am working with will not have a physical input that I can use to wake up the remote device from a system off mode so it needs to be a system on mode as I described before.

    I will look around and see if I can identify where the idle mode is occurring once the remote device has connected to the phone app.  Maybe there is a different handler being specified once the connection has occurred that I have not noticed yet.  If you have any suggestions on how to track that down, I am open to suggestions.

Reply
  • When I spoke of low power mode, I was referring to what is happening during the advertising mode cycling between 1.8 sec off and 200 ms. active times.  On page 77 of the Nordic Datasheet nRF52832 Product Spec v1.4, under the heading Current consumption: Ultra-low power, I was trying to achieve the mode of ultra low power described as: System ON, Full RAM retention, Wake on any event because the consumption amount is 1.5 uA.  When you come out of Ultra low power mode and have already connected with the phone app, the battery reporting timer service would send out the updated battery status and then go back into the previously described Ultra low power mode until the next timed interval occurs to transmit another updated battery status.

    Once the phone app disconnects, then the remote device would need to go back into the advertising cycling mode as I described earlier.

    To answer your question, I do want to be in a system on mode because the design I am working with will not have a physical input that I can use to wake up the remote device from a system off mode so it needs to be a system on mode as I described before.

    I will look around and see if I can identify where the idle mode is occurring once the remote device has connected to the phone app.  Maybe there is a different handler being specified once the connection has occurred that I have not noticed yet.  If you have any suggestions on how to track that down, I am open to suggestions.

Children
  • What does your main loop look like? It should call sd_app_evt_wait() directly or indirectly (through some idle_state_handle() function or something). If so, then the device should reach the low power mode that you can use while using the softdevice actively. Unless you are hanging in an interrupt somewhere, the main loop should be reached after any interrupt.

    Best regards,

    Edvin

  • This is the entry into the main loop:

    #ifdef dbg_UART_Msgs

    printf("Starting Main Loop.\r\n");

    #endif

    // Enter main loop.
    for (;;)
    {
    // #ifdef dbg_Time_Idle_Dly

    // bsp_board_led_on(3);

    // #endif

    idle_state_handle();

    // #ifdef dbg_Time_Idle_Dly

    // bsp_board_led_off(3);

    // #endif
    }

    When it went into Idle_State_Handle(), that was the function I showed in a previous post.  So you are definitely right about the execution going off somewhere else and upon a disconnect it will come back to the main loop and the Idle routine.  More investigation needs to be done to figure out way but at least now I have something to look for.

    Anyway, the project spec changed and I am being asked to advertise every x seconds and send the battery level when the advertise is transmitted.  Any suggestions about that or should I close this discussion and start a new one.  I do have some ideas on things to experiment regarding this to see if it will work.

  • AllenS said:
    advertise every x seconds and send the battery level when the advertise is transmitted.

    What do you mean by this? Do you intend to include the battery level in your advertisement, or are you connected to the device that you send the battery level to?

    BR,

    Edvin

  • Based on my understanding of the new requirement, it would be to blindly send out the battery level and not require any type of connection from the cell phone app.  The cell phone app is looking for the MAC address of the remote device and just the battery level info.  They are now saying that with the 30 mAH battery, I would need to put the device into a System Off, No RAM retention, wake on GPIO mode.  That should get me to 0.3 uA over a period of 9 Secs will only draw 2.7 uA.  I would just need to figure out how much current would be needed to come up and send out the data and then go back into that deep sleep mode.  For the GPIO, I would just use a simple RC network for the delay.  Would it be easier for me to look at a different demo that is more targeted to this approach?  If so, which one would you suggest?

  • Without connections and some battery info, this sounds like a typical beacon application. Just be aware that there is no way to guarantee that an advertisement is picked up, so the typical way here is to advertise more than once before going back to sleep. You should look into advertisement intervals and scan intervals and scan windows. You can read about it in this guide.

    I also suggest that you look into the online power profiler.

    Perhaps settings like this is something you are looking for:

    I think you would want to look into the ble_app_uart example, as this is probably the closest you are looking for. Just be aware that this example is not using the advertising module, but setting up the advertisements manually. So perhaps just disable the scan response and set the advertising type from connectable to unconnectable in whatever ble_peripheral example is just as easy.

    Best regards,

    Edvin

Related