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

how to achieve BLE with beacon low power UART communication?

Hello,

I have been struggling with managing power consumption of my nRF52832 so it can stay low. I'm using nRF5_SDK_17.0.0_9d13099. I did some extensive search on the available threads, but couldn't find any suggestion that can solve my problem. These are some links of similar issues i've been reading so far

https://devzone.nordicsemi.com/f/nordic-q-a/27147/how-to-configure-uart-with-low-power

https://devzone.nordicsemi.com/f/nordic-q-a/47578/nrf52832-uart-power-consumption

https://devzone.nordicsemi.com/f/nordic-q-a/43684/why-is-uart-without-dma-deprecated

https://devzone.nordicsemi.com/f/nordic-q-a/35510/uart-deinit-does-not-reduce-power-consumption-and-it-too-big-600ua

https://devzone.nordicsemi.com/f/nordic-q-a/26030/how-to-reach-nrf52840-uarte-current-supply-specification/102605#102605

https://devzone.nordicsemi.com/f/nordic-q-a/19284/turn-off-uart-on-nrf52832

According to some suggestions, I should disable Easy DMA for my UART setup. however, my UART stop working the moment I stop using Easy DMA.

sdk_config.h

#define UART_EASY_DMA_SUPPORT 1         // set 0 will cause UART stop working
#define UART_LEGACY_SUPPORT 1
#define UART0_CONFIG_USE_EASY_DMA 1     // set 0 will cause UART stop working

The other suggestions I've seen so far were closing and disabling the UART after I'm done using it. 

here's my uart_init function, taken from the available example. 

static void uart_init(void)
{
    uint32_t                     err_code;
    app_uart_comm_params_t const comm_params =
    {
        .rx_pin_no    = RX_PIN_NUMBER,
        .tx_pin_no    = 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_UART_BAUDRATE_115200
#else
        .baud_rate    = NRF_UARTE_BAUDRATE_115200
#endif
    };
    nrf_gpio_cfg_input(RX_PIN_NUMBER, NRF_GPIO_PIN_PULLUP);

    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);
}

Disabling uart according to available suggestions doesn't solve my issue. my board still consume +2 ~ 3mA after I disable my UART.

static void disabling_uart(void) 
{
    app_uart_flush();
    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 */
}

I only need to use UART RX interrupt once per hour. Is there any way to solve my issue? Example of UART without Easy DMA, or how to properly disable UART after using it would be appreciated.

Thank you.

Parents
  • Hello, 

    I believe that 2-3mA is solely from UART module. I am using a custom board and I measured my board with multimeter + power supply @3.3v. when I disable uart_init, I could get around 0.4mA which is still high, but it is because other part of my board still operating. 

    By the way, I managed to get it down to 0.6mA by disabling UART after usage on main instead of the uart_event_handler. I only needed app_uart_close() because adding other codes didn't reduce the current consumption. I assume it was still that high because of easyDMA? or is there any way to reduce more current on when I stop using the UART? I only need to re-activate it once or twice an hour. Thank you.

    best regards,

    Eddy.

  • Hi,

    Are you able to reproduce this on the development kit? It would be great if we could separate any external components from the nRF so that we know exactly what we're measuring. 

    eddyhaha89 said:
    By the way, I managed to get it down to 0.6mA by disabling UART after usage on main instead of the uart_event_handler. I only needed app_uart_close() because adding other codes didn't reduce the current consumption. I assume it was still that high because of easyDMA? or is there any way to reduce more current on when I stop using the UART? I only need to re-activate it once or twice an hour.

    The last part of the workarounds that you included in your original problem statement under disabling_uart() should take care of this. Please don't remove them at this point, as it might be some of the problem. 

    How would you characterize the current consumption, is it steady 0.6 mA or does it vary? If so, by how much? It might be due to floating GPIOs. Do you see any change if you ground the pins that you use for the UART? Including TX, RX, CTS, RTS pins. 

    Another possibility is that the UART slave requires that one of the pins are set to a specific logical level, so that it's not in a undefined state where it would pull a lot of current. Have you checked the datasheet of the slave to ensure that this is not the case?

    Lastly, could you upload your config and application? I'm interested to see what instances you have enabled and exactly from where you disable the module. 

    regards

    Jared 

  • Hello Jared,

    Thank you for your response. After checking my devkit current consumption through power profiler, I found out that it actually quite stable at 7.5 uA when uart disabled, and 2.1mA when uart is enabled.UART enabledUART disabled

    I also found out that using these would actually increase current consumption by 1.5uA on my devkit (or might be only due to some variance).

      //  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 */

    I moved the uart reinitialization / disabling uart on idle_state_handle so it can actually get enabled/disabled when needed.

    static void idle_state_handle(void)
    {
        div_t wakeupCycle;
        if (NRF_LOG_PROCESS() == false)
        {
            nrf_pwr_mgmt_run();
    
             if (m_UartInit == true)
             {
                uart_init();
                m_UartInit = false;
             }
    
             if (m_UartClose == true)
             {
                disabling_uart();
                wakeupCycle = div(m_stm_wake_up_timer, DEFAULT_1Sec_TIMEOUT);
                m_uartwakeup_time = wakeupCycle.quot;
                // TODO: change the cycle depending on how input from user 2020-11-27
                uint32_t err_code = app_timer_start(m_uart_wakeup_timer_id, APP_TIMER_TICKS(DEFAULT_1Sec_TIMEOUT), NULL);
                NRF_LOG_INFO("app_timer_start m_uart_wakeup_timer_id: %.2X", err_code); NRF_LOG_FLUSH();
                APP_ERROR_CHECK(err_code);
                 
                m_UartClose = false;
             }
        }
    }

    I also attached my sdk_config.h files as requested. I guess the issue is actually located on my custom board, and I need to figure out how to reduce my current consumption from there.

    0245.sdk_config.h

    Thank you for your help. 

    Best regards,

    Eddy.

Reply
  • Hello Jared,

    Thank you for your response. After checking my devkit current consumption through power profiler, I found out that it actually quite stable at 7.5 uA when uart disabled, and 2.1mA when uart is enabled.UART enabledUART disabled

    I also found out that using these would actually increase current consumption by 1.5uA on my devkit (or might be only due to some variance).

      //  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 */

    I moved the uart reinitialization / disabling uart on idle_state_handle so it can actually get enabled/disabled when needed.

    static void idle_state_handle(void)
    {
        div_t wakeupCycle;
        if (NRF_LOG_PROCESS() == false)
        {
            nrf_pwr_mgmt_run();
    
             if (m_UartInit == true)
             {
                uart_init();
                m_UartInit = false;
             }
    
             if (m_UartClose == true)
             {
                disabling_uart();
                wakeupCycle = div(m_stm_wake_up_timer, DEFAULT_1Sec_TIMEOUT);
                m_uartwakeup_time = wakeupCycle.quot;
                // TODO: change the cycle depending on how input from user 2020-11-27
                uint32_t err_code = app_timer_start(m_uart_wakeup_timer_id, APP_TIMER_TICKS(DEFAULT_1Sec_TIMEOUT), NULL);
                NRF_LOG_INFO("app_timer_start m_uart_wakeup_timer_id: %.2X", err_code); NRF_LOG_FLUSH();
                APP_ERROR_CHECK(err_code);
                 
                m_UartClose = false;
             }
        }
    }

    I also attached my sdk_config.h files as requested. I guess the issue is actually located on my custom board, and I need to figure out how to reduce my current consumption from there.

    0245.sdk_config.h

    Thank you for your help. 

    Best regards,

    Eddy.

Children
Related