9

I'm trying to get an ATTiny85 to run off a battery. I have it clocked from a 16.384 MHz crystal, with the divide-by-8 fuse set. Vcc is 3.3 volts. Figure 22-7 in the datasheet says that at idle ( set_sleep_mode(SLEEP_MODE_IDLE); sleep_mode(); ), it should draw around 300 µA. In actual fact, I see it drawing more like 850 µA. I can't figure out why the power consumption is double expected. I've turned off everything in PRR except for timer0, which I've configured to interrupt every 25 ms. So it should spend the vast majority of its time in the idle state, which is the best I can do given that I still want the timers to count.

The fuses are 0x7f, 0xdf, 0xff.

Here's the code it's running for this test:

#include <Arduino.h>
#include <EEPROM.h>
#include <avr/sleep.h>
#include <avr/power.h>

#define P0 0
#define P1 1
#define P_UNUSED 2

ISR(TIMER0_COMPA_vect) {
  // do nothing - just wake up
}

void setup() {
  power_adc_disable();
  power_usi_disable();
  power_timer1_disable();
  //PRR = _BV(PRADC) | _BV(PRTIM1) | _BV(PRUSI); // everything off but timer 0.
  TCCR0A = _BV(WGM01); // mode 2 - CTC
  TCCR0B = _BV(CS02) | _BV(CS00); // prescale = 1024
  // xtal freq = 16.384 MHz.
  // CPU freq = 16.384 MHz / 8 = 2.048 MHz
  // count freq = 2.048 MHz / 1024 = 2000 Hz
  OCR0A = 50; // 25 msec per irq
  TIMSK = _BV(OCIE0A); // OCR0A interrupt only.

  set_sleep_mode(SLEEP_MODE_IDLE);

  pinMode(P_UNUSED, INPUT_PULLUP);
  pinMode(P0, OUTPUT);
  pinMode(P1, OUTPUT);
  digitalWrite(P0, LOW);
  digitalWrite(P1, LOW);

  while(1) { sleep_mode(); }
}
void loop() {}
JYelton
  • 32,302
  • 33
  • 134
  • 249
nsayer
  • 1,543
  • 1
  • 18
  • 35
  • What are you using to measure the current? Are you interrupting the Vcc lines directly to the MCU or is there a voltage regulator in between? What are your inputs/outputs connected to? – user36129 Aug 10 '14 at 20:15
  • I am using a µCurrent Gold. This whole thing is on a breadboard, so it's very direct. There are no inputs. The two outputs are connected to LEDs for the moment, but it's a moot point given that we write LOW (so the LEDs are out) and then sleep forever. – nsayer Aug 10 '14 at 20:21
  • Furthermore, if I change the sleep to SLEEP_MODE_PWR_DOWN, I *do* see the level of consumption I expect - on the order of 200 nA. – nsayer Aug 10 '14 at 20:24
  • Which revision of the chip are you using? – Ignacio Vazquez-Abrams Aug 10 '14 at 20:26
  • It's a PDIP one. Theres a bunch of lettering on the bottom. Left to right, top to bottom: 3W1 160 B1 1P 1328 B3. The top just says 1328 ATTINY85 20PU. – nsayer Aug 10 '14 at 20:34
  • Have you tried a 2 MHz crystal instead of running the oscillator at 16 MHz and dividing inside the uC? – JimmyB Aug 10 '14 at 20:36
  • @HannoBinder No. But they don't make low value crystals in the footprint I've got on the boards that are coming. If that's the final answer, then so be it, but there's nothing in the datasheet that suggests that the pre-prescaled frequency would result in double power consumption. Quite the contrary. – nsayer Aug 10 '14 at 20:54
  • 1
    Did you kill the comparator? – Ignacio Vazquez-Abrams Aug 10 '14 at 20:55
  • @IgnacioVazquez-Abrams If it's not implied by the 0 bits in the code above, then no. Can you give me a datasheet reference? – nsayer Aug 10 '14 at 20:56
  • Analog Comparator section, `ACSR` register. – Ignacio Vazquez-Abrams Aug 10 '14 at 20:58
  • @IgnacioVazquez-Abrams Adding `ACSR = _BV(ACD);` didn't change anything in an appreciable way. – nsayer Aug 10 '14 at 21:23
  • 1
    Have you have a look at some of the tricks the jeelabs guy did? See here (start reading at the bottom): http://jeelabs.org/tag/lowpower/ – RJR Aug 11 '14 at 05:13
  • 1
    @RJR I took a look, and unfortunately a lot of their tricks won't work because I can only use SLEEP_MODE_IDLE because I need to keep the timer running. This application is a clock. – nsayer Aug 11 '14 at 13:59
  • Brown out detector running? – JimmyB Aug 11 '14 at 14:50
  • @HannoBinder No. The high fuse setting of 0xDF disables it. – nsayer Aug 11 '14 at 17:19
  • 1
    If this is a clock, can I suggest running off the internal oscillator and using a watch crystal on timer 2 to fire the watchdog interrupt? You can then use deep sleep. I think there a jeelabs blog post about that somewhere too. – RJR Aug 11 '14 at 23:56
  • 1
    All the googling I see suggests that they're using an external RTC module. If you have an RTC, then, yes, you can use the watchdog and the internal oscillator because the CPU clock isn't important. In this case, however, I want the accuracy of the crystal. And also, this is an ATTiny85 - there is no timer 2, just 0 and 1, and timer 1 consumes an order of magnitude more power than timer 0. I don't know how you'd hook a crystal up to an ATTiny without any extra external components other than as the system clock. – nsayer Aug 12 '14 at 04:10
  • 1
    Ah. I found http://jeelabs.org/2011/06/28/jeenode-with-a-32-khz-crystal/ . That's what you were talking about, but that's an ATMega, not an ATTiny. – nsayer Aug 12 '14 at 04:23

3 Answers3

6

You say that according to Figure 22-7 in the datasheet it should only draw 300µA, but that graph shows the current draw for operation without clock division. A crystal oscillator running at 16MHz is bound to draw more current than one running at 2MHz, and the 3 stage divider will add a bit more. The question is - how much more?

The datasheet also suggests that idle current can be reduced by dividing the clock down, but again it doesn't say how much it will be reduced. Extrapolating the 3.3V line suggests that it would normally draw about 1.5mA at 16.4MHz, and 850µA is a significant reduction - but should it be less?

If you can't use a lower frequency crystal on the boards you have coming then there may be nothing you can do. However, while you have the circuit on a breadboard you could at least try a 2MHz crystal, to see if that really is the problem.

enter image description here

Bruce Abbott
  • 55,540
  • 1
  • 47
  • 89
  • Ok. I'll bite. I'll go to the store today and pick up a 2 MHz crystal and re-fuse the chip for no clock division and check it. – nsayer Aug 11 '14 at 14:10
  • Another difficulty is the need for 2^x crystal frequencies. I went to the store and found a 4.096 MHz one, but 1.024 and 2.048 are hard to find. But not using a 2^x clock makes it hard to pick a prescale and OCR0A value that results in even fractions of a second interrupts. But if 8.192 MHz divided by 16 saves significant power, I'd certainly be happy with that over 16.384 divided by 32. – nsayer Aug 11 '14 at 17:32
  • 2
    With a 4.096 MHz crystal in place and a CPU clock prescale value of 8, it now draws around 450 µA. – nsayer Aug 12 '14 at 01:14
  • a few years late, but why not buy a RTC and use it's PPS, hard sleep the processor and have it only wake on interrupt. – HilarieAK Feb 10 '16 at 11:31
3

I had a similar issue with that chip. The power consumption was 30% more than expected.

The issues was unused GPIO !

They were configured as inputs and left floating. The lack of a clear defined input state did make the GPIO driver consume a lot more that what is specified.

The answer was to enable the pull-ups or configure unused pins as outputs.

Are you sure that the pins are set correctly? In your code it seems so, but did you check?

Blup1980
  • 6,120
  • 3
  • 26
  • 47
  • Well, shit. If `pinMode(P_UNUSED, INPUT_PULLUP);` isn't enough, then WTF? – nsayer Aug 11 '14 at 13:35
  • Yeah, but sometimes this is not sufficient. For instance, you may have pins that are ADC input or analog input by default, regardless of the direction you program. There, you first have to disable the secondary function. That's what I meant by "checking". – Blup1980 Aug 11 '14 at 13:48
  • This is an ATTiny85. There are 6 pins, but 3 of them are RESET and the two xtal pins. Two of them are outputs and one is P_UNUSED. The entire ADC has been explicitly powered down. I'll try the INPUT_PULLUP trick on the other 3 pins, but I suspect it won't change anything. There is an errata for the Tiny45 that talks about not setting the xtal pins to OUTPUT because of power consumption. – nsayer Aug 11 '14 at 14:08
  • Adding `pinMode(3, INPUT_PULLUP);` and the same for 4 and 5 did nothing. – nsayer Aug 11 '14 at 14:17
3

I would like to add that for a separate project, I asked this question, and the answer dramatically impacted this question as well. clearing ADCSRA brought the idle consumption down to what figure 22-6 says it's supposed to take - around 100 µA at a divided system clock rate of 500 kHz - and that's the post-divided clock frequency, not the crystal frequency.

nsayer
  • 1,543
  • 1
  • 18
  • 35