#include <avr/sleep.h>
#include <avr/power.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
#define BODS 7 //BOD Sleep bit in MCUCR
#define BODSE 2 //BOD Sleep enable bit in MCUCR
uint8_t mcucr1, mcucr2;
#define LED1_PIN 3
#define LED2_PIN 4
// milliseconds
#define BLINK_RATE 200
volatile boolean f_wdt;
volatile boolean f_btn;
// 8 = 4 seconds
// 9 = 8 seconds
#define WATCHDOG_SETTING 8
extern volatile unsigned long timer0_overflow_count; // specific to attiny
void setup() {
pinMode(LED1_PIN,OUTPUT);
pinMode(LED2_PIN,OUTPUT);
// Power down various bits of hardware to lower power usage
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
disable_adc();
disable_ac();
disable_brown_out_detector();
f_wdt = 0;
disable_watchdog();
setup_watchdog(WATCHDOG_SETTING);
// enable global interrupts
sei();
}
void loop() {
goToSleep();
if( f_wdt == 1 ) {
digitalWrite(LED1_PIN,HIGH);
digitalWrite(LED2_PIN,HIGH);
delay(BLINK_RATE);
digitalWrite(LED1_PIN,LOW);
digitalWrite(LED2_PIN,LOW);
f_wdt = 0;
}
}
void goToSleep() {
sleep_cpu();
}
void disable_brown_out_detector() {
mcucr1 = MCUCR | _BV(BODS) | _BV(BODSE);
mcucr2 = mcucr1 & ~_BV(BODSE);
MCUCR = mcucr1;
MCUCR = mcucr2;
}
void disable_adc() {
cbi(ADCSRA,ADEN);
}
void disable_ac() {
sbi(ACSR,ACD);
}
//****************************************************************
// 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);
}
void disable_watchdog() {
cbi(WDTCR,WDIE);
}
ISR (WDT_vect) {
f_wdt = 1;
}