Go Down

Topic: Power Down consumption on custom board (Read 7974 times) previous topic - next topic

estratos

Feb 28, 2011, 01:02 pm Last Edit: Feb 28, 2011, 01:11 pm by estratos Reason: 1
Hi,

On a custom board, consisting in an Atmega328P and some few passives, I want to check the current consumption of the board in Power Down mode. The only pull-up resistor is the 10k one for the reset circuit. Then there are a number of de-coupling capacitors, that's all. No external crystal used. The atmega is running at 8 MHz internal RC clock, 3.3VDC, BOD disabled.

I've picked some ideas from this post:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1285656727/5

So I've created a very simple sketch that puts the atmega in Power Down State:

Code: [Select]

#include <avr/power.h>
#include <avr/sleep.h>

void setup()
{                
 byte i;
 
 // Ensure no floating pins
 for(i=0; i<32 ; i++)
 {
   pinMode(i, OUTPUT);
   digitalWrite(i, LOW);
 }

 // Power-down state
 set_sleep_mode(SLEEP_MODE_PWR_DOWN);
 sleep_enable();
 // Disable functions
 power_all_disable();
 // Enter sleep mode
 sleep_mode();
}

void loop()
{
}


The issue is that I was hopping to see some few microamps entering the board but I'm finally monitoring 105 uA after entering the Power Down state. Being the circuit so simple I wonder whether I'm entering the low-power state and disabling the functions correctly... On the other hand, I'm now checking the possible leakage through the de-coupling capacitors.

Thanks in advance for your help.

Daniel.

48X24X48X


estratos


Hi,

Is there any 3.3 V regulator?


No, I'm directly powering the board from an external power supply.

Thanks.

Coding Badly

Quote
BOD disabled


Disabled by fuse settings?

Quote

 // Ensure no floating pins
 for(i=0; i<32 ; i++)
 {
   pinMode(i, OUTPUT);
   digitalWrite(i, LOW);
 }


There are no definitions for pins 20 through 31 and neither pinMode nor digitalWrite check for an out-of-bounds pin number.  Change the for condition to "< 20".

Quote
// Disable functions
 power_all_disable();


I vaguely recall that this function does not catch everything.  I can't remember the details so you'll have to search the forum.

estratos

Thank you very much for your response.


Quote
BOD disabled


Disabled by fuse settings?


Yes


Quote

 // Ensure no floating pins
 for(i=0; i<32 ; i++)
 {
   pinMode(i, OUTPUT);
   digitalWrite(i, LOW);
 }


There are no definitions for pins 20 through 31 and neither pinMode nor digitalWrite check for an out-of-bounds pin number.  Change the for condition to "< 20".


OK thanks. I copied that piece of code from an sketch written for the Atmega644...


Quote
// Disable functions
 power_all_disable();


I vaguely recall that this function does not catch everything.  I can't remember the details so you'll have to search the forum.

[/quote]

Indeed, removing "power_all_disable()" from the code does not add a single uA to the consumption so I've decided to directly work with the PRR register instead:

Code: [Select]

#include <avr/power.h>
#include <avr/sleep.h>

void setup()
{               
  byte i;
 
  // Ensure no floating pins
  for(i=0; i<20 ; i++)
  {
    pinMode(i, OUTPUT);
    digitalWrite(i, LOW);
  }
 
  // Power-down board
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
 
  sleep_enable();
  // Disable functions
  PRR = 0xFF;
 
  // Enter sleep mode
  sleep_mode();
}

void loop()
{
}


Unfortunately, the above changes still achieve 105 uA in the global consumption. I'm beginning to think that I have a damaged capacitor or a micro-shortcut somewhere on my board...

Thanks again.

Coding Badly

From the datasheet...

9.11.3 PRR - Power Reduction Register

Bit 0 - PRADC: Power Reduction ADC
Writing a logic one to this bit shuts down the ADC. The ADC must be disabled before shut down.
The analog comparator cannot use the ADC input MUX when the ADC is shut down.

48X24X48X

Quote
From the datasheet...

9.11.3 PRR - Power Reduction Register

Bit 0 - PRADC: Power Reduction ADC
Writing a logic one to this bit shuts down the ADC. The ADC must be disabled before shut down.
The analog comparator cannot use the ADC input MUX when the ADC is shut down.


But, if we don't enable the ADC at the 1st place, we don't have to do the above setting right?
Look at 9.10.1 of the datasheet.

Coding Badly

The ADC is enabled by the core.  I believe init in wiring.c does the deed.

48X24X48X

Found it, it is in the wiring file in the core folder. The ADC is enabled by default.
For timers, I think for power down mode, the clock source is not available for it to work.

estratos

OK, trying to disable individual functions before stopping each function clock:

Code: [Select]

#include <avr/power.h>
#include <avr/sleep.h>

void setup()
{               
  byte i;
 
  // Ensure no floating pins
  for(i=0; i<20 ; i++)
  {
    pinMode(i, OUTPUT);
    digitalWrite(i, LOW);
  }
 
  // Power-down board
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
 
  sleep_enable();
  // Disable functions
  power_adc_disable();
  power_spi_disable();
  power_twi_disable();
  power_usart0_disable();
  power_timer0_disable();
  power_timer1_disable();
  power_timer2_disable();
 
  PRR = 0xFF;
 
  // Enter sleep mode
  sleep_mode();
}

void loop()
{
}


Consumption is still around 105 uA  =(

Thanks guys!

estratos

I've investigated the possibility of "loosing" current through the decoupling capacitors but, even in the worst cases, they might be wasting a total of a few uAmps maximum. I think I'm going to order a couple of DIP-form atmegas in order to do the tests on a breadboard. Then I'll be able to mount only the essential components and measure the current consumption. That will let me discard any programming-related problem.

Coding Badly

These...

Quote
// Disable functions
  power_adc_disable();
  power_spi_disable();
  power_twi_disable();
  power_usart0_disable();
  power_timer0_disable();
  power_timer1_disable();
  power_timer2_disable();


...and this...
 
Quote
PRR = 0xFF;


...are equivalent.  You still have not disabled the ADC.

estratos

You're right!

Let's do then:

Code: [Select]

#include <avr/power.h>
#include <avr/sleep.h>

void setup()
{               
  byte i;
 
  // Ensure no floating pins
  for(i=0; i<20 ; i++)
  {
    pinMode(i, OUTPUT);
    digitalWrite(i, LOW);
  }
 
  // Power-down board
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
 
  sleep_enable();
 
  // Disable ADC
  ADCSRA &= ~(1 << ADEN);

  // Power down functions
  PRR = 0xFF;
 
  // Enter sleep mode
  sleep_mode();
}

void loop()
{
}


And the result is... less than 0.2 uAmps !!!

Thanks a lot guys for your great help!!

CrossRoads

Can you wake up on external interrupt with these power down settings??
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Coding Badly

I think Atmel calls them "asynchronous interrupts".  Off the top of my head (read that as probably with mistakes): pin-change interrupts, USART activity, TWI address match, watchdog interrupt, INTx level.  For the 328, the table in "9.1 Sleep Modes" provides a good overview.

Go Up