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..!! 

  • Hi,

    I have disabled NRFX_UARTE_ENABLED 0  but got same problem. When I used below function for disabled UART consumption goes down:

    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 */
    }
    
    void Enable_Uart(void)
    {
    	
    NRF_UARTE0->ENABLE = 8; // also tried here set 1 but not enable UART
    NRF_UART0->TASKS_STARTTX = 1;
    NRF_UART0->TASKS_STARTRX = 1;
    }

    But this uart_enabled() function not working.

    here is my below uart_inti()

    static void uart_init(void) {
      uint32_t err_code;
      app_uart_comm_params_t const comm_params =
      {
        .rx_pin_no = RX_PIN_NUMBER, //RX_PIN_NUMBER,
        .tx_pin_no = TX_PIN_NUMBER, //TX_PIN_NUMBER,
        .rts_pin_no = RTS_PIN_NUMBER,
        .cts_pin_no = CTS_PIN_NUMBER,
        .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
        .use_parity = false,
    #if defined(UART_PRESENT)
        .baud_rate = NRF_UARTE_BAUDRATE_115200
    #else
        .baud_rate = NRF_UARTE_BAUDRATE_115200
    #endif
      };
    
      APP_UART_FIFO_INIT(&comm_params,
          UART_RX_BUF_SIZE,
          UART_TX_BUF_SIZE,
          uart_event_handle,
          APP_IRQ_PRIORITY_LOWEST,
          err_code);
      APP_ERROR_CHECK(err_code);
    }

    I am getting very difficult to understand where exactly issue for enable and disabled UART properly.

    Thanks..

  • Seeing as the workaround still is required to disable the UART properly, you are enabling UARTE somewhere in your code. For instance, .baud_rate = NRF_UARTE_BAUDRATE_115200 should be .baud_rate = NRF_UART_BAUDRATE_115200. This could be the only one, but please go through your project and make sure there aren't any other oversights.

    Best regards,

    Simon

  • Hi Simonr,

    I trying to find where exactly UARTE enabled but still not find. When I called app_uart_close();

    void nrf_drv_uart_uninit(nrf_drv_uart_t const * p_instance)
    {
        if (NRF_DRV_UART_USE_UARTE)
        {
            nrfx_uarte_uninit(&p_instance->uarte);
        }
        else if (NRF_DRV_UART_USE_UART)
        {
            nrfx_uart_uninit(&p_instance->uart);
        }
    }

    I set break point for both but in my project it will going to nrfx_uarte_uninit(&p_instance->uarte); not in second condition.

    I have also changed NRF_UART_BAUDRATE_115200 in my init function.

    Will you please suggest me how i can find where exactly UARTE enabled?

    Thanks...

  • Hi Vishal

    It's very hard for me to guess where you have set UARTE enabled, but let's start at the top. Does your main.c contain these defines at the top? If it does, could you remove the last half (UARTE_PRESENT) and include nrf_uarte.h

    #if defined (UART_PRESENT)
    #include "nrf_uart.h"
    #endif
    #if defined (UARTE_PRESENT)
    #include "nrf_uarte.h"
    #endif
    

    You could also check if this function still takes you to UARTE if you switch places on the two. If not, make sure to switch back to keep the function the same as the SDK.

    void nrf_drv_uart_uninit(nrf_drv_uart_t const * p_instance)
    {
    if (NRF_DRV_UART_USE_UART)
    {
    nrfx_uart_uninit(&p_instance->uart);
    }
    else if (NRF_DRV_UART_USE_UARTE)
    {
    nrfx_uarte_uninit(&p_instance->uarte);
    }
    }
    Best regards,
    Simon
  • Hi,

    I have commented the last half UARTE from my code.

    But still switched into nrfx_uarte_uninit(&p_instance->uarte) function please see below image:

    I have checked in ble_app_uart example from SDK 15.3 version in this example also when i call to close UART it will switch into UARTE function not a UART function.

    I think is by default enabled UARTE because i have checked in freash downloaded SDK v15.3.

    Thanks....

Related