[SOLVED]...current consumption after EEPROM write on TINY84A

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

Hello!

I've got a small battery powered circuit running from a 32Khz crystal which may log events about every hour by writing to EEPROM.

Since the batteries are very small I've tried to keep current consumption very low. The circuit runs full tilt on just 13µA @ ~ 4.5 volts with CLKPR=2 (8Khz clock). This is fine.

However, after having written a single byte to EEPROM the current jumps to 80µA and stays there. I've even tried reproducing the datasheet's EEPROM writing function to eliminate avr-lib as a suspect but the behaviour remains the same.

Nothing I tried so far reduces the current back to its initial value; once EEPROM is written, only a strobe on RESET fixes it, but I'd rather avoid that.

Both searches here and my google-fu failed me.

I've reduced the test case to a small program that illustrates the problem. The following code basically turns off µC features, sets up a 1 interrupt per second ISR and then the main loop waits until ten seconds have passed and then writes a byte. 13µA on power up, 10 seconds later constant 80µA.

#include 
#include 
#include 
#include 

volatile uint8_t sentinel=0;

ISR(TIM1_COMPA_vect) {
  sentinel++;
}

void eewritebyte(uint16_t address, uint8_t byte) {
  while(EECR&(1<<EEPE));
  EECR=0;
  EEAR=address;
  EEDR=byte;
  EECR|=(1<<EEMPE);
  EECR|=(1<<EEPE);
}

void inithardware(void) {
  CLKPR=(1<<CLKPCE); CLKPR=2;   // 8Khz.
  DDRA=0; PORTA=0xff;           // All pull-ups to prevent floating inputs.
  DDRB=0; PORTB=0xff;           // All pull-ups to prevent floating inputs.
  PRR|=(1<<PRTIM0);             // Turn timer0 off.
  PRR|=(1<<PRADC);              // Turn ADC off.
  PRR|=PRUSI;                   // Turn USI off.
  ACSR|=(1<<ACD);               // Turn off Analog comparator.
  TCCR1B|=(1<<WGM12)|(1<<CS10); // CLKio, CTC
  TIMSK1|=(1<<OCIE1A);          // Enable COMPA interrupt.
  OCR1A=8191;                   // ISR @ 1Hz.
  sei();
}

int main(void) {
  uint8_t barbar=0;
  uint8_t oldsentinel=0;
  inithardware();
  while(1) {
    if(oldsentinel!=sentinel) {
      if(sentinel==10) {
        sentinel=0;
        cli();
        // eeprom_write_byte((uint8_t *)10,barbar++); // lib-avr.
        eewritebyte(10,barbar++);                     // datasheet.
        sei();
      }
      oldsentinel=sentinel;
    }
  }
}

The date code on the ATTINY84A-PU is 1127 (Not sure if that's a factor.)

Anyone have ideas?

Attachment(s): 

odokemono. I try to entice electrons to do my bidding.

Last Edited: Sat. Jun 14, 2014 - 10:36 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Interesting.

Generally, the advice I give, from my experience, is to run "fast", get your work done, and then sleep for as long as practical. You've chosen the "plod along just fast enough to keep running" approach.

Anyway, I winder if your symptoms might have something to do with the main clock running much slower than the EEPROM clock. Digging out that datasheet to see about EEPROM clock for that model...

No definitive answer to me:

Quote:
The calibrated Oscillator is used to time the EEPROM accesses. Make sure the Oscillator frequency is within the requirements described in “OSCCAL – Oscillator Calibration Register” on page 31.

So, what happens if you "run fast" CLKPR=0 during the EEPROM write? Do you get the same results if e.g. using the internal 128kHz as the main clock source?

That AVR model is limited with respect to timers and ASSR and such. My first question is whether you need accurate one hour, or is "or so" good enough.

"Traditional" approach for me: Use a normal clock source in the say 4MHz-8MHz range. Either crystal (slow wakeup from deep sleep) or internal (faster wakeup but not as accurate for e.g USART comms). Use the watchdog timer set at e.g. 8 seconds and use WDT interrupt to awaken from power-down sleep. Do your business as fast as practical, then go back to deep sleep. Overall consumption in the AVR becomes maybe 5uA depending on the model and how long one stays awake.

"Modern" approach used by many nowadays: Use ASSR and watch crystal to clock timer2 to wake from deepest possible sleep that still keeps timer2 going. Now you have an accurate time base. With some/many AVR8 models, this gives a consumption about the same (in some models better) than the WDT approach.

An interesting situation. Let us know the cause when you figure it out.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Thanks for the excellent suggestions.

By the way, I've tried forcing a reset by way of the watchdog; it has the same effect as strobing RESET: the current draw goes back down for 10 seconds.

Going "fast" for just the EEPROM write doesn't change the behaviour.

32768hz crystal + CLKPR=0 gives me the same behaviour but 32µA and then 97µA. Interesting that it's about the same current increase no matter CLKPR: 65µA. Maybe something normally not clocked gets turned on but not off.

Since EEPROM writing is documented as requiring the internal oscillator as you pointed out this got me thinking that maybe what was happening was that EEPROM writing could turn the OSC on even while using the external crystal. So I tried:

8MHz calibrated internal oscillator + CLKPR=8 (31250Hz) gives me 166µA and then 230µA ten seconds later. One instantly sees why using the watch crystal is a plus.

Curiouser and curiouser.

Quote:
My first question is whether you need accurate one hour, or is "or so" good enough.

Somewhat. The gizmo logs events like over-voltage and under-pressure which are pretty rare events but knowing when they happened is important.
Sadly, I can't have the µC in deep sleep for any amount of time, it could miss short and transient events. It also it keeps time.

If I don't find a solution before I have to go back to the client's site I might change the code so that instead of writing just the event log I might write the whole set of state variables to EEPROM and then force a WDT reset and have the init() read the state at start-up. Ugly, but it would work. It'd also require adding an RTC. Darn it.

I'll still do more head-scratching and testing first; it's an interesting problem.

odokemono. I try to entice electrons to do my bidding.

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

Quote:

Sadly, I can't have the µC in deep sleep for any amount of time, it could miss short and transient events.

Yes, you can have it in deepest sleep. Pin-change wakes up the CPU.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

theusch wrote:
Quote:

Sadly, I can't have the µC in deep sleep for any amount of time, it could miss short and transient events.

Yes, you can have it in deepest sleep. Pin-change wakes up the CPU.

Nope. Routinely polling multiple hardware sensors which don't provide interrupt-friendly signals.

odokemono. I try to entice electrons to do my bidding.

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

Looking at the datasheet, the eeprom access uses the calibrated osc (high speed osc) for it's timing. Since your using the low speed osc for system clock, at reset time only it is powered up, then when doing the eeprom access, the hsp osc starts, using more current. Looks like only a reset of some type will halt that clock.
You may be stuck setting up the wdt to reset after an eeprom write operation in order to drop power consumption again.
Interesting problem, let us know what you come up with.

JC

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

Quote:
Since your using the low speed osc for system clock, at reset time only it is powered up, then when doing the eeprom access, the hsp osc starts, using more current.

As said in my second message in this thread, I tried:

Quote:
8MHz calibrated internal oscillator + CLKPR=8 (31250Hz) gives me 166µA and then 230µA ten seconds later.

I've made a modified version of the code that does a WDT-forced-reset to cover for the eventuality that there's no solution. It's ugly and means that there's a short window when the device won't be doing sampling after an event log.

Still, it's puzzling.

Quote:
Interesting problem, let us know what you come up with.

I'm going to do more fiddling this weekend and report any findings here.

odokemono. I try to entice electrons to do my bidding.

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

Just some stupid questions to try to get closer to the problem.

when you use 13uA is the WDT enablet or not!
if you enable the WDT does the power then go from 13 to 80 ?
If you just do an eeprom read does the power still go up?
(perhaps a read after write will help).
I don't know the 84 but if the WDT can be used as timer an WDT ISR perhaps do the job.
Perhaps flipping with the power (low noise) bit's so things isn't powered under ADC can do the job.
if it's some timing problems because of the slow clk, then perhaps speed your clk up under EEPROM write (and don't slow down again before the write is done).

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

Quote:
Just some stupid questions to try to get closer to the problem.

Those aren't stupid questions, they're perfectly valid.

Quote:
if you enable the WDT does the power then go from 13 to 80 ?

Well, it goes from 19 to 86 and stays there. The extra 6µA is surely for the watchdog circuitry, as expected.

Quote:
if it's some timing problems because of the slow clk, then perhaps speed your clk up under EEPROM write (and don't slow down again before the write is done).

Funny you should say, actually I've been trying a few things again this morning and discovered that the combination of having the WDT enabled AND CLKPR=0 just for the time the the EEPROM is busy fixes (or bypasses) the problem.

My theory: Inside the µC there's probably a very small capacitive voltage booster for EEPROM programming which uses whichever clock is available and it gets confused when the clock is slow because of the pre-scaler and the current draw on the whole chip is very low. If the WDT is enabled it probably relaxes its safety procedures or the clocking is handled differently.

It also probably has to do with power fluctuations caused by current draw as well. During my tests I even tried running the µC without a bypass cap. You won't believe the results so I made a video: http://youtu.be/FbZUA1BQDas

In that one it's running on the internal calibrated OSC, CLKPR=8. Two runs, first with bypass cap exhibits problem, second without cap doesn't exhibit problem. WTF!?!?!

I was ripping my hair out on that one.

So thanks everyone for the suggestions, they were all excellent.

Now how do I mark this topic as [SOLVED]...

odokemono. I try to entice electrons to do my bidding.

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

Not so much 'solved' as 'skirted'. Very curious as to why removing a requied component results in proper device behavour.

Have you done the bypass cap test with your original config (i.e. 32.768 kHz / 4, no WDT)?

"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]

 

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

Quote:
I even tried running the µC without a bypass cap.

Have you checked the bypass cap. for leakage? Maybe a better quality capacitor for this situation would solve that particular problem. Things may also improve without the capacitance of breadboard circuit.

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

Quote:
Not so much 'solved' as 'skirted'. Very curious as to why removing a requied component results in proper device behavour.

Agreed on both counts.

Quote:
Have you done the bypass cap test with your original config (i.e. 32.768 kHz / 4, no WDT)?

Yup. Same weird behaviour.

Quote:
Have you checked the bypass cap. for leakage? Maybe a better quality capacitor for this situation would solve that particular problem. Things may also improve without the capacitance of breadboard circuit.

I've tried every kind of 0.1µF I have in stock. Always the same weird behaviour. Does the same thing with 10µF and 0.1µF caps in parallel too.

I've also done tests with the microcurrent-monitoring DMM shorted to eliminate the possibility that its internal resistance could be the cause. Nope.

I'm baffled but I can live with the quirk.

odokemono. I try to entice electrons to do my bidding.

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

odokemono wrote:
I've also done tests with the microcurrent-monitoring DMM shorted to eliminate the possibility that its internal resistance could be the cause.
My next suggestion ;)
Quote:
Nope.
Hmm. So you short the DMM for a low-impedance path to power, power-up the device, wait the required ten seconds, remove the short, and the DMM still shows the elevated current?

"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]

 

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

Quote:
Hmm. So you short the DMM for a low-impedance path to power, power-up the device, wait the required ten seconds, remove the short, and the DMM still shows the elevated current

Yup. Obviously there's still a bit of resistance in the breadboard's contacts and the jumper wires use to connect it all but they should be negligible in the µA range.

odokemono. I try to entice electrons to do my bidding.

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

what happens if you remove all other stuff from the board? can it be that the rectangular thing connected is causing problems?
So really only leave the MCU placed on the board.

also what happens if you add a 10K pull-up resistor to the reset line. There should be an internal pull-up, but just to rule out problems there....

also what happens if you just do a single eeprom write after 10 seconds. what happens to the current after lats say 5 minutes or so(you are running very slow so it might be that the current drop back is also very slow....

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

Quote:
what happens if you remove all other stuff from the board?

Tried many times with nothing but the µC on the board. Tried it a couple of times with just the µC's Vcc and GND clipped in mid-air without a board of any kind.

Quote:
also what happens if you add a 10K pull-up resistor to the reset line. There should be an internal pull-up, but just to rule out problems there....

I tried it with RESET tied to Vcc.

Quote:
also what happens if you just do a single eeprom write after 10 seconds. what happens to the current after lats say 5 minutes or so(you are running very slow so it might be that the current drop back is also very slow....

I originally discovered the abnormal behaviour +45 minutes after an EEPROM-written event log. At the time I didn't know that the two were related. I "stimulated" an event, checked the output, went for a snack at the pub, came back and noticed the extra current. The 10-second wait between writes came much later, while trying to diagnose. The extra current doesn't lessen over time.

No worries though. I've moved on.

odokemono. I try to entice electrons to do my bidding.