Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

High power consumption of softdevice

Hello!

I am working on firmware for device that has freertos in the base and implements BLE beacon and 1 service with 7 characteristics. Everything works. But power consumption is too high.

After plenty of tests on final HW, I've created playground based on ble_app_hrs_freertos_pca10040_s132 sample project and switched to sparkfun board.

When have just FreeRTOS with no user-defined tasks, consumption is about 1uA.

After I call  ble_stack_init with code below, I got about 500uA. It is without advertising at all.

static void ble_stack_init(void)
{
    ret_code_t err_code;

    err_code = nrf_sdh_enable_request();
    APP_ERROR_CHECK(err_code);

    // Configure the BLE stack using the default settings.
    // Fetch the start address of the application RAM.
    uint32_t ram_start = 0;
    err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
    APP_ERROR_CHECK(err_code);

    // Enable BLE stack.
    err_code = nrf_sdh_ble_enable(&ram_start);
    APP_ERROR_CHECK(err_code);

    // Register a handler for BLE events.
    NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
}

When beacon is enabled I have cca 650uA.

When GATT and beacon are working I have cca 750uA.

I measure with multimeter.

Results seems fine for me except for those 500uA after stack is initialized. Why is it so high? What can I do to lower it?

  • SDK v 15.0
  • NRF_LOG_ENABLED is 0
  • Using RELEASE configuration.
  • Tried S132 and S140 - result is the same
  • Hi Rahmat,

    yes, make sure that UART and logging is switched off in your sdk_config.h and that you are not running your application with debugger.

    Maybe some more information about your application could help to point you.

    Cheers,

    Elias

  • Got it, Thanks. Just wanted to start with the right template. Was surprised it consumed a few hundred microAmps with example codes

  • In addition to the FPU and SAADC interrupt-issues Elias Löwe mentions further down, I ran into another issue:

    sd_app_evt_wait();
    returns immidiately the first time it is called (it is also reported here) and power consumption is many milliamps. You probably used WFE in SDK15 instead because you ran into this bug/issue that seems to be intermiettent..

    It works for me if I duplicate a second call

    #ifdef SOFTDEVICE_PRESENT
                if (nrf_sdh_is_enabled())
                {
                    uint32_t err_code = sd_app_evt_wait();
                    APP_ERROR_CHECK(err_code);
                    err_code = sd_app_evt_wait();
                    APP_ERROR_CHECK(err_code);
                }
                else
    #endif

    If it just need to be called again, then why doesnt it work when vPortSuppressTicksAndSleep() is called again almost immidiately by the idle task?

    I dont know. Whatever condition that makes sd_app_evt_wait(); return immidiately seems to be triggered again by the the exit and reentereance into vPortSuppressTicksAndSleep().

    In summary, the complete checklist that made it work for me was (I dont use SAADC so it wasnt an issue for me):

    • Install an FPU interrupt handler that clears the FPU errors
    • Call sd_app_ewt_wait() twice in vPortSuppressTicksAndSleep()
Related