Power consumption is too high

I am using the PCA10028 to connect to my board and use Segger embedded studio. I am unable to bring my power consumption below 1 mA.

To exclude my hardware from the equation, I decided to connect the EEPROM I´m using (24LC16) and one key to the PCA10028 board and use the nRF current measurement feature. I soldered a 22 Ohm resistor on R6 and loaded my program into it. 

The program is very simple: if key is ON I have BLE advertising and all runs.

If key is OFF, then I stop BLE advertising and only keep my app_timer running on RTC1. I tried also stopping the timer and the result is the same. I get 1 mA consumption.

I tried performing NRF_POWER->SYSTEMOFF = 1; instruction but the controller doesn't stop (I made an endless loop with this instruction and toggle of a LED) and the code just ignores the command and continues running, even if I don't connect the board to the PC (use then a battery for supply).

I tried also NRF_POWER->TASKS_LOWPWR = 1; but it also doesn't work.

I tried __WFE(); __SEV(); and even __WFI(); but none seams to work. 

What am I doing wrong?

Parents
  • For information, here is my main loop:

    //-------------------------------------
    /**@brief Application main function.
     */
    //-------------------------------------
    int main(void)
    {
        uint32_t err_code;
    
    // ---- Initialize ckock timer ----
        
        APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
        err_code = app_timer_create(&real_time_clock_id, APP_TIMER_MODE_REPEATED, rtc_handler);
        app_timer_start(real_time_clock_id, 32767, false);
        
    // ---- Initialize kernel timer ----
        err_code = app_timer_create(&kernel_clock_id, APP_TIMER_MODE_REPEATED, kernel_handler);
    // ----
    #ifdef USE_BLE
        ble_stack_init();
        gap_params_init();
        services_init();
        advertising_init();
        conn_params_init();
    #endif
    //    configure_ram_retention();
    #ifdef DEBUG_PRINT
        printf("\r\nUART Start after RESET!\r\n");
        printf("BT Disconnected");
        printf("\r\n");
    #endif
        InitIo();
        CheckWarmCold();      // chek if EEPROM was initialized
        ClearRxString();      // clear BLE receive buffer
        f_key_was_on = 0;
        f_power_is_on = 0;    
        InitIo();             // configure ports
        for (;;)
          {
          power_manage();
          if (f_power_is_on)
            {
            if (f_data_rx)
              {
              f_data_rx = 0;
    #ifdef DEBUG_PRINT
              printf("RX: ");
              printf(rx_string);
              printf("\r\n");
    #endif
              if (ParseMessage())           // parse command to rx_data[]
                {
                ClearRxString();            // clear rx_buffer for next communication
                ExecuteMessage();
                }
              else
                ClearRxString();            // message invalid: clear rx_buffer for next communication
              }
            if (f_data_tx)
              {
              f_data_tx = 0;
    #ifdef DEBUG_PRINT
              printf("TX: ");
              printf(tx_string);
              printf("\r\n");
    #endif
              ble_nus_string_send(&m_nus, tx_string, tx_string_len);
              }
            }
          CheckPowerKey();                // check power key
          if (f_power_is_on)
            {
            CheckScheduling();
            UpdatePumpOperation();
            Timers();
            UpdateLed();
            }
          }
    }
    

  • and the Check Power Key routine:

    //-------------------------------------
    void CheckPowerKey(void)
    {
      if (f_key_was_on)
        {
    #ifdef DEMO_BOARD
        if (nrf_gpio_pin_read(K_PWR) || !nrf_gpio_pin_read(PDN))
    #else
        if (!nrf_gpio_pin_read(K_PWR) || !nrf_gpio_pin_read(PDN))
    #endif
          {
          f_key_was_on = 0;   // key changed ON -> OFF
          }
        else // Key is On and not PDN: => switch on if was off
          {
          if (!f_power_is_on)
            {
            f_power_is_on = 1;
            PowerOffToOn();
            first_minute = 60;
            StartBLE();       // start BLE and kernel_int
            RebuildActionSequence();
    //        ReloadOnPeriod();
    //        ReloadOffPeriod();
            if (!po_on_period)
              po_on_period = TEST_ON_PERIOD;
            }
          }
        }
      else // f_key_was_on = 0
        {
    #ifdef DEMO_BOARD
        if (!nrf_gpio_pin_read(K_PWR) && nrf_gpio_pin_read(PDN))
    #else
        if (nrf_gpio_pin_read(K_PWR) && nrf_gpio_pin_read(PDN))
    #endif
          {
          f_key_was_on = 1;       // key changed OFF -> ON
          }
        else // Power key is OFF: => switch off if it was on
          {
          if (f_power_is_on)
            {
            StopBLE();       // stop BLE and kernel_int
            f_power_is_on = 0;
            first_minute = 0;
            PowerOnToOff();
            }
          }
        }
    }
    

  • Here is the rest:

    //-------------------------------------
    void StopBLE(void)
    {
    #ifdef USE_BLE
      if (f_bt_connected)
        bsp_event_handler(BSP_EVENT_DISCONNECT);
      advertising_stop();
    #endif
      app_timer_stop(kernel_clock_id);
      InitIo();                       // set IO to minimum consumption
    }
    //-------------------------------------
    //
    //-------------------------------------
    void StartBLE(void)
    {
    #ifdef USE_BLE
      ble_advertising_start(BLE_ADV_MODE_FAST);
    #endif
      app_timer_start(kernel_clock_id, 327, false);
      InitIo();                       // set IO to minimum consumption
    }
    //-------------------------------------
    //
    //-------------------------------------
    void PowerOnToOff(void)
    {
      nrf_gpio_pin_set(LED);
      nrf_gpio_pin_set(P_ON);
      i2c_init();
      app_timer_stop(real_time_clock_id);       // stop RTC1 - also clears COUNTER
    }
    //-------------------------------------
    //
    //-------------------------------------
    void PowerOffToOn(void)
    {
      lword seconds_elapsed;
      
      seconds_elapsed = NRF_RTC1->COUNTER;
      app_timer_start(real_time_clock_id, 32767, false);
    }
    

Reply
  • Here is the rest:

    //-------------------------------------
    void StopBLE(void)
    {
    #ifdef USE_BLE
      if (f_bt_connected)
        bsp_event_handler(BSP_EVENT_DISCONNECT);
      advertising_stop();
    #endif
      app_timer_stop(kernel_clock_id);
      InitIo();                       // set IO to minimum consumption
    }
    //-------------------------------------
    //
    //-------------------------------------
    void StartBLE(void)
    {
    #ifdef USE_BLE
      ble_advertising_start(BLE_ADV_MODE_FAST);
    #endif
      app_timer_start(kernel_clock_id, 327, false);
      InitIo();                       // set IO to minimum consumption
    }
    //-------------------------------------
    //
    //-------------------------------------
    void PowerOnToOff(void)
    {
      nrf_gpio_pin_set(LED);
      nrf_gpio_pin_set(P_ON);
      i2c_init();
      app_timer_stop(real_time_clock_id);       // stop RTC1 - also clears COUNTER
    }
    //-------------------------------------
    //
    //-------------------------------------
    void PowerOffToOn(void)
    {
      lword seconds_elapsed;
      
      seconds_elapsed = NRF_RTC1->COUNTER;
      app_timer_start(real_time_clock_id, 32767, false);
    }
    

Children
  • Another thing: if I hold the controller in RESET (on the PCA10028) I have 1 mA consumption!

  • I forgot to mention: I am using soft_device 12 and I can say that it is the BLE soft_device that is consuming this power. So I think the answer to my problem could be quite simple:
    How can I switch off the complete BLE before going into low power consumption?

  • Hi there,

    To exclude my hardware from the equation, I decided to connect the EEPROM I´m using (24LC16) and one key to the PCA10028 board and use the nRF current measurement feature. I soldered a 22 Ohm resistor on R6 and loaded my program into it. 

    To be clear, you're using the nRF51 development kit right? 

    Let's start with verifying your current measurement setup:

    Can you describe your measurement setup in more detail, how are you measuring the current?

    What current do you measure if you run the Power Management Example with nothing external connected to the development kit. Follow the instructions in the example description to put the chip into System Off mode. What current do you measure?

    Sergio T said:
    using soft_device 13

    Did you mean nRF5SDK v13? nRF51 is only supported up to v12.3,

    regards
    Jared 

  • Hi Jared:

    I am using nRF51 board PCA10028 development kit. In my project, I am using the nRF51822.

    I am using s130 softdevice and SDK V12.3.

    I place 22 Ohm in R6 to measure with a voltmeter on P22.

    Step 1: Connect the USB to the PC. Voltmeter reads 0.2 mV (9 uA)

    Step2: Start SEGGER and load the program. Voltmeter reads 26.4 mV (1.2 mA). I didn't press RUN and I placed a BREAK at reset_handler's first instruction in ses_nrf51_startup.s (that I didn't change).
    Probably this consumption is because the 16 MHz quartz was started!?

    Step 3: If I define my main as:

    int main(void)

    {

      for(;;)

         power_manage();

    }

    and run it, then voltmeter reads 101.3 mV (4.6 mA)

    If instead I define main as:

    int main(void)

    {

      ble_stack_init();

      for(;;)

         power_manage();

    }

    and run it, then voltmeter reads 27.7 mV (1.2 mA).

    If I put in this loop NRF_POWER->SYSTEMOFF = 1; then the loop continues to operate (probably because of debug) but the power consumption goes to 4.6 mA.

    My question is: how can I put the controller to the lower power consumption, as when I first powered the board? What is the function(s) I have to call to do that?

    Kind regards

    Sergio

  • Hi,

     Before we proceed we need to verify your measurement setup. You should measure around 4 µA with the example that I shared in my previous reply, if you measure anything else then your measurement setup is not correct. Can you confirm what you measure with the Power management example, is that 9 µA?

    Also if the debug connector is connected then the chip will be in debug mode. The chip will never go to system off in debug mode, it will only emulate it, and the HFCLK will be kept active which will consume current, around a 1mA which explains what you measure. If you want to measure current then chip can't be in debug mode. 

    regards

    Jared 

Related