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

How optimize high current consumption in sleep mode using nRF52840?

Hello to all,

We have developed our application & the following platform we are using:

  • SDK 15.0, Segger IDE on windows PC
  • Softdevice version is 6.0.0
  • Hardware version nRF52840 SoC.
  • Our product is battery operated, so high power consumption is serious an issue for us.

In our application we have used ble_app_uart example with SAADC because our sensor is analog. We also made custom PCB using nRF52840 and it working well not an issue. But our problem is very too much high current consumption is sleep mode means system OFF mode.

Here is below measured analysis with the help of Nordic Power Profile kit:

  1. The average current consumption while advertising is 962uA - 1.62mA I think this is OK.
  2. The average current consumption when sensor device enter into sleep mode is 562uA (Which is very high)

We have disabled all used peripheral before enter device into sleep mode as like below:

void sleep_mode_enter() {
  uint32_t err_code;
  NRF_LOG_INFO("Sleep mode Enter");
  flash_data_sending = false;
  start_measurement = false;
  nrf_gpio_pin_clear(SENSOR_PIN);  // OFF Sensor
  nrf_gpio_pin_set(GREEN_LED_PIN); // OFF Green LED
  nrf_gpio_pin_set(BLUE_LED_PIN);  // OFF BLUE LED
  stop_adc();
  err_code = app_uart_close();
  APP_ERROR_CHECK(err_code);
  NRF_LOG_INFO("UART close: %d", err_code);
}

void stop_adc() {
  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_SAADC->TASKS_STOP = 1;
  nrf_drv_saadc_uninit();
}

We have tested our hardware and sure this not hardware problem because when our device enter into deep sleep mode system OFF that time the current consumption near about 0.7uA to 1uA. Even when our designed firmware upload into nRF52840 DK and measured consumption using PPK that time got same results.

Questions:

  1. Why this too much very high power consumption getting in sleep mode?
  2. Is any wrong in our sleep mode enter function and disabled module functions?

Will you please suggest any solution, We should need to optimize this consumption to increase battery life because our sensor devices is battery operated.

Looking forward your response..!!

Thanks in advanced..!! 

  • Finally I am able to enabled and disabled UART peripheral as below is this right way:

    void disabled_uart(void) {
      uint32_t err_code = app_uart_close();
    //  APP_ERROR_CHECK(err_code);
      NRF_UARTE0->TASKS_STOPTX = 1;
      NRF_UARTE0->TASKS_STOPRX = 1;
      NRF_UARTE0->ENABLE = 0;
      /* Workaround by disabling the UART peripherals due to Nordic SDK15.0 issue */
      *(volatile uint32_t *)0x40002FFC = 0; /* Power down UARTE0 */
      *(volatile uint32_t *)0x40002FFC;     
      *(volatile uint32_t *)0x40002FFC = 1; /* Power on UARTE0 so it is ready for next time */
    }
    

    For enabled UART call uart_init(); function is this correct but it working.

    Now it will significantly improve battery life.

    Now we measure power consumption 37.74uA, but still this also high because data sheet mentioned 1uA to 10uA in sleep mode with RTC running.

    Can you give me suggestions for reduced this sleep mode consumption?

    Thank you so much for your great help and quick response...

  • Ok, I'm glad we finally were able to solve that one! Yes, this seems like the correct way to go shut down the UARTE0.

    A few questions to help us narrow down what's drawing this extra current:

    • Your device is sleeping in system ON mode correct?
    • Do you have any other peripherals or additional timers running now?
    • Do you use RAM retention?
    • What is the wake-up condition of your device?
    • What low-frequency clock is the RTC using (the external one should be most power efficient)?
    • What regulator(s) are you using, DCDC or LDO? 

    Best regards,

    Simon

  • Your device is sleeping in system ON mode correct?

    Yes you are correct.

    Do you have any other peripherals or additional timers running now?

    No, I have used saadc but i have already disabled. How i can check addition timer if running.

    Do you use RAM retention?

    RAM retention means what? In my application RTC running for wake up device as per schedule time.

    What low-frequency clock is the RTC using (the external one should be most power efficient)?

    Yes I am using RTC with low frequency clock.

    What regulator(s) are you using, DCDC or LDO? 

    I have enabled DCDC regulator in soft and hardware components also.

    Here is my timer_inti() function:

    static void timers_init(void) {
      ret_code_t err_code = app_timer_init();
      APP_ERROR_CHECK(err_code);
      // Create twice press switch timer.
      err_code = app_timer_create(&twice_press_timer_id, APP_TIMER_MODE_SINGLE_SHOT, button_twice_timeout_handler);
      APP_ERROR_CHECK(err_code);
      // Create advertising timeout timer
      err_code = app_timer_create(&advertising_timeout_timer_id, APP_TIMER_MODE_SINGLE_SHOT, deep_sleep_timeout_handler);
      APP_ERROR_CHECK(err_code);
      // Create http request send time out timer
      err_code = app_timer_create(&request_send_timer_id, APP_TIMER_MODE_SINGLE_SHOT, device_state_request_send);
      APP_ERROR_CHECK(err_code);
      // Create WiFi response check time out timer
      err_code = app_timer_create(&wifi_resp_timer_id, APP_TIMER_MODE_SINGLE_SHOT, server_WiFi_resp_timeout_handler);
      APP_ERROR_CHECK(err_code);
        // Create server response check time out timer
      err_code = app_timer_create(&Server_resp_timer_id, APP_TIMER_MODE_SINGLE_SHOT, server_WiFi_resp_timeout_handler);
      APP_ERROR_CHECK(err_code);
    }

    Thanks......

  • Do the timers you have initialized keep running when you go to sleep mode, or do you stop them before going to sleep and restart them once you wake up?

    The RAM is by default set to go off and restart when you wake up from sleep, but you can retain data in RAM while sleeping, at the cost of some current consumption. If you don't know what this is I assume you are not using it.

    Yes, but the system supports 3 different low-frequency clock sources:

    • 32.768 kHz RC oscillator (LFRC)
    • 32.768 kHz external crystal oscillator (LFXO, also the most power efficient)
    • 32.768 kHz synthesized from HFCLK (LFSYNT, the least power efficient, as it requires the HFCLK to be on).

    Page 94 in the product specification shows you how to set your clock source.

    Best regards,

    Simon

  • Hi Simonr,

    We are facing one problem for enable and disable UARTE module if I do below flow:

    1. Is it necessary to uart_init() before start saadc because when I enable as below saadc not working:

      memset(&adc_buff, 0, sizeof(adc_buff));
    //  nrf_gpio_pin_set(WIFI_PIN);   // ON WIFI Module
      nrf_gpio_pin_set(SENSOR_PIN); // ON Sensor
    //  uart_init();
      saadc_sampling_event_init();
      saadc_sampling_event_enable();
      nrf_delay_ms(3000);
      uart_init();
      adc_configure_battery();

    If I remove comment of nrf_gpio_pin_set(WIFI_PIN);   then every thing working fine.

    But I want ON WiFi module after completion of saadc task.

    I am little bit confused why this happening?

    Thanks.....

Related