Power consumption of ATMEGA32U4 during sleep Power Down higher than expected

Ladies and Gentlemen

I have an issue that has been bothering me for over a few years now.

5 years a go I started working on a project of mine. All is working relatively well, and currently I am going through the 10th iteration. I switched MCUs multiple times. I started out with a ATMEGA328P, went to ATTINY85, went back to ATMEGA328P and eventually ended up with the ATMEGA32U4 (build in USB is so handy :slight_smile: ).

Anyways, I want to leave my device on during extended periods of time, so frequent use of the sleep power down function is quite important to me. I have always been able to get down to the 5 uA or lower figures with the ATTINY85 and ATMEGA328P during sleep.

When I switched to the ATMEGA32U4 I noticed my standby time dropped, and found some board issues. (stupidly placed pull ups or pull downs, beginner mistakes etc ..). After having these fixed it was better but not quite what I was used to with the ATTINY85 and ATMEGA328P.

Note, I am running my ATMEGA32U4 at 3,3V 8 MHz external clock. The ATTINY85 and ATMEGA328P where at 8 MHz internal clock.

I did some power consumption measurements this week. I tried different things: uCurrent + scope, uCurrent + multimeter, amp measurement on multimeter. All more or less shown a 105'ish uA power consumption during sleep power down.

I tried many things getting this down at least an order of magnitude to the 10 uA range.

Over the last week I have tried multiple scripts and libraries, eventually writing my own libraries based on the avr/xxx.h files, cross checking everything with the 32U4 manual. Result, 105 uA ....

So I am willing to give some extra power consumption to my board design, I am not a grandmaster and there might be some flaws. But nothing in this range.

So I wanted to try with my Pro Micro 3,3V 8 MHz and see what I could get there without any external components. After seeing that I completely bricked it a while back I had to resort to a small ATMEGA32U4 board with 16MHz 5V running the Arduino Leonardo bootloader. This board is almost bare bones, so not much on there that can suck up current.

I used Rocketscream's LowPower.h library.

Used the following code (see below), and measured the current. Still 85 uA .....
I have no clue anymore what is happening. I should be able to go lower.

I also tried my own libraries, old ones, new ones, all with the same results ..

Sparkfun on lower power consumption. I can't get their results, while I am running almost the exact same code..

I ordered a new Pro Micro to replace the brick I now have.

Does anybody have some experience with this? I don't have any ideas where too look anymore.
Any advise or insight will be greatly appreciated!

// **** INCLUDES *****
#include "LowPower.h"

void setup()
{
    digitalWrite(LED_BUILTIN, HIGH);
    delay(16000);
    digitalWrite(LED_BUILTIN, LOW);
}

void loop() 
{
    // Enter power down state for 8 s with ADC and BOD module disabled
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);  
    // Do something here
    // Example: Read sensor, data logging, data transmission.
    for (int i = 0; i <= 16; i++) {
      digitalWrite(LED_BUILTIN, HIGH);
      delay(250);
      digitalWrite(LED_BUILTIN, LOW);
      delay(250);
    }
}

This problem crops up a lot on newish "ATmega328" boards, and has been traced to counterfeit chips.

Where did you buy your ATmega32u4 chips?

Yeah, I was one of the lucky ones getting counterfeit 328P chips on Pro Minis. 140uA sleep current even with all the oscillators turned off.

I don't have any experience with the 32U4. Are you running these tests with some power supply other than USB? Do you need to shut down the USB module to get the lowest current? (I notice at the bottom of the keywords.txt file of the library there are SPI_OFF, TWI_OFF and USB_OFF options.)

What current do you see running that code on a barebones 328P?

Thank you for the input people!

jremington:
This problem crops up a lot on newish "ATmega328" boards, and has been traced to counterfeit chips.

Where did you buy your ATmega32u4 chips?

Interesting link!

My small Leanardo like board was purchased in 2017 from dx.com.
And I have bought loose ATMEGA32U4 chips on two different occasions from Aliexpress.

So yes counterfeit could be possible. I did not know this was going on..

I attached pictures of all three types op 32U4 I have.

I also tried an older prototype of my device that had an ATMEGA32U4 of the first purchase on there. Same result, 105 uA current draw during sleep mode.

I ordered an Arduino Micro to perform some tests on a.s.a.p.
Also I will ask some samples from Microchip, to double check.

Still, with my luck it could be possible to get counterfeit chips on three different occasions.
But this would mean this is going on on a big scale, and shouldn't we know about this then by now?
I am not 100% convinced, but it seems likely to be so.

ShermanP:
Yeah, I was one of the lucky ones getting counterfeit 328P chips on Pro Minis. 140uA sleep current even with all the oscillators turned off.

I don't have any experience with the 32U4. Are you running these tests with some power supply other than USB? Do you need to shut down the USB module to get the lowest current? (I notice at the bottom of the keywords.txt file of the library there are SPI_OFF, TWI_OFF and USB_OFF options.)

What current do you see running that code on a barebones 328P?

I performed by tests running either from a 250 mAh lipo, or my bench power supply (Korad KA3005P).
None of the tests were performed while powering from an USB port.
Also I just now uploaded the exact same code to one of my original Arduino Unos, I pulled the ATMEGA328P off, and made the most basic barebones possible. 6 uA .. So it does not seem to be my code.

.
.
.
.
.

I think there are 4 options now:

  1. Some register is wrongly defined in the AVR libraries somewhere. But I don't think so since I cross referenced most of the libraries with the ATMEGA32U4 datasheet.
  2. The low_power.h library has some fault in there, and I also made the same mistake in my code.
    But then why am I the first to discover this?
  3. I received counterfeit chips on all occasions. Will test as soon as my Arduino Micro gets here.
  4. Atmel has some design flaw in their ATMEGA32U4? Which I really do not think so.
    So counterfeit chips is what seems most reasonable if I look at this list.

Leonardo.png

New_Batch.png

Old_Batch.png

Leonardo.png

New_Batch.png

Old_Batch.png

My guess is it's something not being done right with the registers on the 32U4. Try running your code without the ADC_OFF switch, and see if the current is higher. If it's the same current either way, then maybe ADC isn't being turned off. Then do the same test for BOD_OFF.

Here's the code I use to test the 328P. It does a sleep forever which turns off all the oscillators, and produces sleep current under 1uA.

#include <avr/sleep.h>
#include <avr/wdt.h>
int i;

void setup(){

  for (i = 0; i < 20; i++) {          // all pins to one rail or the other
    pinMode(i,OUTPUT);
    digitalWrite(i,LOW);
  }
  ADCSRA = 0;                         // disable ADC for power saving
  wdt_disable();                      // disable WDT for power saving
  set_sleep_mode (SLEEP_MODE_PWR_DOWN); // Deep sleep
  sleep_enable();
  sleep_bod_disable();                // disable brownout detector during sleep
  sleep_cpu();                        // now go to sleep

}

void loop(){
}

In the 328P, the BOD disable has to be given immediately before the sleep_cpu command. But I don't know if any of this will work on the 32U4. For what it's worth, on the 328P I found that ADC turnoff was worth 110uA, and BOD turnoff was worth 20uA.

The USB cable may be disconnected but that does not mean the USB interface inside the chip is disabled. Try the USB_OFF and TWI_OFF options mentioned before.

ShermanP:
My guess is it's something not being done right with the registers on the 32U4. Try running your code without the ADC_OFF switch, and see if the current is higher. If it's the same current either way, then maybe ADC isn't being turned off. Then do the same test for BOD_OFF.

Here's the code I use to test the 328P. It does a sleep forever which turns off all the oscillators, and produces sleep current under 1uA.

#include <avr/sleep.h>

#include <avr/wdt.h>
int i;

void setup(){

for (i = 0; i < 20; i++) {          // all pins to one rail or the other
   pinMode(i,OUTPUT);
   digitalWrite(i,LOW);
 }
 ADCSRA = 0;                         // disable ADC for power saving
 wdt_disable();                      // disable WDT for power saving
 set_sleep_mode (SLEEP_MODE_PWR_DOWN); // Deep sleep
 sleep_enable();
 sleep_bod_disable();                // disable brownout detector during sleep
 sleep_cpu();                        // now go to sleep

}

void loop(){
}




In the 328P, the BOD disable has to be given immediately before the sleep_cpu command. But I don't know if any of this will work on the 32U4. For what it's worth, on the 328P I found that ADC turnoff was worth 110uA, and BOD turnoff was worth 20uA.

Thanks for your continued input.

Did some more tests with the ATMEGA32U4 - 16 MHz 5V Leonardo Board:

  • Original code posted here above, ADC OFF - 86,9 uA in sleep
  • Original code posted here above, ADC ON - 191,8 uA in sleep
  • ShermanP code (removed BOD line) - 80,8 uA in sleep

So your code did improve the performance a bit.
But it also clearly confirms that the ADC was turned off, and the issue lies somewhere else.

sleep_bod_disable() is only available for the picoPower ATMEL / MicroChip devices.
Only those can disable their BOD while in operation.

Smajdalf:
The USB cable may be disconnected but that does not mean the USB interface inside the chip is disabled. Try the USB_OFF and TWI_OFF options mentioned before.

Smajdalf, yes I realize this. But turning USB off in code is either not working, or just not making a big difference.
I am using this code, and still am ending up at 86,9 uA...

	if (adc == ADC_OFF)
	{
		ADCSRA &= ~(1 << ADEN);
		power_adc_disable();
	}

	if (timer4 == TIMER4_OFF)	power_timer4_disable();
	if (timer3 == TIMER3_OFF)	power_timer3_disable();
	if (timer1 == TIMER1_OFF)	power_timer1_disable();
	if (timer0 == TIMER0_OFF)	power_timer0_disable();
	if (spi == SPI_OFF)			power_spi_disable();
	if (usart1 == USART1_OFF)	power_usart1_disable();
	if (twi == TWI_OFF)			power_twi_disable();
	if (usb == USB_OFF)			power_usb_disable();

	if (period != SLEEP_FOREVER)
	{
		wdt_enable(period);
		WDTCSR |= (1 << WDIE);
	}

	lowPowerBodOn(SLEEP_MODE_PWR_DOWN);   //Altered 

	if (adc == ADC_OFF)
	{
		power_adc_enable();
		ADCSRA |= (1 << ADEN);
	}

	if (timer4 == TIMER4_OFF)	power_timer4_enable();
	if (timer3 == TIMER3_OFF)	power_timer3_enable();
	if (timer1 == TIMER1_OFF)	power_timer1_enable();
	if (timer0 == TIMER0_OFF)	power_timer0_enable();
	if (spi == SPI_OFF)			power_spi_enable();
	if (usart1 == USART1_OFF)	power_usart1_enable();
	if (twi == TWI_OFF)			power_twi_enable();
	if (usb == USB_OFF)			power_usb_enable();
}
#endif

My Adafruit ItsyBitsy 32u4 - 5V 16MHz should arrive this week. Then I can double check with a chip that should be an original Atmel/MicroChip. But I am starting to think the issue will still be present.

I am starting to think the issue will still be present.

The ATmega32u4 data sheet claims that in power down sleep mode, the supply current is less than 1 uA at 25C with the WDT disabled (less than 7 uA enabled).

There is no reason to disbelieve these values, so either you have counterfeit chips, you are not turning off all of the possible MCU subsections, or external components are draining power.

With regard to counterfeit chips, Kevin Darrah has done a couple of videos on this and this on outlines how to check possible fakes.

jremington:
The ATmega32u4 data sheet claims that in power down sleep mode, the supply current is less than 1 uA at 25C with the WDT disabled (less than 7 uA enabled).

There is no reason to disbelieve these values, so either you have counterfeit chips, you are not turning off all of the possible MCU subsections, or external components are draining power.

You misunderstood me, I am not doubting the specs Atmel/MicroChip claim. I meant that I think it will be a code issue rather than a hardware issue. But fake chips can very well also be the culprit. I am waiting for my original Adafruit ItsyBitsy 32u4 - 5V 16MHz now so I can do some troubleshooting.

Riva:
With regard to counterfeit chips, Kevin Darrah has done a couple of videos on this and this on outlines how to check possible fakes.

Thanks for that! Once I have my Adafruit ItsyBitsy 32u4 - 5V 16MHz, and it meets the required specs, I will try this!

The ItsyBitsy and Pro Micro modules also have a voltage regulator and LED, both of which will draw current. How are you going to deal with that?

ShermanP:
The ItsyBitsy and Pro Micro modules also have a voltage regulator and LED, both of which will draw current. How are you going to deal with that?

Good question.
The Leonardo like module I have does not have a voltage regulator.
And the LED I can turn off in the code.
With the ItsyBitsy I am going to feed 5V into its 5V pin. So that the voltage regulator gets bypassed.
I am not going to use the VCC/RAW pins. And the LEDs can be turned off :slight_smile:

I think you will find that current will flow from the 5V pin back through the regulator to ground. When I measure the current on a Pro Mini, I remove the regulator and the power-on LED, so that nothing can draw current except the processor.

ShermanP:
I think you will find that current will flow from the 5V pin back through the regulator to ground. When I measure the current on a Pro Mini, I remove the regulator and the power-on LED, so that nothing can draw current except the processor.

Good point! I will first try with the regulator on there. See what results I get then. And if necessary I can remove the regulator for additional tests.

If there is a regulator on the board you have been testing all along, that is almost certainly the problem.

jremington:
If there is a regulator on the board you have been testing all along, that is almost certainly the problem.

I agree with you, but the 16 MHz 5V Leonardo like board is pretty much bare bones, and relies on an USB port to provide stable 5V. So this board is pretty much the most barebones you can go. There are 3 leds on there, but those care not being used during sleep.
So I suspect either fake chips, or something in the code not shutting down. I am still waiting for the ItsyBitsy to arrive, and I also requested some ATMEGA32U4 samples directly from MicroChip. With this I hope I can solve this issue :slight_smile: Will keep you gentlemen updated once I make some progress, unless you have other leads I can pursue?

"Pretty much" is a meaningless phrase.

Make a genuine, absolutely minimal bare bones ATmega32u4 and tell us what sleep current you measure. That would be one with NO voltage regulator.

jremington:
"Pretty much" is a meaningless phrase.

Make a genuine, absolutely minimal bare bones ATmega32u4 and tell us what sleep current you measure. That would be one with NO voltage regulator.

Guess you are right in your statement, and I should have been more clear. This board does NOT have a voltage regulator. Just a few caps for stability. Except for the 3 LEDs and their resistors, it is barebones.

Made an interesting discovery today.

PRR1 |= (1 << PRUSB); or power_usb_disable(); from the avr/power.h do absolutely nothing for power consumption.
Same for most of the other functions in that library.

BUT:
USBCON |= (1 << FRZCLK); // Freeze the USB Clock
PLLCSR &= ~(1 << PLLE); // Disable the USB Clock (PPL)
USBCON &= ~(1 << USBE ); // Disable the USB

Yields a 27.5 uA decrease in power consumption. That is a third of what it was consuming!
Running at 58.8 uA in sleep mode now. (BOD is still on in my fuse settings, and I think I will leave BOD on in my design). This means there is still +/- 50 uA hiding somewhere.

So I will have to check what other things like this might be hidden.

Following functions from avr/power.h do nothing in power consumption reduction for a ATMEGA32U4 (DURING "POWER DOWN SLEEP"!):

  PRR0 |= (1 << PRADC); //power_adc_disable();

  PRR0 |= (1 << PRSPI); //power_spi_disable();
  PRR0 |= (1 << PRUSART1); ////power_usart1_disable();
  PRR0 |= (1 << PRTWI); //power_twi_disable();
  PRR1 |= (1 << PRUSB); //power_usb_disable();

  PRR1 |= (1 << PRTIM4); //power_timer4_disable();
  PRR1 |= (1 << PRTIM3); //power_timer3_disable();
  PRR0 |= (1 << PRTIM1); //power_timer1_disable();
  PRR0 |= (1 << PRTIM0); //power_timer0_disable();

Will do some more tests tomorrow.

BOD consumes around 25 uA on the ATmega328.

Following functions from avr/power.h do nothing in power consumption reduction for a ATMEGA32U4:

Sorry, I do not believe you. You must have made several mistakes.

jremington:
Sorry, I do not believe you. You must have made several mistakes.

The PRR stops main clock to the selected peripheral freezing it. In Power Down Sleep main clock is stopped freezing nearly everything. From this it is clear PRR does not affect power consumption in Power Down Sleep. It is for Active or Idle modes.