Author Topic: Watchdog Timer Interrupt not working  (Read 2810 times)

0 Members and 1 Guest are viewing this topic.

Offline vishalTopic starter

  • Regular Contributor
  • *
  • Posts: 102
  • Country: in
Watchdog Timer Interrupt not working
« on: August 09, 2017, 12:37:15 pm »
Hi
   I have written code to sleep a device using watchdog timer.The code is as follows:
Code: [Select]
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
 

Offline Yansi

  • Super Contributor
  • ***
  • Posts: 3893
  • Country: 00
  • STM32, STM8, AVR, 8051
Re: Watchdog Timer Interrupt not working
« Reply #1 on: August 09, 2017, 03:44:25 pm »
It would be helpful to provide thy type of the MCU next time. It might be obvious for some, but not for others!
 

Offline floobydust

  • Super Contributor
  • ***
  • Posts: 7429
  • Country: ca
Re: Watchdog Timer Interrupt not working
« Reply #2 on: August 10, 2017, 04:10:46 am »
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.
 

Offline KL27x

  • Super Contributor
  • ***
  • Posts: 4108
  • Country: us
Re: Watchdog Timer Interrupt not working
« Reply #3 on: August 10, 2017, 05:11:27 am »
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.
« Last Edit: August 10, 2017, 05:30:40 am by KL27x »
 

Offline vishalTopic starter

  • Regular Contributor
  • *
  • Posts: 102
  • Country: in
Re: Watchdog Timer Interrupt not working
« Reply #4 on: August 10, 2017, 05:40:51 am »
It would be helpful to provide thy type of the MCU next time. It might be obvious for some, but not for others!
I am using avr-atmega256rfr2
 

Offline KL27x

  • Super Contributor
  • ***
  • Posts: 4108
  • Country: us
Re: Watchdog Timer Interrupt not working
« Reply #5 on: August 10, 2017, 10:29:28 am »
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.
 

Offline vishalTopic starter

  • Regular Contributor
  • *
  • Posts: 102
  • Country: in
Re: Watchdog Timer Interrupt not working
« Reply #6 on: August 11, 2017, 03:14:26 am »
Well I have modified my code for avr-atmega256rfr2MCU as follows with sleep routine :
Code: [Select]
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 performed
   for(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
 

Offline vishalTopic starter

  • Regular Contributor
  • *
  • Posts: 102
  • Country: in
Re: Watchdog Timer Interrupt not working
« Reply #7 on: August 25, 2017, 04:13:44 am »
Hi ,I could make it working with following code.Here I tried with 8Sec  and 4Sec.
Code: [Select]
#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); //4Sec
WDTCSR=(1<<WDIF)|(1<<WDIE)|(1<<WDP3)|(1<<WDP0);//8Sec
sei();
}

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.
 

Offline KL27x

  • Super Contributor
  • ***
  • Posts: 4108
  • Country: us
Re: Watchdog Timer Interrupt not working
« Reply #8 on: August 25, 2017, 04:23:35 am »
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.
« Last Edit: August 25, 2017, 04:32:49 am by KL27x »
 

Offline Brumby

  • Supporter
  • ****
  • Posts: 12380
  • Country: au
Re: Watchdog Timer Interrupt not working
« Reply #9 on: August 25, 2017, 04:55:33 am »
You never wait for 2 seconds in the middle of an interrupt service routine.

I 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 there may be situations where you would want to do otherwise, the standard approach is to make the interrupt routine as 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.
 

Offline boffin

  • Supporter
  • ****
  • Posts: 1027
  • Country: ca
Re: Watchdog Timer Interrupt not working
« Reply #10 on: August 25, 2017, 06:11:29 am »
Hi ,I could make it working with following code.Here I tried with 8Sec  and 4Sec.

You 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 this

ISR {
  count++;
}

main {
  count = 0;
  while (count < 6) {
    sleep;
  }
  do stuff here;
}
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf