re-compiling code took sleep I from 2.5ua to 120ua...

Go To Last Post
21 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi - I built up a device a few years back that had a very low current sleep mode. I measured it at 2.5ua. It uses an ATMEGA168P. I recently made some changes to the code to track down a different problem with the device, and recompiled that code and installed it. I did not measure sleep current at the time. I have now reverted to old code, but compiled today, and my sleep current is now 120ua.

I believe I went from AVR studio 5 to 6 during that time.

Is there possibly some setting in AVR studio that could be blocking my AVR from going into sleep mode? I can't find anything in the hardware that should be causing this. The only change I made to the hardware is I installed a slightly higher capacitance 32K crystal. I expected a microamp or so change from that at most. Not 117.5ua!!!

I call sleep mode like this:
SMCR = (1<<SM1) | (1<<SM0) | (1<<SE);
sleep_cpu();

At the top of my file I have this:
#include

Any ideas? This is driving me nuts!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Put a diagnostic signal on a pin that is present when it is not sleeping.

You should be able to tell from that if it is sleeping or not.

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is a really good argument for using version control, so you could go back and check the differences in the output files.

Not to beat up on you, but you broke an important rule by changing multiple things at once: hardware and tool chain.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kk6gm wrote:
This is a really good argument for using version control, so you could go back and check the differences in the output files.

Not to beat up on you, but you broke an important rule by changing multiple things at once: hardware and tool chain.


I do use version control. I reverted to old code. That's why I'm pretty sure it's AVR Studio doing it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ka7ehk wrote:
Put a diagnostic signal on a pin that is present when it is not sleeping.

You should be able to tell from that if it is sleeping or not.

Jim


I'll try to add that in. I'm debating how to, however. I think I'll have my main wait loop just constantly toggle an IO. But there are times when it is in an interrupt handler, so it'd look like it was asleep when in reality it is interrupting... I'll try to figure something out.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This may not be important, but I get this error message when I open the project:

"23:17:51: [WARNING] The device [atmega168p] is not supported in ASF Version [3.1.3] that is used in the project Nixie Clock"

Googling around suggests that it isn't anything to worry about - but I thought I'd mention it anyways.

Further - I just noticed that it was set to build as a "debug" version. I have just changed the configuration to "release". I am not at the lab so I can't test the release code till the morning. The hex file shrank considerably (46.3% usage to 29.0% usage), so that's a good sign.

On a related note - what's the difference between "Build solution" and "Build Nixie Clock"? (Nixie Clock is the project name) They seem to do the same thing, unless I'm missing something. And what about "Compile"?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

The hex file shrank considerably (46.3% usage to 29.0% usage), so that's a good sign.

What were the -O setting in "Debug" and "Release". It sounds like the Debug mught have been set to the dreaded -O0.
Quote:

On a related note - what's the difference between "Build solution" and "Build Nixie Clock"? (Nixie Clock is the project name) They seem to do the same thing, unless I'm missing something. And what about "Compile"?

If you only have one project in the solution then yes they do the same thing. When you have more than one project then "Build Solution" means "Build all the projects" while "Build " just builds the one.

This is really an inheritance from VS2010 where AS6 started. In that it's not unusual to have many many projects in a solution. For example I just built something in Visual Studio that said:

========== Build: 1 succeeded, 0 failed, 52 up-to-date, 2 skipped ==========

So that's a solution with 55 projects (mainly libraries/DLLs) in it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

On a related note - what's the difference between "Build solution" and "Build Nixie Clock"? (Nixie Clock is the project name) They seem to do the same thing, unless I'm missing something. And what about "Compile"?

Build solution builds a complete solution /potentially containing several projects).
Build
builds one project.
Compile compiles an individual source file, methinks.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Perhaps unrelated, but I've found sleep mode current varies a lot based on what you do with unused pins. I now set them to output and low.

The largest known prime number: 282589933-1

In my humble opinion, I'm always right. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Torby wrote:
Perhaps unrelated, but I've found sleep mode current varies a lot based on what you do with unused pins. I now set them to output and low.

I have all of mine set to inputs with pull ups.

I know different chips have different IO states that achieve the lowest current. Any idea what it is for an AVR?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Quote:

The hex file shrank considerably (46.3% usage to 29.0% usage), so that's a good sign.

What were the -O setting in "Debug" and "Release". It sounds like the Debug mught have been set to the dreaded -O0.
Quote:

On a related note - what's the difference between "Build solution" and "Build Nixie Clock"? (Nixie Clock is the project name) They seem to do the same thing, unless I'm missing something. And what about "Compile"?

If you only have one project in the solution then yes they do the same thing. When you have more than one project then "Build Solution" means "Build all the projects" while "Build " just builds the one.

This is really an inheritance from VS2010 where AS6 started. In that it's not unusual to have many many projects in a solution. For example I just built something in Visual Studio that said:

========== Build: 1 succeeded, 0 failed, 52 up-to-date, 2 skipped ==========

So that's a solution with 55 projects (mainly libraries/DLLs) in it.


Yes - optimization in debug was set to "None (-O0)". Debug was set to "Default (-g2)". My release settings are "Optimize for size (-Os)" and "None". Would those debug settings mess somehow with sleep current? This device should be sleeping about 99% of the time - so even if it was operating a little slow I would think that that would change anything.

Thanks for the explanation about the making. Glad I wasn't doing anything wrong there!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Would those debug settings mess somehow with sleep current? This device should be sleeping about 99% of the time - so even if it was operating a little slow I would think that that would change anything.

In later versions of AS6 (I think because I moaned!) Atmel changed the default for "Debug" from -O0 to -O1. I would ensure that's always the case for any existing projects you have. -O0 is really just a test mode for the compiler developers and should not be used in reality.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK here is an interesting update.

The debug version of the code pulls 120ua or so.

The release version of the code pulls 600ua or so.

Anybody got any theories here? I have not had time to look at how much time it is spending in sleep mode - won't be able to do that till probably Monday evening (I'm leaving town shortly for Thanksgiving!)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nleahcim wrote:
kk6gm wrote:
This is a really good argument for using version control, so you could go back and check the differences in the output files.

Not to beat up on you, but you broke an important rule by changing multiple things at once: hardware and tool chain.


I do use version control. I reverted to old code. That's why I'm pretty sure it's AVR Studio doing it.

Then have you loaded the old hex file (not a new hex file built with the old code) into your current hardware and measured the current?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kk6gm wrote:
nleahcim wrote:
kk6gm wrote:
This is a really good argument for using version control, so you could go back and check the differences in the output files.

Not to beat up on you, but you broke an important rule by changing multiple things at once: hardware and tool chain.


I do use version control. I reverted to old code. That's why I'm pretty sure it's AVR Studio doing it.

Then have you loaded the old hex file (not a new hex file built with the old code) into your current hardware and measured the current?

Sadly, I did not have the hex file version controlled. Just the .C file. Because I trusted the compiler not to go nuts on me. Never have had a problem like this before...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think the more you know about this, the more confusing it gets.

The largest known prime number: 282589933-1

In my humble opinion, I'm always right. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have the sleep command in a while(1) loop - is there any chance that that is getting optimized away? It looks like this:

int main (void)
{
    init(); //configure peripherals
	while(1)
    {
		if (CurrentMode & Mode_Battery)
		{
			//switch to power save mode
			SMCR = (1<<SM1) | (1<<SM0) | (1<<SE);
			sleep_cpu();
			
		}
    }
	return(0);
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nleahcim wrote:
I have the sleep command in a while(1) loop - is there any chance that that is getting optimized away?

You can check the .lss file and see what's there.

Also, if you have a spare pin, connect a LED with series resistor from the pin to ground. When the program starts, switch the LED on. Just before entering sleep mode switch the LED off and right after waking up switch the LED back on. This will give you a visual indicator.

One thing to look at are the fuses. Both the watchdog and brownout circuits consume power.

Here's a link to a tutorial at Sparkfun showing what was required to get an ATmega328 down to 1 uA.
While it was a different uC, the steps he followed may give you some ideas.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have changed my main to look like this:

int main (void)
{
    init(); //configure peripherals
	while(1)
    {
		PORTC ^= 1<<PORTC0;
		if (CurrentMode & Mode_Battery)
		{
			//switch to power save mode
			SMCR = (1<<SM1) | (1<<SM0) | (1<<SE);
			sleep_cpu();
			
		}			
    }
	return(0);
}

When not in battery mode, I can see PC0 toggling constantly. When in battery mode, it toggles once every time the interrupt fires. So 16 times per second. So it looks like the part is sleeping properly. Further, I have PC1 being set when the interrupt handler starts, and cleared when the interrupt handler ends, and the interrupt handler takes about 60us.

Finally, I've attached a plot of my current for one second (I know it says 10 - but really, it is one second). You can see it spiking at 16Hz (which is my interrupt).

So now I have to figure out why my sleep current is so darn high. Argh.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is another strange data point:

I tried turning off everything in the PRR - so I wrote 0xFF to PRR, and then I slept. That should disable the 32K interrupt that is waking me up periodically. The goal was to put the MCU permanently to sleep. Sleep current went from 115ua to 2ma.

Why would disabling an extra peripheral increase my sleep current?

Also, I have gone through every IO and as far as I can tell they're all driven to the correct state (pull ups on unused IOs, all outputs are driven low as they are connected to a device that is not powered).

I also switched to my original crystal and that changed nothing.

Anybody have any ideas here?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As a guess I'd say you're not sleeping. How have you confirmed that you are?

However, there are some peripherals that you must first disable before you shut them down with PRR, or the resources they were using will remain active. If the ADC is enabled and configured to use Vbg as a reference or a MUX, the bandgap will remain active even after setting PRADC.

None of this should amount to 2 ma, so I still think you're not actually going to sleep, or at least not the mode you think you are.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]