Getting Atmega into uA Standby?

I’m having some bother putting my Atmega328P-PU to sleep into the microAmp ranges…

I’ve been all over Nick Gammon’s thread on his site here:- https://www.gammon.com.au/forum/?id=11497 following as many of the steps as possible but I can’t get my Atmega to draw any less than 1.4mA when put to sleep.

I am using this sketch as my benchmark / baseline to test the Atmega (also from Nick Gammon’s Site):-

//LOW POWER BASE LINE TEST SKETCH H FROM NICK GAMMON FORUMS - https://www.gammon.com.au/forum/?id=11497


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

const byte LED = 9;

void flash ()
  {
  pinMode (LED, OUTPUT);
  for (byte i = 0; i < 10; i++)
    {
    digitalWrite (LED, HIGH);
    delay (50);
    digitalWrite (LED, LOW);
    delay (50);
    }
    
  pinMode (LED, INPUT);
    
  }  // end of flash
  
// watchdog interrupt
ISR (WDT_vect) 
{
   wdt_disable();  // disable watchdog
}  // end of WDT_vect
 
void setup () { }

void loop () 
{
 
  flash ();
  
  // disable ADC
  ADCSRA = 0;  

  // clear various "reset" flags
  MCUSR = 0;     
  // allow changes, disable reset
  WDTCSR = bit (WDCE) | bit (WDE);
  // set interrupt mode and an interval 
  WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0);    // set WDIE, and 8 seconds delay
  wdt_reset();  // pat the dog
  
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
  noInterrupts ();           // timed sequence follows
  sleep_enable();
 
  // turn off brown-out enable in software
  MCUCR = bit (BODS) | bit (BODSE);
  MCUCR = bit (BODS); 
  interrupts ();             // guarantees next instruction executed
  sleep_cpu ();  
  
  // cancel sleep as a precaution
  sleep_disable();
  
  } // end of loop

My Atmega is set up on a breadboard running at 3V3 @ 8Mhz INTERNAL with nothing connected to it other than VCC and GND which is supplied by the 3V3 and GND pins from a NANO. My DMM is in series with the 3V3 wire coming from the NANO to the Atmega. I don’t have the LED connected as shown in the Arduino Sketch.

When I run Nick’s Sketch, I can see that the Atmega is doing something along the lines of going to sleep because I can see the meter periodically jumping up and then back down as expected but the current consumption isn’t what I’d expected.

When the Atmega comes out of Sleep, my DMM shows around 5.5mA and when the Atmega goes to sleep again, it drops to 1.5mA. Not the microAmp ranges I’d hoped for.

Now you can’t get a simpler circuit setup than I’ve got on breadboard and you can’t get a more simple sketch to test with so I’m at a loss as to why my Atmega won’t do what I think it’s meant to do.

The only thing left really is fuses. And until now, fuses are a subject I’ve happily avoided having to deal with. I tend to use the board files inside of the Arduino IDE so that could be where the issue is, I don’t know.

What I can tell you is that I struggled to find a board file for Atmega328 at 3V3 @ 8Mhz Internal Oscillator. Eventually I found a board file but it took a lot of faffing about to install it in the modern Arduino IDE for it to find so I could burn it to the chip. So maybe I’ve done something wrong there?

I couldn’t find much up to date information on telling an Atmega to run at those speeds and voltages so I went with what I could.

This is the BOARDS.TXT File I have been using to program my Atmegas and I’ve had to put it into folders in my Arduino projects folder like so: Libraries/Documents/Arduino/Hardware/Breadboard/AVR/Boards.TXT

##############################################################

atmega328bb.name=ATmega328P-PU (8 MHz internal clock)

atmega328bb.upload.protocol=arduino
atmega328bb.upload.maximum_size=30720
atmega328bb.upload.speed=57600

atmega328bb.bootloader.low_fuses=0xE2
atmega328bb.bootloader.high_fuses=0xDA
atmega328bb.bootloader.extended_fuses=0x05

atmega328bb.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
atmega328bb.bootloader.unlock_bits=0x3F
atmega328bb.bootloader.lock_bits=0x0F

atmega328bb.build.mcu=atmega328p
atmega328bb.build.f_cpu=8000000L
atmega328bb.build.core=arduino:arduino
atmega328bb.build.variant=arduino:standard


atmega328bb.bootloader.tool=arduino:avrdude
atmega328bb.upload.tool=arduino:avrdude

Any help appreciated!

Thx!

Do you get the same result if you physically disconnect the LED from pin 9 ?

pi_and_chips:
What I can tell you is that I struggled to find a board file for Atmega328 at 3V3 @ 8Mhz Internal Oscillator.

I think you are measuring the wrong way. As you have a to much bare-bone setup (no decoupling capacitors) you’re using the decoupling from the connected Nano and so you’re measuring these currents too. In my setups I didn’t reach the exact same values as Nick but power down sleep with ADC off show values clearly below 1mA.

6v6gt:
Do you get the same result if you physically disconnect the LED from pin 9 ?

Hi, I didn't connect the LED, I used the multimeter to confirm my readings instead - but I will re-run the experiment with the LED and will also try with the section of code which makes the LED blink commented out as well - thanks for the suggestion :slight_smile:

DrAzzy:
GitHub - MCUdude/MiniCore: Arduino hardware package for ATmega8, ATmega48, ATmega88, ATmega168, ATmega328 and ATmega328PB

Thank you! That's a VERY interesting looking link and I'll be ploughing through it after I've answered this post.

pylon:
I think you are measuring the wrong way. As you have a to much bare-bone setup (no decoupling capacitors) you're using the decoupling from the connected Nano and so you're measuring these currents too. In my setups I didn't reach the exact same values as Nick but power down sleep with ADC off show values clearly below 1mA.

Hi,

What I didn't mention in my OP, to save confusion was that I had first noticed something wasn't right when the Atmega was in my prototype PCB. I had expected a much lower current draw even with a 3V3 regulator and the correct decoupling on the Atmega itself.

With only the Atmega and the Voltage regulator powered up on my PCB, I observed a current draw of 4.8mA.
I knew that much of it was down to a poor choice of Voltage Regulator (which I'll be changing soon to one with a lower quiescent current) but still it wasn't what I was expecting.

So I removed the Atmega and powered up my PCB with JUST the voltage regulator powered up and I measured 3.35mA current draw for just the regulator meaning the the difference was roughly what the Atmega was taking - 1.45mA.

To rule out my PCB and the Voltage Regulator and anything else that might be fudging my results completely, I then did as stated in my original post and wired up just the Atmega on the breadboard using the Nano to power it and measured a current draw of 1.45mA - which seems too coincidental to me - I may be wrong...

Ideally, I would like to get my project down to around 500uA or less combined current draw for the Atmega and Regulator if possible. That's my goal. But something is stopping it from happening and I'm not sure what - yet...

I will check out that link kindly posted by DrAzzy and see if I can see anything helpful there in the meantime.

Thanks!!

QUICK UPDATE:-

I've just installed Mini Core suggested by DrAzzy and I've burnt the bootloader for 328P using 8Mhz Internal clock with BOD disabled. I did this using my USBASP.

I then re-uploaded Nick Gammon's sketch but I'm still getting 1.5mA draw showing on my DMM...

I've then tried several other low power sketches from various forums and websites all of which seem to work okay for everyone else and they're getting measurements in the uA range and that's using cheapo DMMs :S
Yet no matter what sketch I try with, I'm still getting 1.5mA draw....

I can't get my head around it...

So either the error lies in my measurements OR there's something not right with the chip I'm using.
I can't see what else it could be?

I did read a thread in these very forums about taking the current measurements more accurately using two DMMs. One to read the current and one to read the voltage but I'm pretty certain my DMM isn't lying to me. I may be very wrong though...

Back to the drawing board though I seem to be out of pencils and paper, and a drawing board LOL

:confused:

Thanks.

I'm guessing no one has any ideas as to why my Atmega won't go below 1.5mA current draw at Power Down sleep?

Me neither lol.

I've tried different bootloaders and I've tried various low power sketches and libraries but the Atmega is still allegedly eating 1.5mA. I can't find any other references on the internet to anyone having the same problem so I'm left to conclude it must be these Atmega IC's I'm using.

Everywhere I've looked and every sketch I've tried, no one has had any issues. They've all reported currents of less than 1mA.

I think this batch of Atmegas I'm using may have originated from eBay so there's no telling what they are. They might very well be plain old 328's without the P and some unscrupulous bugger has re-branded them.. who knows. I've read of all sorts of practices with some of these ICs from eBay / China.

SO... I've now ordered some genuine Atmega328P-PU ICs from Farnell (Element14). £15 for 5 delivered. I about fell through the floor! I'll be even more gutted if these Atmega ICs do the same thing and I see 1.5mA on my DMM when I test them with the low power sketch.

How do you measure the current? You will need to change the DMM's range after the processor has gone to sleep. This will interrupt the supply current so the processor resets and starts up again. On the other hand if you use the µA-range from the beginning the DMM will present a large shunt resistor to the circuit which prevents the processor from running properly.
What DMM do you use and how is it connected? Please provide a schematic

From the description, it is not clear if there is a voltage regulator in the path in which the current is being measured or not.
If you succeeded in changing the fuses or burning a bootloader, the problem is unlikely to be a relabeled plain ATMEGA328 chip because these have another device signature. I guess you know that changing the fuses is not simply a matter of changing boards.txt. You have to burn the bootloader as well if you use the Arduino IDE for this.
In the OP you say “When the Atmega comes out of Sleep, ...” . How are you forcing it to wakeup?

olf2012:
How do you measure the current? You will need to change the DMM's range after the processor has gone to sleep. This will interrupt the supply current so the processor resets and starts up again. On the other hand if you use the µA-range from the beginning the DMM will present a large shunt resistor to the circuit which prevents the processor from running properly.
What DMM do you use and how is it connected? Please provide a schematic

Hi olf2012,

I've been using an Auto Ranging DMM set to mA with two decimal place precision. Not great but a drop from mA to uA should show up. When the Atmega is "sleeping", the DMM shows 1.45 - 1.5mA. When the Atmega wakes periodically, it rises to about 5mA and then goes back down when the Atmega goes to sleep. It does this no matter what low power code / sketches / libraries I've tried.

6v6gt:
From the description, it is not clear if there is a voltage regulator in the path in which the current is being measured or not.
If you succeeded in changing the fuses or burning a bootloader, the problem is unlikely to be a relabeled plain ATMEGA328 chip because these have another device signature. I guess you know that changing the fuses is not simply a matter of changing boards.txt. You have to burn the bootloader as well if you use the Arduino IDE for this.
In the OP you say “When the Atmega comes out of Sleep, ...” . How are you forcing it to wakeup?

Hi 6v6gt,

Oddly, I'm getting the same results no matter how the Atmega is powered.

I've tried the Atmega in my prototype PCB which uses a 3V3 regulator (having measured the regulator on its own and subtracted the difference with the Atmega installed) and get roughly 1.45mA draw and I've tested with just the Atmega set up on a breadboard where I've used the 3V3 pin from a Nano to power it. I've put my DMM in series with the 3V3 from the Nano to the Atmega and the current draw is weirdly the same.

RE: Bootloader, yes I did re-burn the bootloader using the suggested mini core bootloader (Atmega328P, 3V3 @ 8MHz Internal) prior to uploading sketches but still the same result.

To wake up the Atmega, I am using the WDT set at 8 second intervals in the example codes I've been trying in order to periodically wake the Atmega up from sleep to check if anything needs to happen. I've tried several example codes / libraries but even the most basic of sketch / code yields the same results - 1.45 - 1.5mA. It really is odd.

The Atmega appears to go to sleep in that I see the current draw sitting at 1.45 - 1.5mA and after aprox 8 seconds, the current draw increases to around 5mA and then drops back to 1.45 - 1.5mA.

If you say it can't be the Atmega chip then I am happy to accept that. I am no expert so I must be doing something wrong somewhere. But I can't understand where.

Here is my process for handling the Atmega....

I use a USBASP programmer and a small breadboard to program my stand alone Atmega(s). Initially for first programming, I have the Atmega set up with a 16Mhz crystal and two 22uF caps.

The first thing I do is to select the correct board, processor and desired clock speed then I click upload using programmer. No probs.

In my case, I can then remove the 16Mhz crystal and the two caps because the chip is now running on the internal oscillator at 8Mhz. From there on in I just upload my code to the Atmega using Upload Using Programmer.

I don't get any errors or complaints and the Atmegas all seem to run okay after programming (i.e. seem happy at 3V3 with the internal oscillator).

Beyond that, I don't know if I'm missing something or doing something wrong...

I've tried all kinds of code for low power and with all the codes I've tried, including Nick Gammon's sketches, I've not seen or heard anyone reporting anything like this. They all just seem to get results. Not always identical but certainly in the expected ball park.

So I'm at a loss.....

Thanks for all the replies so far guys, - in the meantime, I'll keep on digging :slight_smile:

Never mind what I wrote. I didn't see "all of your response" above where you wrote, "RE: Bootloader, yes I did re-burn the bootloader using the suggested mini core bootloader (Atmega328P, 3V3 @ 8MHz Internal) prior to uploading sketches but still the same result." That explains it - my confusion. :slight_smile:

pi_and_chips:
Here is my process for handling the Atmega....

I use a USBASP programmer and a small breadboard to program my stand alone Atmega(s). Initially for first programming, I have the Atmega set up with a 16Mhz crystal and two 22uF caps.

The first thing I do is to select the correct board, processor and desired clock speed then I click upload using programmer. No probs.

In my case, I can then remove the 16Mhz crystal and the two caps because the chip is now running on the internal oscillator at 8Mhz. From there on in I just upload my code to the Atmega using Upload Using Programmer.

I don't get any errors or complaints and the Atmegas all seem to run okay after programming (i.e. seem happy at 3V3 with the internal oscillator).

Beyond that, I don't know if I'm missing something or doing something wrong...

I've tried all kinds of code for low power and with all the codes I've tried, including Nick Gammon's sketches, I've not seen or heard anyone reporting anything like this. They all just seem to get results. Not always identical but certainly in the expected ball park.

So I'm at a loss.....

Thanks for all the replies so far guys, - in the meantime, I'll keep on digging :slight_smile:

I'm kinda confused by the two speeds mentioned. If I understand correctly, you programmed at 16MHz, assuming you also uploaded the bootloader for that frequency and external crystal. But then you unplug the crystal and are now running at 8MHz? It seems as if the 16MHz crystal shouldn't have been any part of this process. I haven't read the datasheet, but didn't think it would do that switch without reprogramming the fuses. If still using the internal circuitry for external crystal while running on the internal oscillator (didn't think that was possible) it wouldn't achieve the low power, and maybe even overdriving the part with 3.3v if internal circuitry to drive at 16MHz is still active. I may have this all wrong, but that's just something that caught my attention. Someone with more understanding of this may have more to say about this, even enlightening me on what I'm thinking about it.

FWIW, I did the same test and got around 840uA. So now curious, will too try and figure it out.

It may need to run at only 1MHz and 1.8v to get any lower. Will experiment with that later. Nick Gammon that you mentioned didn't seem to mention those things when relating to power down mode - just current draw when running.

Clock frequency does not matter while in sleep, the clock is not running then. Also your running current seems too high. It should be around 3mA with 8MHz and 3.3V, not 5mA.

olf2012:
Clock frequency does not matter while in sleep, the clock is not running then.

The datasheet shows:
Power Consumption at 1MHz, 1.8V, 25°C
Power-down Mode: 0.1μA

So I was going for that.

justjohn:
The datasheet shows:
Power Consumption at 1MHz, 1.8V, 25°C
Power-down Mode: 0.1μA

So I was going for that.

I'll repeat what olf2012 said: The clock frequency does not matter, because it is OFF while the micro is asleep. That's what sleeping means in a microcontroller.

Also, you won't reach 100 nA like this. That spec is with literally everything possible turned off. You are using the watchdog timer to wakeup, which IIRC consumes 10 uA of current.

Right now you have too many variables. Remove the code that flashes the LED, remove the code that sets up the watchdog timer, and just put the controller to sleep. Focus on learning how to sleep properly first (and get your current consumption down), then learn how to wake up, then learn how to do things while awake.

Do you have decoupling capacitors on the board? If no, fix that now.

Jiggy-Ninja:
Do you have decoupling capacitors on the board? If no, fix that now.

Hmm well that’s interesting…

Using the breadboard setup as before (just the atmega powered by the Nano 3V3 and GND pins), I’ve added the decoupling caps of 0.1uF (100nF) across both of the Atmega’s VCC and GND pins and the current consumption goes up…

With Decoupling I get 2.88mA and without decoupling I get 1.41mA…

I was using this sketch:

//LOW POWER BASE LINE TEST SKETCH H FROM NICK GAMMON FORUMS - https://www.gammon.com.au/forum/?id=11497


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


  
// watchdog interrupt
ISR (WDT_vect) 
{
   wdt_disable();  // disable watchdog
}  // end of WDT_vect
 
void setup () { 
 
  
  }

void loop () 
{
  
  // disable ADC
  ADCSRA = 0;  

  // clear various "reset" flags
  MCUSR = 0;     
  // allow changes, disable reset
  WDTCSR = bit (WDCE) | bit (WDE);
  // set interrupt mode and an interval 
  WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0);    // set WDIE, and 8 seconds delay
  wdt_reset();  // pat the dog
  
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
  noInterrupts ();           // timed sequence follows
  sleep_enable();
 
  // turn off brown-out enable in software
  MCUCR = bit (BODS) | bit (BODSE);
  MCUCR = bit (BODS); 
  interrupts ();             // guarantees next instruction executed
  sleep_cpu ();  
  
  // cancel sleep as a precaution
  sleep_disable();
  
  } // end of loop

Now I am totally confused… lol

You may be having same problem I was having - thinking my meter could measure something that it couldn't, just because it had uA on it, and seemed to have the resolution I needed. I just never measured anything this small. Have a look at this.

I figured it to be a "meter problem" after watching this video, seeing actual results of various sleep modes on his meter, and then actually running his sample code linked to at that video, getting the same wrong results from my meter. Then, I figured it was a problem with my meter, and finally figured out my meter just wasn't capable of reading uA in that way.

I felt just a little bit like a "nit-wit," but it won't be the first time, and likely not the last. :-/

Hi all and thanks once again for all your contributions and help.

PROBLEM NOW SOLVED:-

It turns out my instincts were correct. It was all down to the Atmega328P-PU IC I was using. No matter what I did or tried with it, I couldn't get it to draw below 1.4mA.

Having wasted three days this week waiting in for useless UPS to deliver my Atmega's from Farnell, I decided to have a rummage around my scraps box and I found an old project with an Atmega328P-PU to use.

I uploaded my test code to it and low and behold it worked.

My project dropped down to a current consumption of 200uA which is well under my target of 500uA and that figure also includes the MP1584EN Buck module powering the Atmega at 3.3V :slight_smile:

So I'm well pleased.

----Side Note Mini Rant Warning------

I am not so pleased with UPS on the other hand whose tracking website stated my Farnell order would be delivered by the end of the day Monday which then became Tuesday which then became - tracking information unavailable.

And as a first time customer, I am also less than impressed with Farnell's customer service / email support responses. Having contacted them Wednesday to chase the issue up with their courier, I got ZERO response or acknowledgement. Sent a second Email on Thursday and still no reply.

Wont be bothering with them again if this is what I can expect.

Sorry for the little rant at the end but I got quite annoyed by it. As a customer, no matter how little I spend, I don't expect to be the one having to do all the chasing around for my goods and getting ignored once you've had my money.

Anyway, I've sorted my issue now and I've got a nice low powered Atmega so I'm happy.

Thanks again!