BLE Nano - Low Power Consumption


#1

I am powering the BLE Nano using the GND and VIN pin with a 150mah 3.7V Lipo Battery in Arduino, but the battery life is very poor. Currently it consumes 2.4ma and is completely drained in 1-2 days. Is there any way to get the power consumption down below 1ma? Right now all the LED’s are turned off and I have the device sitting in this while loop:

//While device is not connected, just wait.
while(!ble.getGapState().connected){
ble.waitForEvent();
}

Is this code correct for a sleep mode when not being used? If anyone can help with this it would be much appreciated. I can always wake the device up via an analog read, I just need help getting the BLE Nano into the deepest sleep mode possible (lowest possible power consumption). Code would be appreciated if possible. Thanks.


Question about Advertising and Disconnecting
Power reduce in ble nano..........?
Power reduce in ble nano..........?
BLE Nano and coin cell
Power reduce in ble nano..........?
#2

Hi jstrag711,

void loop() {
ble.waitForEvent(); //Don't do other things
}

Don’t use the uart.


#3

Hi jixing,

I am using the simple chat sketch with no extra components, just the BLE Nano connected with a 3.7v Lipo to VIN and GND. Is it possible to achieve power consumption below 1ma using the regulated power on this board? Or does the 3.3v regulator prevent this?

I have turned off the onboard LED on pin 13. I even tried disabling uart as seen here:

And I used the code you provided for the main loop and did not do other things, only waited for the event. I still measured consumption at 2.2ma using a multimeter (black on GND and red on VDD).

I am very confused. Any help would be great. Thank you.


#4

Hi

Try this sample code

#include <BLE_API.h>

#define DEVICE_NAME            "BLE_Peripheral"
#define TXRX_BUF_LEN           20

BLE                            ble;

// The uuid of service and characteristics
static const uint8_t service1_uuid[]        = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t service1_tx_uuid[]     = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t service1_rx_uuid[]     = {0x71, 0x3D, 0, 2, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t uart_base_uuid_rev[]   = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71};

uint8_t tx_value[TXRX_BUF_LEN] = {0,};
uint8_t rx_value[TXRX_BUF_LEN] = {0,};

// Initialize value of chars
GattCharacteristic  characteristic1(service1_tx_uuid, tx_value, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE );
GattCharacteristic  characteristic2(service1_rx_uuid, rx_value, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
GattCharacteristic *uartChars[] = {&characteristic1, &characteristic2};
GattService         uartService(service1_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *));

void disconnectionCallBack(const Gap::DisconnectionCallbackParams_t *params) {
  ble.startAdvertising();
}

void gattServerWriteCallBack(const GattWriteCallbackParams *Handler) {

}

void setup() {

  NRF_POWER->DCDCEN = 0x00000001;
  NRF_UART0->TASKS_STOPTX = 1;
  NRF_UART0->TASKS_STOPRX = 1;
  NRF_UART0->ENABLE = 0;
  
  // put your setup code here, to run once
  ble.init();
  ble.onDisconnection(disconnectionCallBack);
  ble.onDataWritten(gattServerWriteCallBack);

  // setup adv_data and srp_data
  ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
  ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
                                   (const uint8_t *)"TXRX", sizeof("TXRX") - 1);
  ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
                                   (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid_rev));
  // set adv_type
  ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
  // add service
  ble.addService(uartService);
  // set device name
  ble.setDeviceName((const uint8_t *)"Simple Chat");
  // set tx power,valid values are -40, -20, -16, -12, -8, -4, 0, 4
  ble.setTxPower(4);
  // set adv_interval, 100ms in multiples of 0.625ms.
  ble.setAdvertisingInterval(160);
  // set adv_timeout, in seconds
  ble.setAdvertisingTimeout(0);
  // start advertising
  ble.startAdvertising();
}

void loop() {
    ble.waitForEvent();
}

About the multimeter,should be connected:

Lipo+ —> Red —> Black ----> Nano_VIN

Lipo- ---->Nano_GND


#5

Thank you jixing! You saved us lots of headache! :slight_smile:

Also, we used this in setup to disable onboard LED:
pinMode(13, INPUT);

And now power consumption around ~150ua. :slight_smile:


#6

Also for those struggling with low power consumption.

Set TX Power to 4 and set Advertising Interval to 1000 to keep the the BLE still easy to connect to. Any longer and the device may not be discovered easily.

Also be sure you have NOT used Serial.begin(9600) (or any baud rate for that matter). The Serial.begin() will still consume extra power, even with the following code:

NRF_POWER->DCDCEN = 0x00000001;
NRF_UART0->TASKS_STOPTX = 1;
NRF_UART0->TASKS_STOPRX = 1;
NRF_UART0->ENABLE = 0;

Note that Serial.end() will not fix this either. Simply put, you must not use Serial.begin().

With these settings we have consumption around 100ua. We are trying to optimize it even further, for low power consumption while still in power on mode.

Hopefully this helps anyone else with low power consumption questions.


#7

Hi jstrag711,
Thanks very much!


#8

what peripheral are by default running in redbear core. like timers etc. 100uA is alot for long life of battery. I am switching off peripherals after use like I2C. so I would like to know how I can reduce current. most of time the program is sleepingI also have kept low freq wakeup low Latency.
NRF_POWER->TASKS_LOWPWR = 1;


#9

trailblazer47:

NRF_POWER->SYSTEMOFF = 1;

You can go into power off (deep sleep) mode using this code. It consumes about 6uA which is much more long term battery friendly. However you will have to wake it up using interrupts or timers and BLE is disabled in power off mode. I have not had success with this yet, but it is possible. But this is what you might be looking for as far a true sleep mode.


#10

I think that will also reset the chip which I don’t want, I am maintaining time for clock (RTC 32Khz). is it the Regulator over nano that consumes 100uA-200uA avg current in nano?


#11

hai

i am using bleperipheral.h to program my ble nano.
So can i use

NRF_POWER->DCDCEN = 0x00000001;
NRF_UART0->TASKS_STOPTX = 1;
NRF_UART0->TASKS_STOPRX = 1;
NRF_UART0->ENABLE = 0;

in bleperipheral.h

bleperipheral library


#12

Hi I would like to update on power consumption. I am getting power for one of the product I am working on as 5-8uA in sleep. I can’t share the complete code of it but we are not using any serial port and also switching off any peripherals(I2C NRF_TWI0->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos; ) we are using when we go to sleep. We are using MDBT40 modules, no regulator only one EEPROM on it.

NRF_POWER->TASKS_LOWPWR = 1; NRF_POWER->DCDCEN = 0x00000001; ble.waitForEvent();

I do this much. I am still not sure that current is accurate. I am using fluke 17B+ multimeter. Is there any better way to make sure the current is ok? any low cost instrument.


#13

hiii @jstrag711,

Is there any possible way to wake up BLE nano from sleep using an internal interrupt…??

thank you


#14

Hey guys,

I am trying to set my BLE Nano into a deep sleep with power off. How would somebody go about waking it up by some change in the analogIn?

So basically I want my BLE to go into deep sleep after a inactivity timeout and be woken up by a strong signal from analogIn.
Do I have to make an event? Or interrupt?
I don’t need BLE when I wake it up. In fact, BLE should be off when it is woken up.


#15

Hi js
Just gotten the BLE nano, flash it with the mbed example of simple controller.
Used your advice in getting low power consumption, but i still get like 1mA drawn.
can you see what can be wrong at all? Thanks much for the time.

my main looks like this
int main(void)
{
Ticker ticker;
ticker.attach_us(m_status_check_handle, 200000);
// ADDED
NRF_POWER->DCDCEN = 0x00000001;
NRF_UART0->TASKS_STOPTX = 1;
NRF_UART0->TASKS_STOPRX = 1;
NRF_UART0->ENABLE = 0;
// END OF ADDED

ble.init();
ble.onDisconnection(disconnectionCallback);
ble.onDataWritten(WrittenHandler);  

//pc.baud(9600);
//pc.printf("SimpleChat Init \r\n");

//pc.attach( uartCB , pc.RxIrq);

// setup advertising 
ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
                                (const uint8_t *)"Biscuit", sizeof("Biscuit") - 1);
ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
                                (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid));

// ADDED     
// 100ms; in multiples of 0.625ms. 
ble.setAdvertisingInterval(1000); // advertise interval 
ble.setTxPower(4); // tx power to 4 
ble.addService(uartService);
//ENDED 
ble.startAdvertising(); 

//pc.printf("Advertising Start \r\n");

while(1)
{
    ble.waitForEvent(); 
}

}


#16

I have similar issue, but it only affects one Nano 2 board, not another one.

#include <nRF5x_BLE_API.h>

void setup() {
  NRF_POWER->SYSTEMOFF = 1;
}

void loop() {}

This code on my normal Nano 2 gives 4uA consumption. On the second one it shows around 300uA

Could you help me with that?


#17

Hello
I Am having the same problem as boon
Using the following code as described by boon I also get current consumption around 1mA
What could be wrong with that?
Thanks a lot

int main(void)
{
Ticker ticker;
ticker.attach_us(m_status_check_handle, 200000);
// ADDED
NRF_POWER->DCDCEN = 0x00000001;
NRF_UART0->TASKS_STOPTX = 1;
NRF_UART0->TASKS_STOPRX = 1;
NRF_UART0->ENABLE = 0;
// END OF ADDED

ble.init();
ble.onDisconnection(disconnectionCallback);
ble.onDataWritten(WrittenHandler);

//pc.baud(9600);
//pc.printf(“SimpleChat Init \r\n”);

//pc.attach( uartCB , pc.RxIrq);

// setup advertising
ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
(const uint8_t *)“Biscuit”, sizeof(“Biscuit”) - 1);
ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
(const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid));

// ADDED
// 100ms; in multiples of 0.625ms.
ble.setAdvertisingInterval(1000); // advertise interval
ble.setTxPower(4); // tx power to 4
ble.addService(uartService);
//ENDED
ble.startAdvertising();

//pc.printf(“Advertising Start \r\n”);

while(1)
{
ble.waitForEvent();
}
}