Pages: 1 2 3 [4] 5   Go Down
Author Topic: Atmega328p Power Saving Techniques  (Read 5652 times)
0 Members and 1 Guest are viewing this topic.
Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5469
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So I'm as confused as ever. Going into sleep mode definitely uses less power (I can measure the difference!) but consumption doesn't seem to be anywhere near as low as it should be.

Did you read my reply #18 ?

Yep. I've done it with/without the programmer, it made no real difference.
Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6614
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So I'm as confused as ever. Going into sleep mode definitely uses less power (I can measure the difference!) but consumption doesn't seem to be anywhere near as low as it should be.

Did you read my reply #18 ?

Yep. I've done it with/without the programmer, it made no real difference.


You've misunderstood my reply, I didn't say anything about the programmer. What have you done to ensure that none of the I/O pins is a floating input?
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5469
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't know what your setup looks like to determine what's wrong. It could be a software issue or hardware issue, such as something wrong with the wiring.

There are no wires, just a chip.

Are you asking how to accurately measure current of the chip using a multi-meter or with the 1M Ohmz method Nick showed?

Any method that works.

Here, follow these steps to get your power readings: http://www.gammon.com.au/forum/?id=11497

Yes, I've done ALL of that.

I was able to get the Attiny85V chip down to pretty low power in the uA as well using these steps.

Question is: How do you know? How do you measure it?

Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5469
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You've misunderstood my reply, I didn't say anything about the programmer. What have you done to ensure that none of the I/O pins is a floating input?

I set them to input with pullup resistors. I also set DIDR0 to all 1s for good measure.

Here's the complete sketch I'm using at the moment:

Code:
#include <Arduino.h>
#include <avr/power.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/cpufunc.h>
#include <util/delay.h>

/*================================================================
  Go to sleep for 4 seconds
================================================================*/
// Watchdog interrupt vector
ISR (WDT_vect)
{
  WDTCR &= ~(1<<WDIE);    // Disable the watchdog interrupt
}

void doSleep()
{
  // Set watchdog time to 4 seconds
  cli();
  byte b = (1<<WDE)|(1<<WDP3)|(0<<WDP2)|(0<<WDP1)|(0<<WDP0);
  WDTCR = b;
  WDTCR = b|(1<<WDIE);    // Enable watchdog interrupt (this wakes me up!)
  wdt_reset();
  // sleep
  sei();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_mode();
}

/*================================================================
  Main program
================================================================*/
void setup()
{
  power_all_disable();
  // All pins input with pullups
  DDRB = 0;
  PORTB = 0x1f;
  // Do these achieve anything? They don't seem to...
  ADCSRA = 0;
  DIDR0 = 0x3c;
}

// Alternate between sleep/work (the reading on the multimeter will switch every 4s...)
void loop()
{
  // Sleep for 4s
  doSleep();
  // Work for 4s
  _delay_ms(4000);
}


With a 10k resistor in series with the 5V supply the voltage across the resistor changes between 2.2V (sleep mode) and 3.6V (in _delay_ms()). That corresponds to currents of 220uA and 360uA - two orders of magnitude more than what I should be getting.
« Last Edit: April 25, 2013, 10:45:47 am by fungus » Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5469
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

...with the 1M Ohmz method Nick showed?

Aside: I don't understand that method. With a 1M resistor on a 5V supply you can never measure than 5uA no matter what the chip is doing. It's Ohms law.
« Last Edit: April 25, 2013, 06:59:04 am by fungus » Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5469
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is the complete circuit I'm using to get the 2.2/3.6V readings:



* 2013-04-25 13.12.29.jpg (141.94 KB, 1059x546 - viewed 24 times.)
Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6614
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Try adding a 0.1uF decoupling capacitor between the Vcc and ground pins of the chip. Without it, the chip may misbehave.

btw I just found this in the attiny datasheet:

Quote
10.2.5 Digital Input Enable and Sleep Modes
As shown in Figure 10-2, the digital input signal can be clamped to ground at the input of the
schmitt-trigger. The signal denoted SLEEP in the figure, is set by the MCU Sleep Controller in
Power-down mode to avoid high power consumption if some input signals are left floating, or
have an analog signal level close to VCC/2.
SLEEP is overridden for port pins enabled as external interrupt pins. If the external interrupt
request is not enabled, SLEEP is active also for these pins. SLEEP is also overridden by various
other alternate functions as described in “Alternate Port Functions” on page 59.

So it looks like setting the pins to inputs with pullups enabled isn't necessary on the attiny. It might even be worth trying without the internal pullups enabled.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5469
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Try adding a 0.1uF decoupling capacitor between the Vcc and ground pins of the chip. Without it, the chip may misbehave.

I was actually doing most of the tests in the little PCB shown below which has a capacitor. The breadboard was a paranoia test. smiley

(No, there's no difference in readings...)

btw I just found this in the attiny datasheet:

...

So it looks like setting the pins to inputs with pullups enabled isn't necessary on the attiny. It might even be worth trying without the internal pullups enabled.

I just tried it...maybe a tiny bit lower without pullups, but background noise level.

There's a definite difference between sleep/awake (220uA vs. 360uA) so I'm fairly confident that the 'sleep' code is doing something.

This makes me think something is left switched on, something that uses 220uA. I don't know what it might be though, there's only four things you can switch off and I've done all of them (individually, all at once, it's the same).


* 2013-04-25 14.50.26.jpg (62.81 KB, 668x474 - viewed 21 times.)
« Last Edit: April 25, 2013, 08:14:17 am by fungus » Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6614
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I built an attiny-based remote control a while ago, and I seem to be using different sleep code. This is what I use:

Code:
// Wait for button to be pressed
do
{
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
cli();
if (PORTB & 0b00000100)
{
GIMSK = _BV(INT0);
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
}
sei();
uint32_t now = micros();
while ((micros() - now) < 5000) {}
} while (PORTB & 0b00000100);

Ignore the PORTB stuff, it checks that a button isn't pressed. I can't remember why I used sleep_enable(), sleep_cpu() and sleep_disable() rather than sleep_mode(), but I expect there was a reason (possibly to do with using an interrupt to wake up from sleep mode, but maybe not).

What does the current drop to if you don't use the watchdog?
« Last Edit: April 25, 2013, 08:23:26 am by dc42 » Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5469
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I built an attiny-based remote control a while ago, and I seem to be using different sleep code. This is what I use:

Code:
sleep_enable();
sei();
sleep_cpu();
sleep_disable();

The only difference between that and "sleep_mode()" is the "sei()" in the middle.

I tried it but it makes no difference (not really surprising because I powered down all the timers so there's no interrupts.


What does the current drop to if you don't use the watchdog?

If I go to sleep and never wake up? No difference.

The watchdog is designed for this usage, I doubt it's responsible for the 220uA.

Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6614
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The watchdog is designed for this usage, I doubt it's responsible for the 220uA.

It certainly shouldn't be, the datasheet shows the power-down current @ 3V to be about 0.4uA with watchdog enabled and 0.2uA with watchdog disabled.

I might just try this out tonight. What fuse settings are you using? Have you tried it with more than one attiny chip?
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5469
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I might just try this out tonight. What fuse settings are you using?

My boards.txt has:
Code:
attiny85.name=ATtiny85 (internal 1 MHz clock)
attiny85.bootloader.low_fuses=0x62
attiny85.bootloader.high_fuses=0xd7
attiny85.bootloader.extended_fuses=0xff
...

Have you tried it with more than one attiny chip?

Yes.

Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Switzerland
Offline Offline
Sr. Member
****
Karma: 6
Posts: 375
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Are you sure the watchdog is being set correctly?  Normally you need to set WDCE before changing WDE or the prescaler bits.

BTW, after the watchdog interrupt WDIF is cleared automatically (so you don't need to do it in the ISR).  Meanwhile the WDT is still running, and may reset the processor before the 4s delay finishes (not that it matters much in this case).

I also noticed that you're not switching the ADC off after disabling it (power reduction register, PRR).
« Last Edit: April 25, 2013, 11:23:04 am by tim7 » Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5469
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Are you sure the watchdog is being set correctly?  Normally you need to set WDCE before changing WDE or the prescaler bits.

Not if the WDTON bit is set in the fuses (bit 4 of fuse high byte)...

BTW, after the watchdog interrupt WDIF is cleared automatically (so you don't need to do it in the ISR).  Meanwhile the WDT is still running, and may reset the processor before the 4s delay finishes (not that it matters much in this case).

This is still a bit mysterious to me. I checked the MCUSR:WRDF flag in setup() but I never had the watchdog cause a reset, only interrupts.

I need to investigate further but I'm more worried about the power consumption at the moment.

I also noticed that you're not switching the ADC off after disabling it (power reduction register, PRR).

The "power_all_disable()" does that.
Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Switzerland
Offline Offline
Sr. Member
****
Karma: 6
Posts: 375
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The "power_all_disable()" does that.

Are you sure?  The datasheet makes a point of saying that the ADC must be disabled (ADCSRA) before being shutdown (PRR).  You commented that disabling the ADC doesn't seem to do anything, but it should make a noticeable difference.
Logged

Pages: 1 2 3 [4] 5   Go Up
Jump to: