Hi everybody,
I'm new to the forum and still a rookie at programming microcontrollers - though I know my way around in Java. Currently I'm trying to get a watchdog to wake an Attiny85, but I simply don't get it to work. For testing purposes the code is supposed to wake the uC every two seconds, give a short blink on the LED and sleep again. I also tried to shut down as many systems as possible to save power.
The problem is: It just won't blink, the LED stays lit all the time and I just don't see why. The only thing I could imagine is that I messed up with the watchdog registers, but comparing it to some online tutorials, they seem fine to me.
I hope some of you experts can help me on this one. Thanks in advance for any suggestions.
Pete
PS: Can anyone btw explain to me the purpose of using the flag for the watchdog. I read about this one somewhere but I don't get the reason for using it.
Here's my code:
#include <avr/sleep.h>
#include <avr/power.h>
#define LED_PIN 4
volatile boolean wdt_flag = 1;
//Watchdog Interrupt Service
ISR(WDT_vect){
wdt_flag = 1; //flag signalling Watchdog Timeout
}
void setup(){
byte i;
// all pins to OUTPUT LOW
/*for(i=0; i<=5 ; i++){
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}*/
pinMode(LED_PIN, OUTPUT);
ADCSRA = 0; // turn off ADC
//ADCSRA &= ~(1<<ADEN); //not sure if needed in, does previous command do the job?
watchdogSetup();
}
void loop(){
if (wdt_flag == 1) { // wait for watchdog timeout flag
wdt_flag = 0; // reset flag
//blink
digitalWrite (LED_PIN, HIGH);
delay (30);
digitalWrite (LED_PIN, LOW);
goToSleep();
}
}
void goToSleep(){
set_sleep_mode(SLEEP_MODE_PWR_DOWN); //set sleep mode
sleep_enable();
//power_all_disable(); // disable as much as possible
sleep_mode(); //sleep
//-----------------ZZZ
sleep_disable(); //aufwachen
//power_timer0_enable(); // enable timers, don't need the rest anyway
//power_timer1_enable(); //
}
void watchdogSetup(){
cli(); //interrupts off
MCUSR &= ~(1 << WDRF); //delete WDRF Bit
WDTCR |= (1<<WDCE) | (1<<WDE); //Watchdog registers: WDCE (Change Enable Bit), WDE (System Reset Enable Bit; both must be on)
WDTCR = (1 << WDP0) | (1 << WDP1) | (1 << WDP2); // set WD to 2 seconds, see table
WDTCR = (1<<WDIE); //set WD to interrupt mode (WDIE)
sei(); //interrupts on
}
/*
time const Prescaler-Bits
WDP0 WDP1 WDP2 WDP3
16 ms WDTO_15MS 0 0 0 0
32 ms WDTO_30MS 1 0 0 0
64 ms WDTO_60MS 0 1 0 0
0,125s WDTO_120MS 1 1 0 0
0,25s WDTO_250MS 0 0 1 0
0,5s WDTO_500MS 1 0 1 0
1,0s WDTO_1S 0 1 1 0
2,0s WDTO_2S 1 1 1 0
4,0s WDTO_4S 0 0 0 1
8,0s WDTO_8S 1 0 0 1
*/