Reducing Battery Power Consumption for Digispark ATtiny85

Introduction: Reducing Battery Power Consumption for Digispark ATtiny85

About: Arduino addict

or: Running an Arduino with a 2032 coin cell for 2 years.

Using your Digispark Arduino Board out of the box with an Arduino program it draws 20 mA at 5 volt.

With a 5 volt power bank of 2000 mAh it will only run for 4 days.

Step 1: Reducing Supply Voltage by Using a Li-ion Battery

Using a Li-ion battery with 3.7 volt as supply your Digispark board draws only 13 mA.

With a battery of 2000 mAh it will run for 6 days.

Step 2: Reduce CPU Clock

If you do not use USB connection, heavy math or fast polling in your program, reduce the clock speed. E.g. the heavy polling infrared receiving library IRMP runs well at 8 MHz.

At 1 MHz your Digispark draws 9 mA. With a battery of 2000 mAh it will run for 9 days.

Step 3: Remove the on Board Power LED and Power Regulator

Disable the power LED by breaking the copper wire that connects the power LED to the diode with a knife or remove / disable the 102 resistor. The LED runs at 1.9 volt, so with 3.7 volt Li-ion there are 1.8 volt at the 1k resistor resulting in 1.8 mA for the LED.

Since you are using a Li-ion battery now, you can also remove the on board power regulator IC. First lift the outer pins with the help of a solder iron and a pin. Then solder the big connector and remove the regulator. For small regulators, use much solder and heat up all 3 pins together, then remove it.

The regulator internally has a 2k2 resistor between its output and ground, using 1.7 mA.

At 1 MHz and 3.7 volt your Digispark now draws 5.5 mA. With a battery of 2000 mAh it will run for 15 days.

Step 4: Optional - Disconnecting the USB D- Pullup Resistor (marked 152) From 5 Volt (VCC) and Connect It to USB V+

This step removes the pullup resistor connecting VCC and the 3.7 volt zener diode. This resistor is 1k5 on micro USB boards and 1k0 on USB A boards.

At 5 volt it saves 0.85 / 1.3 mA, with a 3.7 volt Li-ion supply, it saves nothing!

This modification is compatible with all1.x versions of the micronucleus bootloader. If you already have a new 2.x bootloader on your board, you must upgrade to one the 2.6 versions with "activePullup" in its name. The easiest way to do this, is to install the new digispark board package and burn the bootloader with the recommended (!!!not the default or aggressive!!!) version.

Break the copper wire on the side of the resistor that points to the ATtiny.

This disables the USB interface and in turn the possibility to program the Digispark board via USB. To enable it again, but still save power, connect the resistor (marked 152 on micro USB boards and 102 on USB A boards) directly to the USB V+ that is easily available at the outer side of the shottky diode.

The diode and its correct sides can be found by using a continuity tester. One side of this diode is connected to pin 8 of the ATtiny (VCC) and Digispark 5V. The other side is connected to the USB V+.

Now the USB pullup resistor is only activated if the Digispark board is connected to USB e.g. during programming.

The latter 2 steps are also documented here.

Step 5: Use Sleep Instead of Delay()

Instead of long delays you can use power saving CPU sleep. Sleeps can last from 15 milliseconds to 8 seconds in steps of 15, 30, 60, 120, 250, 500 milliseconds and 1, 2, 4, 8 seconds.

Since startup time from sleep is 65 milliseconds with the factory digispark fuse settings, only delays bigger than 80 ms can be replaced by sleep.

During sleep your Digispark draws 27 µA. With a 200 mAh button cell 2032 it will sleep for 10 month.

To be correct, the Digispark must at least wake up every 8 seconds, running for at least 65 milliseconds and drawing around 2 mA current. This leads to an average current of 42 µA and 6 month. In this scenario it makes almost no difference if your program runs for 10 milliseconds (every 8 seconds).

The code for using sleep is:

#include <avr/sleep.h><br>#include <avr/wdt.h><br>volatile uint16_t sNumberOfSleeps = 0;
extern volatile unsigned long millis_timer_millis;

void setup() {
sleep_enable();
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // deepest sleep mode
...
}

void loop(){
...
sleepWithWatchdog(WDTO_250MS, true); // sleep for 250 ms
...
sleepWithWatchdog(WDTO_2S, true); // sleep for 2 s
...
}

/*
* aWatchdogPrescaler can be 0 (15 ms) to 3(120 ms), 4 (250 ms) up to 9 (8000 ms)
*/
uint16_t computeSleepMillis(uint8_t aWatchdogPrescaler) {
uint16_t tResultMillis = 8000;
for (uint8_t i = 0; i < (9 - aWatchdogPrescaler); ++i) {
tResultMillis = (tResultMillis / 2) + 65; // + 65 for the startup time
}
return tResultMillis;
}

/*
* aWatchdogPrescaler (see wdt.h) can be one of
* WDTO_15MS, 30, 60, 120, 250, WDTO_500MS
* WDTO_1S to WDTO_8S
*/
void sleepWithWatchdog(uint8_t aWatchdogPrescaler, bool aAdjustMillis) {
MCUSR = 0; // Clear MCUSR to enable a correct interpretation of MCUSR after reset
ADCSRA &= ~ADEN; // disable ADC just before sleep -> saves 200 uA
// use wdt_enable() since it handles that the WDP3 bit is in bit 5 of the WDTCR register
wdt_enable(aWatchdogPrescaler);
WDTCR |= _BV(WDIE) | _BV(WDIF); // Watchdog interrupt enable + reset interrupt flag -> needs ISR(WDT_vect)
sei(); // Enable interrupts
sleep_cpu(); // The watchdog interrupt will wake us up from sleep
wdt_disable(); // Because next interrupt will otherwise lead to a reset, since wdt_enable() sets WDE / Watchdog System Reset Enable
ADCSRA |= ADEN;
/*
* Since timer clock may be disabled adjust millis only if not slept in IDLE mode (SM2...0 bits are 000)
*/
if (aAdjustMillis && (MCUCR & ((_BV(SM1) | _BV(SM0)))) != 0) {
millis_timer_millis += computeSleepMillis(aWatchdogPrescaler);
}
}

/*
* This interrupt wakes up the cpu from sleep
*/
ISR(WDT_vect) {
sNumberOfSleeps++;
}

Step 6: Modify the Fuses

22 µA of the the 27 µA are drawn by the BOD (BrownOutDetection/undervoltage detection). The BOD can only be disabled by reprogramming the fuses, which can only be done with an ISP programmer. Using this script you can reduce current down to 5.5 µA and also reduce startup time from sleep to 4 milliseconds.

5 of the remaining 5.5 µA are drawn by the active watchdog counter. If you can use external resets for wake up, current consumpion can go down to the 0.3 µA as stated in the datasheet.

If you are not able to reach this value, the reason can be, that the reverse current of the schottky diode between VCC and the pullup is too high. Keep in mind that a 12 MOhm resistor also draws 0.3 µA at 3.7 volt.

This results in an average current consumption of 9 µA (2.5 years with a 200 mAh button cell 2032) if you e.g. process data every 8 seconds for 3 milliseconds like here.

Step 7: Further Information

Battery Powered Contest

Participated in the
Battery Powered Contest

Be the First to Share

    Recommendations

    • Block Code Contest

      Block Code Contest
    • Make it Glow Contest

      Make it Glow Contest
    • Baking Contest

      Baking Contest

    Comments