Strange problem with low power AT Tiny85

Hi all,

I’ve got an infrared remote control transmitter that I made for my DSLR camera.

The remote uses three AAA cells and is powered up all the time.

The hardware is an ATTiny85 processor with a 16 mhz SMD crystal, two 18pF caps and a 1 meg resistor across.

Reset is tied to VCC via a 10K resistor, the other 3 pins are connected as follows:

PB0 - tied low through a 100K resistor and connected to the base of an NPN BJT via a 220 ohm resistor. The BJT drives the IR LED, which is connected between VCC and the collector of the BJT through a 2,2 ohm resistor.

PB1 - tied to VCC via a 100K resistor, currently not used.
PB2 - tied to VCC via a 100K resistor and is pulled to ground via a pushbutton (this sends the IR command).

I measured the supply current by placing a 10K resistor across my voltmeter, then putting the voltmeter and “shunt” in series with the battery pack. I got 0.27 volts, which across 10K is 27 microamps.

So far, so good… but my problem is that the battery pack seems to get sucked dry in a day or two (without the remote even being used).

Am I missing something or testing it wrong? I don’t see how it can draw 27 uA but kill 3 brand new AAA alkaline cells in two days. What the heck is going on here?

By the way, here’s the part of the code that sets up the timer, sets up the power save stuff and puts the board to sleep… is there anything wrong here?

// setup the timer for interrupts
void timerInit (uint32_t rate)
{
    cli(); // disable interrupts

    enable = 0; // zero all...
    busy = 0; // ...ISR...
    count = 0; // ...vars

    IO_OUT = 0x00; // all pins off (no pullup)
    IO_DDR = 0x00; // all pins inputs

    MCUCR = 0x00; // clear MCU control register
    GIMSK = 0x00; // clear interrupt mask register

    // set timer 0 (8 bit) to CTC mode, carrier freq. this times the IR pulses.
    TCCR0A = _BV(WGM01); // mode 2 (CTC) OCR0A = top
    TCCR0B = _BV(CS00); // set F_CPU/1
    OCR0A  = ((F_CPU / (rate * 2)) - 1); // double rate because we toggle
    TIMSK  = _BV(OCIE0A); // enable interrupt on OCR0A match

    // shut off everything not used
    MCUCR |= _BV(PUD); // disable port pullups
    ADCSRA = 0x00; // disable ADC
    power_adc_disable(); // power down ADC
    power_timer1_disable(); // power down timer 1
    power_usi_disable(); // power down USI
    sleep_bod_disable(); // turn off brown-out detector
    set_sleep_mode (SLEEP_MODE_PWR_DOWN); // set CPU sleep mode

    sei(); // interrupts on
}

int main (void)
{
    uint8_t n; // generic

    timerInit (IR_FREQ); // setup 8 bit timer for IR carrier frequency

    while (1) {

        cli(); // disable interrupts

        GIMSK |= _BV(INT0); // enable INT0 to trigger active low
        sleep_enable(); // enable CPU to be powered down

        sei(); // interrupts on
        sleep_cpu(); // power down cpu (all clocks stopped)

        // debounce start button (in case it's tied to SELECT)
        n = 10; // init debounce
        while (n--) {
            if (IO_PIN & BUTTON) { // if button bounced up...
                n = 10; // ...reload debounce count
            }
            delayMS (5);
        }

        // send shutter command
        sendCmd (shutter, 3, 0); // data, repeat 3 times, no inter-command delay

        // wait for button to be RELEASED
        // (prevent repeat if button held down)
        n = 10; // init debounce
        while (n--) {
            if (! (IO_PIN & BUTTON)) { // if button pressed...
                n = 10; // ...reload debounce count
            }
            delayMS (5);
        }
    }
}

Any ideas will be appreciated.

First off, your shunt resistor is too high by at least two orders of magnitude. You need to use a 100 ohm resistor or better yet a 10 ohm resistor The shunt resistor is going to drop a little of the battery voltage when you take the measurement so you need to minimize this. For example suppose your circuit draws 1mA. The 10k shunt will drop 10Volts. Thats more than the entire battery voltage. If you use a 10 ohm resistor, then that same 1mA will create a voltage drop of 10milli volts. If the current draw is so little that its hard to measure that small of a voltage, then use a 100 ohm resistor.

jeffluminais: First off, your shunt resistor is too high by at least two orders of magnitude. You need to use a 100 ohm resistor or better yet a 10 ohm resistor The shunt resistor is going to drop a little of the battery voltage when you take the measurement so you need to minimize this. For example suppose your circuit draws 1mA. The 10k shunt will drop 10Volts. Thats more than the entire battery voltage. If you use a 10 ohm resistor, then that same 1mA will create a voltage drop of 10milli volts. If the current draw is so little that its hard to measure that small of a voltage, then use a 100 ohm resistor.

Um... I had 0.27 volts across the 10K resistor.......

  1. Your battery pack capacity = 860 mAh (AAA Type Alkanine).

  2. Battery pack exhausted in 24 hrs.

  3. So, your ATtiny has drawn 860 mAh/24 = 34 mA current. (How could it be?)

  4. Idle Icc for ATtiny85 is = 2.1 mA at 4.5V.

  5. All IO Modules are OFF except T0; add another 10%.

  6. Idle current drainage = 2.31 mA

  7. The battery pack should last for: 15 days.

  8. Where is the fault? (a) Any surface leakage across the battery terminals? (b) Any leakage across the PCB tracks? (c) Any leaky filter/decoupling capacitors?

  9. Trouble shooting could be proceeded: (a) Remove the 18PFs and observe the battery life. (b) isolate BJT and observe battery life. (c) And etc.

What criteria are you using to determine that the batteries are being "sucked dry"? Pack voltage? Circuit operation? According to the datasheet 16 MHz requires at least 3.78V (1.26V/cell) for operation. This is quite a high cutoff voltage.

BOD has to be disabled immediately before sleeping. The AVRLibc page shows the proper sequence you must follow.

27 uA seems high for sleep current. Did you clean the flux off?

GolamMostafa: 1. Your battery pack capacity = 860 mAh (AAA Type Alkanine).

  1. Battery pack exhausted in 24 hrs.

  2. So, your ATtiny has drawn 860 mAh/24 = 34 mA current. (How could it be?)

  3. Idle Icc for ATtiny85 is = 2.1 mA at 4.5V.

  4. All IO Modules are OFF except T0; add another 10%.

  5. Idle current drainage = 2.31 mA

  6. The battery pack should last for: 15 days.

  7. Where is the fault? (a) Any surface leakage across the battery terminals? (b) Any leakage across the PCB tracks? (c) Any leaky filter/decoupling capacitors?

  8. Trouble shooting could be proceeded: (a) Remove the 18PFs and observe the battery life. (b) isolate BJT and observe battery life. (c) And etc.

All good suggestions... leakage across PCB traces I never thought about, but I did clean the whole board after assembling it (I soaked the board in pure ethanol, then used an old toothbrush to remove the flux). The board is squeaky clean.

As far as the crystal caps... the oscillator does not run in sleep mode (or are you thinking about leakage?).

Jiggy-Ninja: What criteria are you using to determine that the batteries are being "sucked dry"? Pack voltage? Circuit operation? According to the datasheet 16 MHz requires at least 3.78V (1.26V/cell) for operation. This is quite a high cutoff voltage.

BOD has to be disabled immediately before sleeping. The AVRLibc page shows the proper sequence you must follow.

27 uA seems high for sleep current. Did you clean the flux off?

I determine that the cells are being "sucked dry" by the fact that the remote stops working and then when I put a voltmeter across each cell, I read less than 1 volt each. :)

The BOD is disabled (fuse-wise) and I also do a sleep_bod_disable(); call inside the timer init. I don't however, call it before each sleep.

I suppose looking at the Atmel suggested sequence of sleeping would be a good idea, huh?

Lastly, I agree... 27 uA seems a bit high. I expected to see tens of PICO-amperes.

I'll check out Atmel's method and see if that helps.

VERY interesting! I re-arranged the "go to sleep" sequence as per Atmel's docs (LINK) and now asleep the voltage across the 10K shunt is 0.009 volts (i.e. 0.9 uA). MUCH better... I wonder if I can get it any lower?