Skip to content

Instantly share code, notes, and snippets.

@hernan43
Last active April 28, 2018 21:42
Show Gist options
  • Save hernan43/1e20301fdd08d3bbaa0afd34f06d4253 to your computer and use it in GitHub Desktop.
Save hernan43/1e20301fdd08d3bbaa0afd34f06d4253 to your computer and use it in GitHub Desktop.
I took various bits and pieces from the included projects and combined them to create an Annoy-O-Bug that conserves power by using the ATTiny85's built in watchdog timer.
/*
ATTiny85 Annoy-O-Bug
This is equal parts:
https://create.arduino.cc/projecthub/arjun/programming-attiny85-with-arduino-uno-afb829
https://www.hackster.io/AlexWulff/the-annoy-o-bug-a-chirping-light-up-throwie-37e58a
https://github.com/sparkfun/H2OhNo/blob/master/firmware/WatchDogTest/WatchDogTest.ino
https://github.com/SpenceKonde/ATTinyCore
I took various bits and pieces from teh above projects and combined them to create an Annoy-O-Bug
that conserves power by using the ATTiny85's built in watchdog timer. I needed to use the ATTinyCore
from SpenceKonde in order to get tone() support.
*/
#include <avr/sleep.h> //Needed for sleep_mode
#define BUZZ 0
#define LED 1
//Lower bound: 60 seconds
//Upper bound: 10 minutes
#define LOWER 60
#define UPPER 600
volatile int watchdog_counter;
volatile int beep_interval;
//This runs each time the watch dog wakes us up from sleep
ISR(WDT_vect) {
//watchdog_counter++;
watchdog_counter +=8; // 8 seconds
}
void setup() {
// put your setup code here, to run once:
pinMode(BUZZ, OUTPUT);
pinMode(LED, OUTPUT);
//Seed the random function with the value of an
//unconnected analog pin
randomSeed(analogRead(1));
//Flash the light to make sure the device is working
for (int i = 0; i < 5; i++) {
tone(BUZZ, 3500, 200);
digitalWrite(LED, HIGH);
delay(200);
digitalWrite(LED, LOW);
delay(200);
}
watchdog_counter = 0;
beep_interval = 15;
//Power down various bits of hardware to lower power usage
set_sleep_mode(SLEEP_MODE_PWR_DOWN); //Power down everything, wake up from WDT
sleep_enable();
ADCSRA &= ~(1<<ADEN); //Disable ADC, saves ~230uA
setup_watchdog(9); //Wake up after 128 msec
}
void loop() {
sleep_mode(); //Go to sleep!
if(watchdog_counter > beep_interval) {
watchdog_counter = 0;
// set a new random-ish beep interval
beep_interval = random(LOWER, UPPER);
tone(BUZZ, 4500, 250);
digitalWrite(LED, HIGH);
delay(250);
digitalWrite(LED, LOW);
}
}
// 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms
// 6=1sec, 7=2sec, 8=4sec, 9=8sec
// From: http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
void setup_watchdog(int timerPrescaler) {
if (timerPrescaler > 9 ) timerPrescaler = 9; //Correct incoming amount if need be
byte bb = timerPrescaler & 7;
if (timerPrescaler > 7) bb |= (1<<5); //Set the special 5th bit if necessary
//This order of commands is important and cannot be combined
MCUSR &= ~(1<<WDRF); //Clear the watch dog reset
WDTCR |= (1<<WDCE) | (1<<WDE); //Set WD_change enable, set WD enable
WDTCR = bb; //Set new watchdog timeout value
WDTCR |= _BV(WDIE); //Set the interrupt enable, this will keep unit from resetting after each int
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment