Very simple circuit: connect power to pins 4 and 8 on the ATtiny85 and connect a buzzer between pin 6 of the ATtiny85 and GND (the minus of the battery)[br][br]You can [url=http://test.geogebra.org/~mike/attiny85/annoyatron.hex]download the .hex file[/url] or compile the code yourself (below, or from [url=https://raw.githubusercontent.com/pedroliska/ATtiny85/master/watchdog-wake/watchdog-wake.ino]https://raw.githubusercontent.com/pedroliska/ATtiny85/master/watchdog-wake/watchdog-wake.ino[/url]). [br][br]See here for a [url=https://pedroliska.wordpress.com/2015/07/13/building-your-own-annoy-a-tron-with-an-attiny85/]finished project on protoboard[/url].
[code]#include <avr/interrupt.h>[br]#include <avr/io.h>[br]#include <avr/power.h>[br]#include <avr/sleep.h>[br]#include <avr/wdt.h>[br]#include <util/delay.h> [br]#ifndef ARDUINO[br]#include [br]#include "millionUtil.h" //not needed if compiled with Arduino & Arduino-Tiny[br]#endif[br][br]#define BODS 7 //BOD Sleep bit in MCUCR[br]#define BODSE 2 //BOD Sleep enable bit in MCUCR[br][br]int PIN = 1;[br]int REGULAR_HI_MS = 800;[br]int WAKE_INDICATOR_HI_MS = 0; //200;[br]int INITIAL_BEEP_COUNT = 3; // number of "test" beeps before we go into the real loop[br][br]// RANDOM_SLEEP_MIN = minimum number of 8-sec WDT periods to sleep for[br]// RANDOM_SLEEP_MAX = maximum number of 8-sec WDT periods to sleep for[br]int RANDOM_SLEEP_MIN = 7; // 1 min (1 * 60 / 8)[br]int RANDOM_SLEEP_MAX = 30; // 4 mins[br]//int RANDOM_SLEEP_MIN = 225; // 30 mins[br]//int RANDOM_SLEEP_MAX = 525; // 70 mins[br][br]uint8_t mcucr1, mcucr2;[br]bool keepSleeping; //flag to keep sleeping or not[br]unsigned long msNow; //the current time from millis()[br]unsigned long msWakeUp; //the time we woke up[br]long wdtCount; //how many 8-sec WDT periods we've slept for[br][br]void setup() { [br] for (int i=0; i < INITIAL_BEEP_COUNT - 1; i++) {[br] makeTone(REGULAR_HI_MS);[br] goToSleep(1);[br] }[br]}[br][br]void loop() {[br] makeTone(REGULAR_HI_MS);[br] goToSleep(random(RANDOM_SLEEP_MIN, RANDOM_SLEEP_MAX + 1));[br]}[br][br]void makeTone(int msOfTone) {[br] pinMode(PIN, OUTPUT);[br] startTone();[br] delay(msOfTone); // let the tone sound for a bit[br] stopTone();[br] pinMode(PIN, INPUT);[br]}[br]void startTone() {[br] //TCCR1 = 0x94; // faster clock[br] //TCCR1 = 0x99; [br] //TCCR1 = 0x9F; // slower clock (max value)[br][br] //OCR1C = 4; // highest pitch (hard to listen)[br] //OCR1C = 5;[br] //OCR1C = 200;[br] //OCR1C = 255; // lowest pitch (max value)[br][br] // hi pitch combo (perfect with 3v no resistor, and no transistor)[br] TCCR1 = 0x94;[br] //OCR1C = 4;[br] OCR1C = 7;[br][br]// // old phone combo (too silent with 3v, no resistor, and no transistor)[br]// TCCR1 = 0x99; [br]// OCR1C = 255;[br][br]// // audible combo[br]// TCCR1 = 0x94;[br]// OCR1C = 20;[br]}[br]void stopTone() {[br] TCCR1 = 0x90; // stop the counter[br]}[br][br]// wdtLimit = number of WDT periods to wake after[br]void goToSleep(long wdtLimit)[br]{[br] msNow = millis();[br] wdtCount = 0;[br] [br] do {[br] ACSR |= _BV(ACD); //disable the analog comparator[br] ADCSRA &= ~_BV(ADEN); //disable ADC[br] set_sleep_mode(SLEEP_MODE_PWR_DOWN);[br] sleep_enable();[br] [br] wdtEnable(); //start the WDT[br] [br] //turn off the brown-out detector.[br] //must have an ATtiny45 or ATtiny85 rev C or later for software to be able to disable the BOD.[br] //current while sleeping will be <0.5uA if BOD is disabled, <25uA if not.[br] cli();[br] mcucr1 = MCUCR | _BV(BODS) | _BV(BODSE); //turn off the brown-out detector[br] mcucr2 = mcucr1 & ~_BV(BODSE);[br] MCUCR = mcucr1;[br] MCUCR = mcucr2;[br] sei(); //ensure interrupts enabled so we can wake up again[br] sleep_cpu(); //go to sleep[br] //----zzzz----zzzz----zzzz----zzzz[br] cli(); //wake up here, disable interrupts[br] sleep_disable();[br] wdtDisable(); //don't need the watchdog while we're awake[br] sei(); //enable interrupts again (but INT0 is disabled above)[br][br] if (++wdtCount < wdtLimit) {[br] keepSleeping = true;[br] if (WAKE_INDICATOR_HI_MS > 0) {[br] makeTone(WAKE_INDICATOR_HI_MS); //briefly blink an LED so we can see the wdt wake-ups[br] }[br] }[br] else {[br] keepSleeping = false;[br] }[br] } while (keepSleeping);[br] [br] msWakeUp = millis();[br]}[br][br]ISR(WDT_vect) {} //don't need to do anything here when the WDT wakes the MCU[br][br]//enable the WDT for 8sec interrupt[br]void wdtEnable(void)[br]{[br] wdt_reset();[br] cli();[br] MCUSR = 0x00;[br] WDTCR |= _BV(WDCE) | _BV(WDE);[br] WDTCR = _BV(WDIE) | _BV(WDP3) | _BV(WDP0); //8192ms[br] sei();[br]}[br][br][br]//disable the WDT[br]void wdtDisable(void)[br]{[br] wdt_reset();[br] cli();[br] MCUSR = 0x00;[br] WDTCR |= _BV(WDCE) | _BV(WDE);[br] WDTCR = 0x00;[br] sei();[br]}[/code]