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

Reply
  • 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();
            }
          }
    }
    

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

  • 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 

Related