ArduinoBLE icon indicating copy to clipboard operation
ArduinoBLE copied to clipboard

Very high power consumption on Nano 33 IoT

Open baconcheese113 opened this issue 3 years ago • 1 comments

Using a blank sketch with just the following on my Nano 33 IoT:

void setup() {
  BLE.begin();
}
void loop() {
  // no-op
}

Is drawing 90mA. Without BLE.begin() it's 21mA, so the NINA chip requires 69mA to just be active (no scanning or advertising, although there wasn't a significant change in power consumption doing either). That means using ArduinoBLE will give the following life expectancies:

  • Large cr2032 coin battery: 2 hours
  • Standard 4.8v battery pack: 22 hours
  • Battery of flagship Samsung s22: 1.7 days
  • Battery of 2021 16-in Macbook pro: 4 days

With this in mind, many users of this library are seeking a way to just power down the NINA module for a set period of time without changing anything about the currently configured GATT.

  1. I have tried calling BLE.end(), however this resets the GATT and the program crashes when trying to add the services back with BLE.addService(myService) after a subsequent BLE.begin(). The event handlers fail to register with BLE.setEventHandler(BLEConnected, onBLEConnected) as well
  2. I have tried calling digitalWrite(NINA_RESETN, LOW) and HIGH directly and this actually works nearly perfect, except the scan is unable to find anything after turning the module back on. But it can advertise and call event handlers without problems, and the GATT is populated how it was before shutting down.

I'm having a hard time finding a work around, since the ArduinoLowPower sleep function only shaves off 13mA. Do you have any insight how to turn on/off the module without breaking things?

baconcheese113 avatar Jul 13 '22 06:07 baconcheese113

An update:

I pursued my second method above and I think I've found a way to power down the NINA module and get the scan functionality when it's powered back up. This is great because the GATT is retained as well.

You can shut down the module (after having called BLE.begin()) with:

digitalWrite(NINA_RESETN, LOW);

and power it back up with:

digitalWrite(NINA_RESETN, HIGH);
delay(750); // this is what the existing implementation uses after starting

and to restore scan ability, I've found that this is the only line I need to call:

// #include "utility/HCI.h" if you need the import

HCI.setEventMask(0x3FFFFFFFFFFFFFFF);

Calling the BLE.begin() method triggers an HCI.begin() and HCI.reset() as well as a GATT.begin() which resets the GATT back to just defaults. I'm still investigating the side effects of not calling the other HCI methods from the BLE.begin() method. However it's working so far to both preserve my GATT and scan correctly. It's also important to note that there might be other differences for other boards.

baconcheese113 avatar Jul 15 '22 09:07 baconcheese113