Atmega328p Power Saving Techniques

pito:
@Nick: a quick comment - when you measure the voltage drop on a 1Meg resistor pls do consider a standard meter has ~10Meg internal resistance. So, 1Meg || 10Meg = 0.909Meg, thus your nA values will be 9% off.. :wink:

That's a very good point, and it shows the flaw in my plan. I don't normally measure current like that, and was trying to help the OP resolve whether or not his meter was wildly out. The uCurrent device doesn't have that flaw, as it amplifies the voltage drop across its internal resistor.

In fact, my reading was out by about 10% and you have explained why, thanks!

Lefty - I think I know what you mean by latency time.

Mr. Gammon - With bare minimum code running on 3.3V, the atmega draws 46.6 mA. In its sleep mode, it draws .01mA. Correct me if I'm wrong, but it seems the only way to wake the chip from sleep mode without drawing additional current from the system is through the internal watch dog timer. If this is the case, then is it possible to save more power using the watch dog timer to sleep for 200ms and wake for 7ms and during that 7ms of wake, you can power up the chip and pins and do an external pin interrupt to receive signal?

Also, is it possible to save even more power by achieving a "pulsed supply voltage" such that the voltage and current is just enough to receive signal as apposed to continuously drawing a constant power from the source?

Thanks for keeping up with my thread.

You don't have to use the watchdog, in itself that draws quite a lot of current.

My tests of interrupts (eg. pin change interrupts) show that you can be down to nano-amps until a key is pressed. See:

100 nA until a key is pressed.

Just tested your setup and it's really nice. I didn't have the keypad, so I just used a push button. But the real challenge here is how do I incorporate this setup with an ir receiver instead of a push button. The receiver needs a constant 0.35mA supply current in order to work. So it seems that there's no better way to save more power than use a watch dog timer fluctuating from 100nA to 0.35mA to wake the chip intermitedly.

Normally IR receivers are in mains-powered equipment (eg. a TV) and the sender (the remote) is battery powered. Trying to save power whilst detecting IR pulses is going to be problematic.

kentc:
I'm between Sketch C and D in the link and reading 0.40mA after by turning ADC off. I should expect a huge power reduction according to his method, but I'm not. I don't know if I'm missing any steps leading up to that reduction, but if you could help, that'll be fantastic!

How are you measuring it? The error might be in the measuring device once you get down to these values.

@fungus - I got that problem solved. Thanks

@Mr. Gammon - Okay, so that concludes that for IR! I don't know much about rf transceiver, but could you help clear this up for me? I found an rf transceiver model nRF24L01 that takes about 900 nanoAmps in sleep mode, 22 microAmps in standby mode, and above 10milliA when transmit and/or receive. My questions are when this transceiver is in sleep or standby mode, can it receive signal or do you have to power it up for it to receive or does the signal cause it to power up from sleep mode?

Here's a link: Page 14 is where power consumption is at:

https://docs.google.com/viewer?a=v&q=cache:ANWvWgCEyaMJ:www.nordicsemi.com/eng/content/download/2730/34105/file/nRF24L01_Product_Specification_v2_0.pdf+&hl=en&gl=us&pid=bl&srcid=ADGEESjvGkOhVwt8_Dp3LKqfqZeASZGVzVX04R0alriMhtZwfG4NXR5ufvPKsYPNKC-FgnVFwibbZbhyXNJ_YDYMNdSkiMG-LrY544m2CsxP1ApsJ3LVzEBT2u_mmwS8yxC39q1PbF6R&sig=AHIEtbTIzEoK25INVW44oQYBPP-vWYbArw

kentc:
Okay, so I tried your method and measured the voltage across the circuit which comes to about 4.8V. Putting a 1M Ohmz resistor in series and measured the drop across it comes out to 4.1V. Did Ohmz law and got 4100 nanoAmps.

I'm doing the same thing right now and getting very similar numbers (measured about 0.33mA current with my cheapo meter, got 4.1V with the 1M resistor).

I'm confused about what's happening though:

If the voltage drop across the 1M resistor is 4.1V, that means there's only 0.9V across the chip - not enough to keep running! How do I know it's sleeping properly?

You know it sleeps properly when you are able to measure the current dissipation across the chip to be less than .1mA. The chip can go as low as .1uA if you set the fuses and clock correctly.

Make sure you don't have ANY other sensors or leds or "stuff" hooked up into your circuit, because they may be drawing power and current from the system. Don't have anything on your breadboard except for your atmega chip.

kentc:
You know it sleeps properly when you are able to measure the current dissipation across the chip to be less than .1mA. The chip can go as low as .1uA if you set the fuses and clock correctly.

I know that...my question is about how to accurately measure the current. I want to confirm that I'm setting the fuses and clock correctly.

Of course we're going to measure a small current if we put a 1 Megaohm resistor in a 5V circuit, Ohms law tells us it can't possibly be more than 5uA.

I want to know how this method tells us the current consumption of the AVR chip. It doesn't make any sense to me.

More thoughts:

If I'm seeing a voltage drop of about 4V across my 1M resistor in a 5V circuit, that means the AVR chip has a resistance of about 250K at that moment in time.

Using that resistance value I can calculate current consumption with a real working voltage, eg. 2.5V from a coin cell.

At 2.5V the chip would use about 10uA (assuming the resistance stays the same). This is far more than the datasheet says it should draw. The datasheet says it should draw less than 4uA at 2.5V in sleep mode with watchdog timer enabled.

(nb. This is a Tiny85V, not a Mega328P...)

I guess what I need to do is find a resistor which gives me a voltage drop closer to the 2.5V target voltage.

Ok...some results.

I tried a 100K resistor and got about 4V drop across it (the same as the 1M resistor - weird!)

I tried a 10K resistor and got 2.27V drop across it. That gives 2.73V across the chip, which is in the right range.

But...2.27V across a 10K resistor is .227mA - two orders of magnitude higher than it should be.

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.

FWIW my sleep code is:

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();

Brownout detection is disabled by fuse bits and the watchdog timer wakes the chip up after the correct amount of time (I've timed it).

fungus:
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 ?

Have you set ADCSRA = 0?

Our measurements may not likely be the same based on several factors. Firstly, you're using a different chip. Secondly, 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.

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

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

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

dc42:

fungus:
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.

fungus:

dc42:

fungus:
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?

kentc:
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.

kentc:
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.

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

Yes, I've done ALL of that.

kentc:
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?

dc42:
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:

#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.

kentc:
...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.

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