1. Goals

Required Supplies
  • Analog Discovery 2

  • ATtiny85

  • Breadboard

  • Datasheets!

  • Measure MCU power supply currents in various operational modes and states.

2. Setup

Use the following Waveforms workspace:

attiny pinout
Table 1. ISP connections
Purpose Nano ATtiny85 AD2 default Description

RESET

D10

pin 1

D1

reset

MOSI

D11

pin 5

D0

Serial data in

MISO

D12

pin6

D3

Serial data out

SCK

D13

pin 7

D2

Serial clock

Program this code to your ATtiny85:

/*----------------------------------------------------------------------*
 * Sleep demo for ATtinyX5.                                             *
 * Wire a button from pin D2 (INT0, PB2, DIP pin 7) to ground.          *
 * Wire an LED with an appropriate dropping resistor from pin           *
 * D4 (PB4, DIP pin 3) to ground.                                       *
 * Pushing the button wakes the MCU.                                    *
 * After waking, the MCU flashes the LED, then waits 10 seconds before  *
 * going back to sleep.                                                 *
 *                                                                      *
 * Jack Christensen 07May2013                                           *
 *                                                                      *
 * Developed with Arduino 1.0.4.                                        *
 * Test conditions for all results below:                               *
 *   5V regulated power supply                                          *
 *   8MHz system clock (internal RC oscillator)                         *
 *   Fuse bytes (L/H/E): 0xE2 / 0xD5 / 0xFF                             *
 *   Arduino-Tiny core, http://code.google.com/p/arduino-tiny/          *
 *                                                                      *
 * Note that only the ATtinyX5 devices below have BOD disable           *
 * functionality implemented. With Vcc=5V, the BOD will draw            *
 * 20-25µA, depending on temperature.                                   *
 *   ATtiny25, revision E, and newer                                    *
 *   ATtiny45, revision D, and newer                                    *
 *   ATtiny85, revision C, and newer                                    *
 *                                                                      *
 * ATtiny45V-10PU, Rev. G                                               *
 *   7.4mA active, 0.1µA power-down.                                    *
 *                                                                      *
 * ATtiny85V-10PU, Rev. B                                               *
 *   7.1mA active, 21µA power-down.                                     *
 *                                                                      *
 * This work is licensed under the Creative Commons Attribution-        *
 * ShareAlike 3.0 Unported License. To view a copy of this license,     *
 * visit http://creativecommons.org/licenses/by-sa/3.0/ or send a       *
 * letter to Creative Commons, 171 Second Street, Suite 300,            *
 * San Francisco, California, 94105, USA.                               *
 *----------------------------------------------------------------------*/ 
 
#include <avr/sleep.h>

#define LED 0                      //LED on PB0, DIP pin 5
#define KEEP_RUNNING 10000         //milliseconds


void setup(void)
{
    //to minimize power consumption while sleeping, output pins must not source
    //or sink any current. input pins must have a defined level; a good way to
    //ensure this is to enable the internal pullup resistors.

    for (byte i=0; i<5; i++) {     //make all pins inputs with pullups enabled
        pinMode(i, INPUT);
        digitalWrite(i, HIGH);
    }

    pinMode(LED, OUTPUT);          //make the led pin an output
    digitalWrite(LED, LOW);        //drive it low so it doesn't source current
}



void loop(void)
{
    for (byte i=0; i<5; i++) {     // flash the LED
        digitalWrite(LED, HIGH);
        delay(100);
        digitalWrite(LED, LOW);
        delay(100);
    }
    digitalWrite(LED, HIGH);
    
    delay(KEEP_RUNNING);           // opportunity to measure active supply current 

    digitalWrite(LED, LOW);
    goToSleep();
}



void goToSleep(void)
{
    byte adcsra, mcucr1, mcucr2;

    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_enable();
    MCUCR &= ~(_BV(ISC01) | _BV(ISC00));      //INT0 on low level
    GIMSK |= _BV(INT0);                       //enable INT0
    adcsra = ADCSRA;                          //save ADCSRA
    //ADCSRA &= ~_BV(ADEN);                     //disable ADC
    
    cli();                                    //stop interrupts to ensure the BOD timed sequence executes as required
    mcucr1 = MCUCR | _BV(BODS) | _BV(BODSE);  //turn off the brown-out detector
    mcucr2 = mcucr1 & ~_BV(BODSE);            //if the MCU does not have BOD disable capability,
    MCUCR = mcucr1;                           //  this code has no effect
    MCUCR = mcucr2;
    sei();                                    //ensure interrupts enabled so we can wake up again
    
    sleep_cpu();                              //go to sleep
    sleep_disable();                          //wake up here
    ADCSRA = adcsra;                          //restore ADCSRA
}

//external interrupt 0 wakes the MCU
ISR(INT0_vect)
{
    GIMSK = 0;                     //disable external interrupts (only need one to wake up)
}

Connections:

  • PB0 (pin 5) to an oscilloscope input.

  • PB2 (pin 7) to a button that connects to GND.

Measure the power supply current of this sketch. Configure the benchtop meter to:

  • Manual range: 10 mA

  • S speed, for the most precision

This current should:

  • Start at about 4.3 mA, then after a few seconds, drops to

  • 250 μA

Push the button, or briefly connect the pin to GND. The supply current will jump back up to 4.3 mA and eventually return to 250 μA.

  • Connect PB1 (pin 6) to GND.

  • The supply current will increase to 340 μA. This pin has the internal pull-up resistor enabled. What is the effective resistance of this resistor, given this increase in current?

Finally, the Arduino framework enables the ADC even though the chip itself starts with the ADC disabled.

  • UNcomment the line:
    ADCSRA &= ~_BV(ADEN);

  • Recompile and upload

The sleep mode power supply current will drop to either near zero (need to change the meter’s range to actually measure well), or about 92 μA depending on the state of PB1 (pin 6)'s state.

3. Other

Example code segment from avr-libc for the proper way to sequence shutdown into a sleep mode:

#define SLEEP_MODE_IDLE (0x00<<3)
#define SLEEP_MODE_ADC (0x01<<3)
#define SLEEP_MODE_PWR_DOWN (0x02<<3)

void system_sleep(void) {
    set_sleep_mode(SLEEP_MODE_here);
    cli();
    if (some_condition) {
        sleep_enable();
        sleep_bod_disable();
        sei();
        sleep_cpu();
        sleep_disable();
    }
    sei();
}

4. Reference

avr-libc

https://www.nongnu.org/avr-libc/user-manual/groupavrsleep.html[<avr/sleep.h>: Power Management and Sleep Modes^]