Autonomo sleep current

What is the minimum current achievable with the Autonomo in sleep mode?

Greetings Phillip,

The Autonomo uses a cortex m0+ arm processor.
According to the info page from arm, this processor uses 9.8µW/MHz and is one of the best energy arm processors on the market…
The processor runs at 48 MHz, so that would make it 470.4µW/MHz total.

This wouldn’t include any energy loss on the components on the board such as leds, which i think are not .
Using the modem uses allot of power, hope your not planning on using this allot.

The microprocessor has some options for lower energy consumption, such as ultra deep sleep. From what i can make out, this makes the clock inaccurate.

What did you wanted to autonomo to do?
Erik

sources:


I want run a sensor for several years on a battery without solar,

I measure 750uA in standby mode, someone an idea how to lower this?

How did you initialize this standby mode?

For other Arduino boards I’m using this lib http://www.rocketscream.com/blog/2011/07/04/lightweight-low-power-arduino-library/

and as code, e.g…
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);

and waking up the MC via an external IRQ, e.g. by the RTC

Is the rocketscream lib usable for the Autonomous? Don’t know how deep it is connected with the processor?

I’m interested in ultra low power application as Philip also. Same subject: Measuring sensor data–in my case bee hives–with at least one year battery life.

Here are some numers for the Seeeduino Stalker (Arduino Pro compatible with 8 MHz) no sensors attached

version 2.3 of the Seeeduino Stalker

  • bare minimum (empty setup, empty loop): 6.7 mA
  • LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF): 2.6 mA

version 3.0 of the Seeeduino Stalker

  • bare minimum (empty setup, empty loop): 6.7 mA
  • LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 0.05 mA = 50 uA

Unfortunately, that library is written for the AVR platform and so it will not work with the ARM based Autonomo.

We also measure this. On Slack @Philip got the magic number of 200 uA. How can we achieve this?
Any progress?

I’ve done some testing today with:

Arduino IDE 1.6.8
SODAQ_SamdCore 1.6.7
uCurrent Gold
Fluke 101 DMM

It seems to use less current if the board is reset or power cycled after the USB is disconnected. I tried turning off as many peripherals as possible using the PM registers (AHBMASK, APBAMASK, APBBMASK & APBCMASK). I didn’t see any reading much lower than 500 uAs. There also seems to be some inconsistent behaviour depending on if the device was started with the USB plugged in, by external reset or by power on reset.

It would be interesting to run this on the SAMD21 evaluation board in order to get an idea of how much of that is being used by the other components.

The current is about 500 uAs with this sketch:

// Test sleep current

void setup() 
{
  // LED On
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  // Start delay of 10s to allow for new upload after reset
  // Do not remove as there is no wake up trigger
  delay(10000);

  // LED Off
  digitalWrite(LED_BUILTIN, LOW);

  // Set sleep mode
  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

  //Disable USB
  USB->DEVICE.CTRLA.reg &= ~USB_CTRLA_ENABLE;
  PM->AHBMASK.reg &= ~PM_AHBMASK_USB;
  PM->APBBMASK.reg &= ~PM_APBBMASK_USB;

  //Enter sleep mode
  __WFI();
  
  //...Sleep forever

  //Enable USB
  PM->APBBMASK.reg |= PM_APBBMASK_USB;
  PM->AHBMASK.reg |= PM_AHBMASK_USB;
  USB->DEVICE.CTRLA.reg |= USB_CTRLA_ENABLE;
}

void loop() 
{
}

I should also mention that when the bootloader is doing its 500ms double tap delay, the reading is ~335 uAs.

Thanks! With your code we got it a little down. But not a spectacular amount. We tried different autonomo’s and some are in the mid 500uAs and other in the lower 600uAs.

Setup:
Arduino 1.6.7
Sodaq_SamdCore 1.6.7
uCurrent Gold
Some Velleman DMM (uCurrent makes a good range readout)
Measured on the lipo wires.

I think I’ve found the issue. When Arduino initialises the chip, it sets all the digital pins to INPUT mode.

To remove that step comment out lines 89-92 of wiring.c found in the board install directory:
…/Arduino15/packages/SODAQ/hardware/samd/1.6.7/cores/arduino/wiring.c

By skipping that step and using the sketch below (a simplified version of the one above), I am getting a reading of about ~38 uAs.

Note: It is not necessary to disable the USB, however, doing so disconnects the device gracefully from the host.

// Test sleep current

void setup() 
{
  // LED On
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  // Start delay of 5s to allow for new upload after reset
  // Do not remove as there is no wake up trigger
  delay(5000);
  
  // LED Off
  digitalWrite(LED_BUILTIN, LOW);
  
  // Set sleep mode
  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

  //Disable USB
  USB->DEVICE.CTRLA.reg &= ~USB_CTRLA_ENABLE;
  
  //Enter sleep mode
  __WFI();
  
  //...Sleep forever
  
  //Enable USB
  USB->DEVICE.CTRLA.reg |= USB_CTRLA_ENABLE;
}

void loop() 
{
}

I should mention that depending on what other components are initialised, that figure will increase.

For example using the SleepInterrupt sketch from the test repository, the figure is about 80uAs.
This is due to having the EIC initialised and running (to catch the interrupt and wake the board).

Gabriel, do we have any insight on how long the battery will last - any guidance on how to calculate that ? (i understand it depends on powerconsumption while sleeping and the duty-cycle)

It is very difficult to estimate the required current of the active cycle without testing the specific software and hardware configuration. Even then it will vary greatly depending on the specific code it was running at any given instance. External components will also draw varying amounts of power (especially communication modules when active).

I was getting a reading of 36 uAs using the above sketch. That sketch does nothing but put the board to sleep. However, based on that figure you could come to a rough figure of about 7 years on a 2200mAh battery (2.2 / (3.6 x 10^-5) hours). This is not a realistic figure.

  • That figure is based on a 100% sleep cycle.
  • The battery itself will have a certain amount of self discharge.
  • Any useful sketch will require a much higher current both for the duty cycle and the sleep cycle (just adding an external interrupt to wake the board brought the sleep figure up to 80uAs).

You really have to test the specific hardware and software configuration to get the numbers.

The Autonomo (and other SODAQ boards) are designed with a on board battery charger which can be used with a solar panel (or other power generating devices). It is possible to design your software and hardware configuration so that less power is used by the board in a 24 hour cycle than what is generated by the solar panel. This requires tuning of the duty/sleep cycles as well as correctly specifying both the solar panel and battery capacities.

This document provides some details on how to minimise power use on the main chip:
http://www.atmel.com/Images/Atmel-42248-SAM-D20-Power-Measurements_ApplicationNote_AT04188.pdf

1 Like

Today I tested switching the data flash chip into ultra deep sleep mode.

This saves another ~25uAs.

This reduced the reading to ~10uAs for the whole Autonomo.

Thanks! We now have ~126uAs in sleep mode (included with wakeup RTC interrupt) we disabled all the input pins except for 1 pin.

How can we put the data flash chip into ultra deep sleep mode? And how do we get it out of that mode, when we come back from sleep into running mode?

To put the data flash into ultra deep sleep mode, you need to transmit to it the opcode 0x79. Any opcode sent after that will wake it up again (I use 0x00).

The basic process is:

  1. Start SPI.
  2. In case the data flash is already asleep, transmit a wake command. Wait 1ms.
  3. Transmit the opcode for ultra deep sleep (possibly wait another 1ms).
  4. Stop SPI.
  5. Reset the SPI pins (MISO, MOSI, SCK & SS_DFLASH).

You can skip step 5 but it will added 4-5uAs.

Here is the basic code:

void DFlashUltraDeepSleep()
{
  // SPI initialisation
  SPI.begin();

  // Initialise the CS pin for the data flash
  pinMode(SS_DFLASH, OUTPUT);
  digitalWrite(SS_DFLASH, HIGH);

  transmit(0x00); // In case already in sleep, wake
  transmit(0x79); // Now enter sleep
  //transmit(0x00); // Wake again, for testing

  // SPI end
  SPI.end();

  // Resets the pins used
  resetSPIPins();
}

void transmit(uint8_t val)
{
  SPISettings settings;
  SPI.beginTransaction(settings);
  digitalWrite(SS_DFLASH, LOW);

  SPI.transfer(val);
  
  digitalWrite(SS_DFLASH, HIGH);
  SPI.endTransaction();

  delayMicroseconds(1000);
}

void resetSPIPins()
{
  resetPin(MISO);
  resetPin(MOSI);
  resetPin(SCK);
  resetPin(SS_DFLASH);
}

void resetPin(uint8_t pin)
{
  PORT->Group[g_APinDescription[pin].ulPort].PINCFG[g_APinDescription[pin].ulPin].reg=(uint8_t)(0);
  PORT->Group[g_APinDescription[pin].ulPort].DIRCLR.reg = (uint32_t)(1<<g_APinDescription[pin].ulPin);
  PORT->Group[g_APinDescription[pin].ulPort].OUTCLR.reg = (uint32_t) (1<<g_APinDescription[pin].ulPin);
}

Gabriel what is the default state of the dataflash, i.e. should I explitcitly put it in deep sleep ?

The default mode after a power on reset, is idle (what it refers to as standby) which uses about 25uAs.

However, if you put the data flash to sleep and then reset the board in another way (e.g. external reset, software reset or watchdog reset), the data flash will remain in the ultra deep sleep mode. That is why the above example first attempts to wake the data flash chip.

@GabrielNotman Where did you get that opcode (0x79) from? The AT45DB161D datasheet I have only describes:

  • Deep Power-down B9H
  • Resume from Deep Power-down ABH

And the resume sequence takes more than “send any opcode”.