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

How to minimise power consumption for transmitter example ?

Hello!!

I am using transmitter example on my custom board having 10 buttons. I want to minimise the power consumption as it is powered by coin cell. I have used below tutorial to add power management library to transmitter example. 

https://embeddedcentric.com/lesson-14-nrf5x-power-management-tutorial/

I am getting ~ 195uA on idle state and ~ 300uA while transmitting. I have also verified my custom board with ble_app_uart example and I am getting ~ 3uA on idle state and ~ 300 uA while advertising.

I will appreciate any response.

Thanks 

Parents
  • Hi,

    If you are referring to the radio when you say transmitting, this will have considerably higher current consumption than 300 uA while it is active in TX mode, see Current consumption: Radio.

    The average current consumption, and the current consumption in sleep mode will depend on the configuration of the radio activity interval and if any other peripherals are enabled/active.

    There is a lot of other tickets here on DevZone regarding optimization of current consumption. I would recommend that you use the search function and look through a few of these. If you are still not able to lower your current consumption, please include the following information in your response:

    • Which SDK version are you using?
    • Which chip/board/development kit are you using?
    • What do you use for current measurement?
    • Which example/application are you using, and have you made any modifications?

    Best regards,
    Jørgen

Reply
  • Hi,

    If you are referring to the radio when you say transmitting, this will have considerably higher current consumption than 300 uA while it is active in TX mode, see Current consumption: Radio.

    The average current consumption, and the current consumption in sleep mode will depend on the configuration of the radio activity interval and if any other peripherals are enabled/active.

    There is a lot of other tickets here on DevZone regarding optimization of current consumption. I would recommend that you use the search function and look through a few of these. If you are still not able to lower your current consumption, please include the following information in your response:

    • Which SDK version are you using?
    • Which chip/board/development kit are you using?
    • What do you use for current measurement?
    • Which example/application are you using, and have you made any modifications?

    Best regards,
    Jørgen

Children
  • Hi!! 

    Thank you for your reply.

    I tried some tickets regarding optimisation of current consumption but got success only up to ~ 195uA.

    Below is the information :

    1. nRF5_SDK_17.0.2

    2. PCA10040 (nrf52832)

    3. Joulescope to measure current consumption.

    4. nRF5_SDK_17.0.2_d674dde/examples/peripheral/radio/transmitter/pca10040. Yes I have added power management library and call the function according to the tutorial I got from here :

    https://embeddedcentric.com/lesson-14-nrf5x-power-management-tutorial/  

  • Hi,

    This example starts the HFCLK at the beginning of the application, and lets this run all the time. Did you stop the HFCLK before entering sleep mode? The HFCLK will not be stopped automatically when going to sleep if it has been started explicitly by triggering TASKS_HFCLKSTART. You can stop the HFCLK by triggering TASKS_HFCLKSTOP:

    NRF_CLOCK->TASKS_HFCLKSTOP = 1;

    The example also initializes the NRF_LOG module with UART backen enabled. You should disable this in your sdk_config.h file to get to the lowest possible power state:

    // <e> NRF_LOG_ENABLED - nrf_log - Logger
    //==========================================================
    #ifndef NRF_LOG_ENABLED
    #define NRF_LOG_ENABLED 0
    #endif

    Final things that can add to the idle current is the app_timer and BSP modules. These uses RTC (which again uses the LFCLK) and GPIOTE for handling button presses. 

    Best regards,
    Jørgen

  • Thanks Jørgen!!!

    I have added 

    NRF_CLOCK-> TASKS_HFCLKSTOP == 1;

    when the transmission is completed. I have achieved ~17uA. While transmitting it is ~ 250uA.  I want to achieve ~3uA. I tried to add in the main() function and it is ~1.2uA but when I start the transmission it again goes same i.e ~17uA when there is no transmission and ~250uA when there is transmission.   

    Also I have disabled the NRF LOG.

    Thanks

  • It is possible that the increased current is caused by the BSP, app_timer, and LFCLK modules if you did not remove that.

    I created a test application based on the radio transmitter example, which should give close to the lowest possible current consumption:

    /**
     * Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    /** @file
    *
    * @defgroup nrf_dev_button_radio_tx_example_main main.c
    * @{
    * @ingroup nrf_dev_button_radio_tx_example
    *
    * @brief Radio Transceiver Example Application main file.
    *
    * This file contains the source code for a sample application using the NRF_RADIO peripheral.
    *
    */
    
    #include <stdint.h>
    #include <stdbool.h>
    #include <stdio.h>
    #include "radio_config.h"
    #include "nrf_gpio.h"
    #include "app_timer.h"
    #include "boards.h"
    #include "bsp.h"
    #include "nordic_common.h"
    #include "nrf_error.h"
    
    static uint32_t                   packet;                    /**< Packet to transmit. */
    static uint32_t i = 0;
    
    /**@brief Function for sending packet.
     */
    void send_packet()
    {
        /* Start 16 MHz crystal oscillator */
        NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
        NRF_CLOCK->TASKS_HFCLKSTART    = 1;
    
        /* Wait for the external oscillator to start up */
        while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
        {
            // Do nothing.
        }
    
        // send the packet:
        NRF_RADIO->EVENTS_READY = 0U;
        NRF_RADIO->TASKS_TXEN   = 1;
    
        while (NRF_RADIO->EVENTS_READY == 0U)
        {
            // wait
        }
        NRF_RADIO->EVENTS_END  = 0U;
        NRF_RADIO->TASKS_START = 1U;
    
        while (NRF_RADIO->EVENTS_END == 0U)
        {
            // wait
        }
    
        uint32_t err_code = bsp_indication_set(BSP_INDICATE_SENT_OK);
        //NRF_LOG_INFO("The packet was sent");
        APP_ERROR_CHECK(err_code);
    
        NRF_RADIO->EVENTS_DISABLED = 0U;
        // Disable radio
        NRF_RADIO->TASKS_DISABLE = 1U;
    
        while (NRF_RADIO->EVENTS_DISABLED == 0U)
        {
            // wait
        }
        NRF_CLOCK->TASKS_HFCLKSTOP = 1;
    }
    
    
    void GPIOTE_IRQHandler(void)
    {
        NRF_GPIOTE->EVENTS_PORT = 0;
        nrf_gpio_pin_toggle(LED_1);
        packet = i++;
        send_packet();
    }
    
    
    /**
     * @brief Function for application main entry.
     * @return 0. int return type required by ANSI/ISO standard.
     */
    int main(void)
    {
        NRF_POWER->DCDCEN = 1;
    
        // Configure LED1 as output
        nrf_gpio_cfg_output(LED_1);
        nrf_gpio_pin_clear(LED_1);
    
        // Configure BUTTON1 as input to trigger Radio packet
        nrf_gpio_cfg_sense_input(BUTTON_1, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
        NRF_GPIOTE->INTENSET = (GPIOTE_INTENSET_PORT_Enabled << GPIOTE_INTENSET_PORT_Pos);
        NVIC_EnableIRQ(GPIOTE_IRQn);
    
        // Set radio configuration parameters
        radio_configure();
    
        // Set payload pointer
        NRF_RADIO->PACKETPTR = (uint32_t)&packet;
    
        while (true)
        {
            __WFE();
        }
    }
    
    
    /**
     *@}
     **/
    

    This will send a packet on the radio and toggle LED1 on the nRF52 DK when BUTTON1 is pressed.

    I measured the average idle current of this application to be in the 1.6-1.7uA range.

    Best regards,
    Jørgen

Related