Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Can't get BLE device to sleep

I have a custom PCBA with which has the flow of:

- Boot

- Advertise some temperature data read from TWI with a 5 second timeout using `ble_adv_fast_timeout`.

- I then set a timer to wake the `app_timer_start(m_awake_timer_id, APP_TIMER_TICKS(SLEEP_IN_MS), NULL);`

And I expect the device to go into sleep whilst its BLE is not advertising. Here's my main.c file:

#include "app_timer.h"
#include "nrf_pwr_mgmt.h"
#include "nrf_crypto_init.h"
#include "nrfx_clock.h"

#include "SEGGER_RTT.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "nrf_delay.h"

#include "customble.h"
#include "peripheral.h"
#include "encryption.h"

void timers_init(void)
{
  ret_code_t err_code = app_timer_init();
  APP_ERROR_CHECK(err_code);
}

static void idle_state_handle(void)
{
  if (NRF_LOG_PROCESS() == false)
  {
    nrf_pwr_mgmt_run();
  }
}

/**@brief Function for initializing power management.
 */
void power_management_init(void)
{
  ret_code_t err_code;
  err_code = nrf_pwr_mgmt_init();
  APP_ERROR_CHECK(err_code);
}

int main(void)
{
  NRF_LOG_INIT(NULL);
  NRF_LOG_DEFAULT_BACKENDS_INIT();

  ret_code_t reta = nrf_crypto_init();
  APP_ERROR_CHECK(reta);

  timers_init();
  ble_timers_init();
  ble_stack_init();

  power_management_init();

  gap_params_init();
  advertising_init();

  advertising_start();

  for (;;)
  {
    idle_state_handle();
  }
}

and here's the relevant sections of the customble.c code

void awake_timer_handler()
{
  NRF_LOG_INFO("Awake and start advertising");

  update_advertising_data_while_advertising();
  advertising_start();
}

void sleep_timer_handler()
{
  NRF_LOG_INFO("asleep");

  sd_ble_gap_adv_stop(m_advertising.adv_handle); // i've tried with and without this

  // Proceed with setting the device to low power mode
  app_timer_start(m_awake_timer_id, APP_TIMER_TICKS(SLEEP_IN_MS), NULL); // 60 seconds
}

void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
  NRF_LOG_INFO("BLE EVENT");
  switch (ble_adv_evt)
  {
  case BLE_ADV_EVT_IDLE:
    NRF_LOG_INFO("Advertising event: Idle");
    sleep_timer_handler();
    break;
  }
}

I have measured the amps on the device and during advertising it jumps to about 3mA and when it's not advertising (when I thought it would sleep) it's using ~1.48mA. What exactly am I doing wrong here?

I have commented lots of things out, and it's not the TWI causing the issue, it's definitely the BLE. When I comment out starting BLE, I get ~400uA constant.

  • Hello,

    3A sounds like a lot. I don't think you are able to even draw that much through the nRF. Not 1.48A either. We should be talking about perhaps 20mA, or something around those numbers.

    Have you had your PCB design through a design review with Nordic? If not, perhaps you should create a ticket for that (so that it will be assigned to one of our HW engineers).

    Other than that, I can't say that I can see anything wrong with your application. Regarding the power, I see that you are using idle_state_handle() in your main-loop, so the device should enter sleep.

    I don't know what kind of crypto things you are doing, but to rule it out. Does it still draw as much power if you remove that as well? (just to make sure that the CPU isn't running all the time). 

    How do you measure the current consumption? Are you using the Power Profiler Kit 2? Or some other device?

    Best regards,

    Edvin

  • Eugh. Apologies, of course I mean mA not A. so ~3mA and 1.4mA. I'll edit my original answer.

    I'm using both a custom PCBA and also an NRF52DK (by following the document to cut the connection then measure over the power consumption pins). I will take another reading using the DK but the power wasn't too different to what I was seeing on my custom PCBA (with no sleep happening).

    In terms of the crypto, it's not that, I've checked this also. It's definitely the BLE that's causing the device not to go into sleep mode.

  • Ah, that makes more sense then Slight smile

    Is it possible for me to test the application on a DK? Or if you are not able to share it as it is, a strip down version of the application that replicates the issue? Is there some other peripheral you are turning on when you enable BLE? You ruled out TWI. How about UART? Is that running? Perhaps for logging?

    And what advertising parameters are you using? Advertising interval, in particular.

    Best regards,

    Edvin

  • Absolutely, I'll get a stripped down demo uploaded here tomorrow.

    How about UART? Is that running? Perhaps for logging?

    I'll check these again but it seems like all my configuration has UART flags set to 0. For my test I disabled NRF_LOG_BACKEND_RTT_ENABLED. 

    > And what advertising parameters are you using? Advertising interval, in particular.

      init.advdata.name_type = BLE_ADVDATA_NO_NAME;
      init.advdata.include_ble_device_addr = false;
      init.advdata.include_appearance = false;
      init.advdata.flags = flags;
      init.advdata.p_manuf_specific_data = &manuf_specific_data;
      init.config.ble_adv_fast_enabled = true;
      init.config.ble_adv_fast_interval = NON_CONNECTABLE_ADV_INTERVAL;
      init.config.ble_adv_fast_timeout = 100;

  • prsboy said:

    I'll check these again but it seems like all my configuration has UART flags set to 0. For my test I disabled NRF_LOG_BACKEND_RTT_ENABLED. 

    NRF_LOG_BACKEND_RTT_ENABLED doesn't control the UART. It is possible to have both RTT and UART Logging at the same time. Just make sure you don't have NRF_LOG_BACKEND_UART_ENABLED set to 1. If you do, then the UART will be left on. 

    What is NON_CONNECTABLE_ADV_INTERVAL? 160 (100ms)?

    Best regards,

    Edvin

Related