Hi everyone
I'm starting to play with a ATtiny85, and what I wanted this little guy to do is a very simple task, yet I'm having a difficult time making it happen. All I want is have the ATtiny85 run from a 3.7v lipo in order to blink an LED (connected to pin 0) just once (on for only 1 sec), and then have the ATtiny85 go to sleep for 1 hour (using the Watchdog Timer). After the 1hr, it would wake itself up and start the process all over again.
One of the things that I would like is to minimize as much as possible the power consumption so that the battery lasts longer, and therefore:
- making the AT sleep in "power down mode"
- disable the peripherals that are not being used
- disable the brown-out protection
- no need to change the clock speed yet (unless it is super easy & safe)
I've looked online at many excellent examples in order to try implementing this in my own ATtiny85, but I find them a bit confusing because either the articles were written with an ATmega328 in mind, or in some cases (e.g.: http://www.surprisingedge.com/low-power-atmegatiny-with-watchdog-timer/), the author just shows "pieces" of the code, making it hard for a "noob" like me to reconstruct.
Anyone has any thoughts & suggestions on how I could make my ATtiny85 work as I need it?
I've tried working of some examples to "try" to get on the right track. Here's what I have so far, but it only sleeps for 9 seconds (as a test, in the script I'm trying to make it sleep for 18 sec). I wonder if I should start from scratch?
Any advice & suggestions would be really helpful... thanks! ![]()
#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;
volatile boolean f_wdt = 1;
void setup(){
pinMode(pinLed,OUTPUT);
setup_watchdog(9); // approximately 8 seconds sleep
}
void loop(){
//=============SLEEP ROUTINES========================================================================
for (int myLoop= 0; myLoop < 2; myLoop++) // loop around and give delay of 2 * 9sec = 18 sec
{
if (
f_wdt==1) { // wait for timed out watchdog / flag is set when a watchdog timeout occurs
f_wdt=0; // reset flag
digitalWrite(pinLed,HIGH); // let led blink
delay(1000);
digitalWrite(pinLed,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) {
f_wdt=1; // set global flag
}