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

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

Reply Children
  • 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 

  • Hi Jared:

    Thanks for your reply. My measurement setup is probably not 100% accurate as I am measuring with too less resolution. Still the differences are there.

    I am not able to compile the power management project because I don't have a compatible development environment (I don't remember anynmore how I did it, as it was 5 years ago I started this!). 

    Still, I would expect that changing the main.c and the sdk_config files would make the job, because all the rest is the same, but it doesn't work!

    If I disconnect the USB and supply with a battery, then I would assume that the board would not work in DEBUG mode. Still I see similar consumption. How can I prevent or disconnect the DEBUG mode?

    I think it is better I make another question:

    Do you have any documentation explaining how to select and configure the peripherals we need using the code you provide in your examples?

    How can I set the controller to sleep? NRF_POWER->SYSTEMOFF = 1; doesn't work!

    How can I stop the 16 MHz clock? I can't see any oscillation with an oscilloscope, so I assume it is OFF, but the consumption says otherwise!

    There must be some instructions that do the job!

    The production of the final product is stopped because of the power consumption issue, now that a battery backup for the time was implemented.

    Kind regards

    Sergio

Related