Xiao ble sense power off

Hi all,
I would like to know the best power saving solution for my specific case.
My xiao is battery powered (100mah li-ion), and stays most of the time (almost 99%) in system off, until intentionally waken up by the user with a tilt movement.
The rest of the time I really don´t care too much about the consumption, I use some sensors and BLE, but the battery is big enough for all them.
What is really important is the power consumption during system off.
My actual power off sequence is:

  • disable gyroscope
  • enable embedded tilt function on int1 (lsm6ds3)
  • set pinMode of int1 as INPUT_PULLDOWN_SENSE
  • call sd_power_system_off()
    SLEEP…
    It works perfectly but the current drained during the system off is still higher than expected.
    I don´t know exactly what sd_power_system_off() does, maybe I have to power off something else manually before calling the function, something like the bluetooth radio, the flash, I don’t know…
    The only needed hardware is the accelerometer, to wake up the xiao.

Did you set the on-chip regulator to DCDC mode?
Did you set the on-board Flash to DeepPowerDown mode?

hi msfujino.
This is exactly what I need to know, what do I have to switch off or on to get the minimum current in system power off?
I didn´t set the flash in power down mode, neither set on the dcdc regulator.
Is it necessary to power off the ble radio too?

Try this first. And let us know what sleep current value you get.

// on board Flush SPI_1 pins
#define CS1      (25)
#define CLK1     (21)   
#define MOSI1    (20)
#define MISO1    (24)

// Flash functions
void sendSPI(byte data) {
  for (int i = 0; i < 8; i++) {
    digitalWrite(MOSI1, data & 0x80);
    data <<= 1;
    digitalWrite(CLK1, HIGH);
    delayMicroseconds(1);
    digitalWrite(CLK1, LOW);
    delayMicroseconds(1);
  }
}

  // Flash Deep Power Down 
  writeEnable();
  digitalWrite(CS1, LOW);
  sendSPI(0xB9);
  digitalWrite(CS1, HIGH); 

  // Enable DC-DC converter
  NRF_POWER->DCDCEN = 1;
1 Like

writeEnable() is not declared, which library should I use?

Copies were missing.

// on board Flush SPI_1 pins
#define CS1      (25)
#define CLK1     (21)   
#define MOSI1    (20)
#define MISO1    (24)

// Flash commands
#define READ_DATA     0x03
#define WRITE_ENABLE  0x06
#define PAGE_PROGRAM  0x02
#define SECTOR_ERASE  0x20

// Flash functions
void sendSPI(byte data) {
  for (int i = 0; i < 8; i++) {
    digitalWrite(MOSI1, data & 0x80);
    data <<= 1;
    digitalWrite(CLK1, HIGH);
    delayMicroseconds(1);
    digitalWrite(CLK1, LOW);
    delayMicroseconds(1);
  }
}

void writeEnable() {
  digitalWrite(CS1, LOW);
  sendSPI(WRITE_ENABLE);
  digitalWrite(CS1, HIGH);
}


  // on board flash
  pinMode(CS1, OUTPUT);
  pinMode(CLK1, OUTPUT);
  pinMode(MOSI1, OUTPUT);
  pinMode(MISO1, INPUT);
  digitalWrite(CS1, HIGH);   // CS1 HIGH

  // Flash Deep Power Down 
  writeEnable();
  digitalWrite(CS1, LOW);
  sendSPI(0xB9);
  digitalWrite(CS1, HIGH); 

  // Enable DC-DC converter
  NRF_POWER->DCDCEN = 1;
  

There is another way.

#include <Adafruit_SPIFlash.h>

  // Shut down unused QSPI flash memory
  Adafruit_FlashTransport_QSPI flashTransport;
  flashTransport.begin();
  flashTransport.runCommand(0xB9);
  flashTransport.end();

  // Enable DC-DC converter
  NRF_POWER->DCDCEN = 1;


Is BoardServicePackage mbedd or non-mbed?

This may possibly be helpful.

non-mbed

so I suppose the second way will work, right?

lucamox,
Yes, I think so.

I ended up using the first solution, because of a library interference between Adafruit_SPIFlash.h and InternalFileSystem.h
Seems to work well, but I have to check the current, I will reply in a few days.

Thks
Luca

1 Like

I’m here again, with some data.
Now the current in system off is around 246uA, better than before but not yet what I need.
Just to summarize my system off setup, now I put the onboard flash in deep sleep mode, no output is active, no serial, DC/DC is ON , the gyroscope is disabled, the accelerometer is active in low power (ODR 26hz), just to use the embedded tilt function that I use to generate the interrupt on int1 , configured as wakeup source with the statement "pinMode(PIN_LSM6DS3TR_C_INT1, INPUT_PULLDOWN_SENSE); ".

There is something else I can do?

Hi there,

What do you get with Baseline(everything off) ?
your close, you will get it. :+1:

GL :slight_smile: PJ :v:

As shown in the link below, the sleep current should be about 24uA. Why don’t you first see if you can achieve this 24uA and then activate the accelerometer and interrupts?

As for accelerometer interrupts, @PJ_Glasso has lots of samples.
PJ, if you are reading this, please comment.

System off , nothing active, no wakeup source, no accelerometer , no gyroscope, no onboard flash, no serial: 82uA
Same with accelerometer and wakeup: 257uA

Using the sample sketch attached to the link and still not get the sleep current to 24uA?

The ppk2 is connected to the battery pad and 3.6V is applied.

Did some more tests…
I loaded another example and I got 10uA, with accelerometer wakeup, just a little different wake up compared to the tilt I used before.
Then I applied this wakeup to my full app and I achieved 82uA (not bad)

Ok my app does sone more things… a lot of ble services, file read and write from internal flash (using little fs), gyroscope reading, battery level reading, strain gauge reading (external hx711).
But everything should be off when I go system off.
Now I have some 70uA to shave, maybe is the internal flash?

If you mean on-board flash, it consumes about 25uA.
If the external HX711 is powered from XIAO’s 3V3, this also adds up.

To reduce the sleep current, I think it is useful to start with the smallest configuration and gradually add features to find the source of consumption.

The Hx711 is powered through a mosfet switch, which is off during system off.
The last test I did with the same exact hardware, only a different software, and I got 10uA.
The only difference (in terms of software) is the use of the internalFS , I think is the flash of the cpu but maybe I’m wrong.
The rest doesn’t affect the system off behaviour. Or does it?

For XIAO with no external connections, the sleep current will be about 2.4 uA when 3.6 V is applied to the battery pad.
If the current exceeds 2.4uA, it may be consumed by external circuitry or the temperature-sensitive Schottky diodes used inside XIAO may have a high leakage current.

1 Like

Hi there,

So , Comcast having Internet connectivity issues here,
I set up a test with this code and a Xiao nRF52840 Sense
BSP 1.1.10 non-mbed :grin: :+1:

I’m getting 12.6 uA sleep & 7ma. Awake.

#include <Arduino.h>
#include <bluefruit.h>
#include <Adafruit_FlashTransport.h>

long previousMillis = 0;  // last time the battery level was checked, in ms
Adafruit_FlashTransport_QSPI flashTransport;
void setup()
{
sd_power_mode_set(NRF_POWER_MODE_LOWPWR);
sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE);
__WFE();
__WFI();
sd_app_evt_wait() ; //SOFT DEVICE “SYSTEM ON” POWER SAVE

//NRF_POWER->SYSTEMOFF = 1;
}

void loop()
{
  long currentMillis = millis();
      // if 200ms have passed, check the battery level:
      if (currentMillis - previousMillis >= 80000)
      {
        previousMillis = currentMillis;
        shutdown();
      }
// currentMillis = millis();
      // if 200ms have passed, check the battery level:
      if (currentMillis - previousMillis >= 60000)
      {
        previousMillis = currentMillis;
        NRF_POWER->SYSTEMOFF = 1;
      }


}

void sleepFlash() {
    flashTransport.begin();
    flashTransport.runCommand(0xB9);
    flashTransport.end();
}

void disconnectPin(uint32_t ulPin) {
      if (ulPin >= PINS_COUNT) {
        return;
    }

    ulPin = g_ADigitalPinMap[ulPin];

    NRF_GPIO_Type * port = nrf_gpio_pin_port_decode(&ulPin);

    port->PIN_CNF[ulPin] = 
          ((uint32_t)GPIO_PIN_CNF_DIR_Input        << GPIO_PIN_CNF_DIR_Pos)
        | ((uint32_t)GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
        | ((uint32_t)GPIO_PIN_CNF_PULL_Disabled    << GPIO_PIN_CNF_PULL_Pos)
        | ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1       << GPIO_PIN_CNF_DRIVE_Pos)
        | ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled   << GPIO_PIN_CNF_SENSE_Pos);
}

void shutdown() {
    //sleep flash
    sleepFlash();
    //disconnect any pins used
    disconnectPin(D1);
    disconnectPin(D2);
    //setup pin for wakeup
    nrf_gpio_cfg_sense_input(g_ADigitalPinMap[D3], NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
    //power off
    sd_power_system_off();
}

Below DUT :raised_hand_with_fingers_splayed:

HTH
GL :slight_smile: PJ :v:

2 Likes