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 mostly in sleep mode using nRF52832 ?

Hi,

We have developed one application using nRF52832 SoC and Sdk v15.0. For our application we have use ble_app_uart example as a peripheral and multi-link central example.

ble_app_uart peripheral is used as a sensor node with SAADC example merged and which is on battery powered device. Our application is sensor node wake up every 1 Hr and send sensor data to central device then it will go in sleep mode. When i measured current it is very high as per the following with DCDC enabled:

  • When sensor node(ble_app_uart) advertising = 3.50mA
  • When connected to central and sending analog value = 3.1 to 5mA peak.
  • After done sending sensor node goes into deep sleep mode = 0.5mA.

Questions:

  1. Why 0.5mA is consume is system OFF mode how can reduce this consumption upto 50uA.
  2. 2 sleep mode: system on mode and system OFF mode which one is best and very low power consumption and also able to trigger by RTC.
  3. If we use system OFF mode in sensor node for low power consumption is any way to wakup by external low power RTC, if yes How?
  4. How i can go my sensor node into system ON mode after done sending data to central.
  5. Please suggest if any changes in sensor node program for ultra low power solution? we are using SAADC, UART, BLE.
  6. We need at least 1.5- 2 year battery life for sensor node only using coin any cell (1000mAh). How i can achieve this?

Thanks in advanced...!!!

Parents
    1. System OFF consumes about 0.3µA. If you see 0.5mA there must be something else that is drawing the current.
    2. System OFF means that you turn off the chip, including the RTC. It cannot wake up by RTC. Here is a description of what can wake the chip up. In other words: it needs an external  signal to wake up. It wakes up in RESET state. System ON is when the chip is operational. If you want low power consumption in system ON you need to turn off every peripheral that is consuming power and also put the CPU in a WFE (wait for event) loop.
    3. You can wake the chip up from system OFF by using an external RTC. The external RTC needs to toggle one of the GPIOs on the nRF chip.
    4. The chip is always in system ON mode when operational. Make sure that the main loop sets the CPU in WFE state when not used. If you are using the softdevice examples this is automatically handled. This is what is called System ON IDLE mode (when the CPU is not working).
    5. Make sure that peripherals are powered off when you are not using them. Use long BLE advertising/connection intervals.
    6. It depends on your application if you are able to achieve this or not. You need to figure out the requirements of your application. But if it only wakes up every hour I don't think this should be any problem. You can use this power calculator to see the average current in different BLE modes.
  • Thanks for your great answer..!!!

    Now i have tested current consumption in my other board now it is consume in system off mode = 320uA. It is very high as well. Please help me how i can reduced this current consumption. Where should i wrong i am confused and not understating why this high consumption in system off mode. For reference here is my main function init:

    int main(void)
    {
        bool erase_bonds;
        uint32_t err_code;
    
        // Initialize.
        uart_init();
        log_init();
        timers_init();
        buttons_leds_init(&erase_bonds);
        power_management_init();
        ble_stack_init();
        gap_params_init();
        gatt_init();
        services_init();
        advertising_init();
        conn_params_init();
        saadc_init();
        saadc_sampling_event_init();
        saadc_sampling_event_enable();
        advertising_start();
        // Start execution.
    //    printf("\r\nUART started.\r\n");
        NRF_LOG_INFO("Debug logging for UART over RTT started.");
    
        // Enter main loop.
        for (;;)
        {
            err_code = sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE);  // Enable DCDC Mode for LOW power Consumption
            APP_ERROR_CHECK(err_code);
            idle_state_handle();
        }
    }
     

    If i use system ON mode and wake up by RTC, once done job of BLE how i can turn off my all peripheral in my program where should i need to change code. Please suggest changes?

    What is normal current consumption in System ON idle mode if using UART, SAADC, BLE peripheral. Is 1.9 uA as per data sheet?

    Thanks..!!!

  • Make sure that logging is disabled in sdk_config.h. Look for NRF_LOG_ENABLED and set this to 0

    Also initialize the SAADC in low power mode. Please read more about this here: http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk5.v15.0.0/hardware_driver_saadc.html?cp=4_0_0_2_0_12_1_1#saadc_nonblocking

    So if you want to wake up by RTC you typically want to start SAADC, UART and BLE in the RTC interrupt function. I don't know how your system is going to work, but in general, lets say you want to notify the central with the data you collected, you send out a notification, and in the callback function you check if more is available, if not you terminate the BLE connection, stop UART etc..

    You can check out the BLE UART example, this shows how you can send/receive data on UART and forward it over BLE. In this example you see how the callback functions work.

    You don't have to call sd_power_dcdc_mode_set in the main loop. It's enough to call it once after initializing the softdevice.

    Normal system ON IDLE current is 1.9uA. While you are using UART you can expect 1-2mA so you need to disable the UART after the data has been transmitted. 1.9uA is when the softdevice is running (BLE active). SAADC has a low power mode so this should not add anything to the IDLE current.

  • I have disabled in sdk_config.h. Look for NRF_LOG_ENABLED 0 and then measured current consumption it looks while adv. = 3.38mA but not effect on system of current consumption still remains same. 

    The following function i used for disable all peripheral:

    void stop_adc()
    {
        NRF_LOG_INFO("SAADC Stop\r\n");
        nrf_drv_timer_disable(&m_timer);
        nrf_drv_timer_uninit(&m_timer);
        nrf_drv_ppi_channel_disable(m_ppi_channel);
        nrf_drv_ppi_uninit();
        nrf_drv_saadc_abort();
        nrf_drv_saadc_uninit();
        while(nrf_drv_saadc_is_busy());
    }
    
        err_code = app_uart_close();
        APP_ERROR_CHECK(err_code);

    The above functions i have call after sending data, is this functions is correct but i am not sure weather it really shut down SAADC and UART or not.

    I want to use system ON IDLE mode and wake up by timer or RTC so able to trigger sensor every 1 Hr by software interrupt.

    Please tell me effective method for disable all peripherals such as BLE, SAADC, UART after transmitted data. so then i can measure current consumption in system ON mode. 

    Can you please provide me small program code for disabling all peripheral and where should i need to define in main loop or somewhere other?

    for (;;)
      {
          idle_state_handle();
      }

     I am using 3 ADC channels for accelerometer sensor is it need also disable analog GPIO port. which function use for disable GPIO. 

    As lowest possible to optimize sleep current is most important for us..!!

    Thanks...!!

  • Try to stop SAADC sampling before disabling the peripheral:

    void stop_adc()
    {
        nrf_drv_timer_uninit(&m_timer);
        nrf_drv_ppi_channel_disable(m_ppi_channel);
        nrf_drv_ppi_uninit();
        NRF_SAADC->TASKS_STOP = 1;
        nrf_drv_saadc_uninit();
    }

    err_code = app_uart_close();
    APP_ERROR_CHECK(err_code);

    Where you want to put this depends on how you want the application to work. If the BLE transmission defines the end of the applications "tasks" you would typically want to place this in one of the callback functions handling the BLE transmission. Or you can set a flag in the BLE transmission callback, and check for this flag in the main loop.

    The softdevice (BLE) does not have to be disabled. After you disconnect from the central, just make sure that advertising is not started. It will not consume anything in addition to what the RTC consumes.

Reply
  • Try to stop SAADC sampling before disabling the peripheral:

    void stop_adc()
    {
        nrf_drv_timer_uninit(&m_timer);
        nrf_drv_ppi_channel_disable(m_ppi_channel);
        nrf_drv_ppi_uninit();
        NRF_SAADC->TASKS_STOP = 1;
        nrf_drv_saadc_uninit();
    }

    err_code = app_uart_close();
    APP_ERROR_CHECK(err_code);

    Where you want to put this depends on how you want the application to work. If the BLE transmission defines the end of the applications "tasks" you would typically want to place this in one of the callback functions handling the BLE transmission. Or you can set a flag in the BLE transmission callback, and check for this flag in the main loop.

    The softdevice (BLE) does not have to be disabled. After you disconnect from the central, just make sure that advertising is not started. It will not consume anything in addition to what the RTC consumes.

Children
  • Thanks for your reply..

    I have call this function sd_ble_gap_adv_stop(m_conn_handle); after completed three channel but BLE advertising is not stop. I have also check disconnect event and not started again advertising. 

    Will you please provide me small program snippet for how i can do this.

  • Hi Stian,

    I have use app timer for wake up our sensor devices for every one hour. As you mentioned in your above reply i have call this all turn off peripherals in callback BLE transmission once done. But still my sensor device is connected to central it is not disconnecting connection.

    We have problem with app timer for trigger adc every one hour. Once this time out event occur is it need to initialize again all turn off peripheral in other function. Or it goes into main loop. Because my adc is not start after app timer time out event occur.

    Would you please suggest me where should i am going to wrong with your program snippet. 

    We are waiting for your reply......

    Thanks. 

  • Maybe you can open up a new thread in this forum where you explain in detail the workflow of your application. I'm not sure how you want the application to work, so it's hard to give you any code examples which explains things.

Related