Philip Tabone
Published © GPL3+

Sleep AT-tiny

Very low power sleep mode of the ATtiny helps make projects on battery last for days (and possibly months).

AdvancedFull instructions provided2 hours12,019
Sleep AT-tiny

Things used in this project

Hardware components

ATtiny85
Microchip ATtiny85
×1
Resistor 22.1k ohm
Resistor 22.1k ohm
×1
Resistor 4.75k ohm
Resistor 4.75k ohm
×1
Button
×1
Breadboard (generic)
Breadboard (generic)
×1
Resistor 2.21k ohm
Resistor 2.21k ohm
×1
LED (generic)
LED (generic)
×1

Story

Read more

Schematics

AT-tiny timer wake

Design for AT-tiny with sleep timer. Push button puts it back to sleep.
Replace LED with your own awesome project (Via transistor or mosfet)

AT-tiny Interrupt wake

Push button to wake up AT-tiny, Go back to sleep after LED 1 sec Blink. Replace LED with your own awesome project (via Transistor or Mosfet)

Code

Sleep with timer wake

Arduino
Keeps AT-tiny asleep and wakes up on timer interval. Then goes back to sleep.
#include <avr/sleep.h>

#include <avr/wdt.h>

#ifndef cbi

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))

#endif

#ifndef sbi

#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

#endif

int pinLed = 0;
int trig = 2;
int heart = 1;
volatile boolean f_wdt = 1;
int counter = 0;

void setup(){

  pinMode(pinLed,OUTPUT);

  pinMode(heart,OUTPUT);

  pinMode(trig,INPUT);

  setup_watchdog(8); // approximately 4 seconds sleep

}

void loop(){

  if (f_wdt==1) {  // wait for timed out watchdog / flag is set when a watchdog timeout occurs

    f_wdt=0;       // reset flag

  if (counter > 192){ //timer to reset approx 15 min

    digitalWrite(pinLed,HIGH);

    delay(500); // Wait for trigger high until set back to sleep

    while(!digitalRead(trig)){delay(500);}

    digitalWrite(pinLed,LOW);

    counter = 0;

  }

    // Show heartbeat uncomment to show blink

    //digitalWrite(heart,HIGH);

    //delay(200);

    //digitalWrite(heart,LOW );

    pinMode(pinLed,INPUT); // set all used port to intput to save power

    system_sleep();

    pinMode(pinLed,OUTPUT); // set all ports into state before sleep

  }

}

// set system into the sleep state 

// system wakes up when wtchdog is timed out

void system_sleep() {

  cbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter OFF

  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here

  sleep_enable();

  sleep_mode();                        // System sleeps here

  sleep_disable();                     // System continues execution here when watchdog timed out 

  sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter ON

}

// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms

// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec

void setup_watchdog(int ii) {

  byte bb;

  int ww;

  if (ii > 9 ) ii=9;

  bb=ii & 7;

  if (ii > 7) bb|= (1<<5);

  bb|= (1<<WDCE);

  ww=bb;

  MCUSR &= ~(1<<WDRF);

  // start timed sequence

  WDTCR |= (1<<WDCE) | (1<<WDE);

  // set new watchdog timeout value

  WDTCR = bb;

  WDTCR |= _BV(WDIE);

}

// Watchdog Interrupt Service / is executed when watchdog timed out

ISR(WDT_vect) {

  counter++;

  f_wdt=1;  // set global flag

}

Sleep with interrupt Wake

Arduino
Put AT-tiny to sleep and wake up on interrupt.
//ATtiny low power using interrupt to wake

#include <avr/sleep.h>

#include <avr/interrupt.h>

const int switchPin = 3;

const int statusLED = 2;

void setup() {

    pinMode(switchPin, INPUT);

    pinMode(statusLED, OUTPUT);

    // Flash quick sequence so we know setup has started

    for (int k = 0; k < 5; k++) {

        if (k % 2 == 0) {

            digitalWrite(statusLED, HIGH);

            }

        else {

            digitalWrite(statusLED, LOW);

            }

        delay(250);

        } // for

    } // setup


void sleep() {

    GIMSK |= _BV(PCIE);                     // Enable Pin Change Interrupts

    PCMSK |= _BV(PCINT3);                   // Use PB3 as interrupt pin

    ADCSRA &= ~_BV(ADEN);                   // ADC off

    set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // replaces above statement

    sleep_enable();                         // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)

    sei();                                  // Enable interrupts

    sleep_cpu();                            // sleep

    cli();                                  // Disable interrupts

    PCMSK &= ~_BV(PCINT3);                  // Turn off PB3 as interrupt pin

    sleep_disable();                        // Clear SE bit

    ADCSRA |= _BV(ADEN);                    // ADC on

    sei();                                  // Enable interrupts

    } // sleep

ISR(PCINT0_vect) {

    // This is called when the interrupt occurs, but I don't need to do anything in it

    }

void loop() {

    sleep();

    digitalWrite(statusLED, HIGH);

    delay(1000);

    digitalWrite(statusLED, LOW);

    }

Credits

Philip Tabone

Philip Tabone

3 projects • 14 followers
If I need, it I'll build it.

Comments