Watchdog Timer Interrupt not working - Page 1
Forum section: electronics / beginners

author: vishal
author_rank: Regular Contributor
timestamp: August 09, 2017, 12:37:15 pm
content: HiI have written code to sleep a device using watchdog timer.The code is as follows:Code:void portInit(){DDRD|=(1<<PD6);PORTD|=(1<<PD6);}void WDT_Init(){cli();wdt_reset();WDTCSR=(1<<WDCE)|(1<<WDE);WDTCSR=(1<<WDIE)|(1<WDE)|(1<<WDP0);sei();}ISR(WDT_vect){for(uint8_t i=0;i<4;i++){PORTD|=(1<<PD6);_delay_ms(2000);PORTD&=~(1<<PD6);_delay_ms(20);}}int main(){PortInit();WDT_Init();_delay_ms(100);while(1){PORTD|=(1<<PD6);_delay_ms(20);PORTD&=~(1<<PD6);_delay_ms(500);}}Here the program control is not get inside the interrupt service routine ISR(WDT_vect).What is the mistake in my code.please help

author: Yansi
author_rank: Super Contributor
timestamp: August 09, 2017, 03:44:25 pm
content: It would be helpful to provide thy type of the MCU next time. It might be obvious for some, but not for others!

author: floobydust
author_rank: Super Contributor
timestamp: August 10, 2017, 04:10:46 am
content: It's kind of a disaster.You never write to something (variable, port, I/O pin etc.) in Main and also in an interrupt service routine.You never wait for 2 seconds in the middle of an interrupt service routine.I'm not sure what you are trying to do or what the MCU is.

author: KL27x
author_rank: Super Contributor
timestamp: August 10, 2017, 05:11:27 am
content: Without even looking at your code, what you're trying to do doesn't make any sense, generally speaking.When WDT rolls over, it typically performs a RESET. This might be useful for waking a device from sleep, but putting it to sleep will be performed much easier by using a normal timer.To use WDT to put most devices to sleep would be needlessly cumbersome, involving bit check on bootup/reset to determine if it should immediately go to sleep. This would require device which has WDT flag on reset and unless your program is supposed to normally start out by going to sleep, it would make WDT useless for its normally intended purpose.If you actually do still want what you're asking, it might be helpful for you to tell us why you must use WDT for this and what device you are using? It's a somewhat curious thing you are trying to do.

author: vishal
author_rank: Regular Contributor
timestamp: August 10, 2017, 05:40:51 am
content: Quote from: Yansi on August 09, 2017, 03:44:25 pmI am using avr-atmega256rfr2

author: KL27x
author_rank: Super Contributor
timestamp: August 10, 2017, 10:29:28 am
content: Well, forget what I posted. This device's WDT can be set as general timer interrupt. I assume you figured that out already, thru the WDE and WDIE bits.

author: vishal
author_rank: Regular Contributor
timestamp: August 11, 2017, 03:14:26 am
content: Well I have modified my code for avr-atmega256rfr2MCU as follows with sleep routine :Code:bool timerEvent;void sleep_power(){timerEvent=true;while(1){set_sleep_mode(SLEEP_MODE_PWR_DOWN);sleep_enable();sei();sleep_cpu();sleep_disable();if(timerEvent){return;}}}ISR(WDT_vect){timerEvent=true;}void PortInit(){DDRD|=(1<<PD6);PORTD|=(1<<PD6);}void WDT_Init(){cli();wdt_reset();WDTCSR=(1<<WDCE)|(1<<WDE);WDTCSR=(1<<WDIF)|(1<<WDIE)|(1<<WDP3)|(1<<WDP0);sei();}int main(){PortInit();WDT_Init();while(1){sleep_power();//Some Actions to be performedfor(int i=0;i<5;i++){PORTD|=(1<<PD6);_delay_ms(20);PORTD&=~(1<<PD6);_delay_ms(500);}}}while we run the above code we could see that it takes 1 micro ampire in sleep and 20 milli ampire when some action to be performed.basically our aim is to save maximum battery life.Do we have any other better option for the same.please help

author: vishal
author_rank: Regular Contributor
timestamp: August 25, 2017, 04:13:44 am
content: Hi ,I could make it working with following code.Here I tried with 8Sec and 4Sec.Code:#include<avr/io.h>#include<avr/interrupt.h>#include<avr/wdt.h>#include<util/delay.h>void PortInit(void){DDRD|=(1<<PD6);PORTD|=(1<<PD6);}void WDT_Init(void){cli();wdt_reset();WDTCSR=(1<<WDCE)|(1<<WDE);//WDTCSR=(1<<WDIF)|(1<<WDIE)|(1<<WDP3); //4SecWDTCSR=(1<<WDIF)|(1<<WDIE)|(1<<WDP3)|(1<<WDP0);//8Secsei();}ISR(WDT_vect){for(uint8_t i=0;i<4;i++){PORTD|=(1<<PD6);_delay_ms(100);PORTD&=~(1<<PD6);_delay_ms(100);}}int main(void){PortInit();WDT_Init();_delay_ms(100);while(1){for(int i=0;i<5;i++){PORTD|=(1<<PD6);_delay_ms(20);PORTD&=~(1<<PD6);_delay_ms(500);}PORTD|=(1<<PD6);}}Now I am trying to mkae it work for 6Sec.How can I achieve a 6sec using watchdog timer.

author: KL27x
author_rank: Super Contributor
timestamp: August 25, 2017, 04:23:35 am
content: U can make ur own post-postscaler; define a variable that is only going to be used/modified in the ISR. Increment it during the isr. Put the micro to sleep (and reset this counter to predetermined setting) when it rolls over? So something happens only every X times the wdt interrupt triggers.

author: Brumby
author_rank: Unknown
timestamp: August 25, 2017, 04:55:33 am
content: Quote from: floobydust on August 10, 2017, 04:10:46 amI also saw this and cringed.When an interrupt fires, it "interrupts" normal processing and dives off to the interrupt routine. When finished, execution reverts back to the point where processing was up to at the point of the interrupt ... so make it quick and simple.While theremaybe situations where you would want to do otherwise, the standard approach is to make the interrupt routineas short as possible. Putting a 2 second wait in there is just crazy.My typical interrupt routines have less than 5 instructions - and no loops. Increment a counter, set a flag - that sort of thing. Extended processing from an interrupt event occurs in the main logic. Doing too much in an interrupt is inviting problems, IMHO.

author: boffin
author_rank: Unknown
timestamp: August 25, 2017, 06:11:29 am
content: Quote from: vishal on August 25, 2017, 04:13:44 amYou simply make it go every second, and in your ISR (interrupt service routine) you increment a counter. Then in your main loop, if it's less than 6 you go back to sleep.something like thisISR {count++;}main {count = 0;while (count < 6) {sleep;}do stuff here;}