Skip to main content

You are here

WDT question jeenode

21 posts / 0 new
Last post
jm_wsb
WDT question jeenode

Hello,

I have 2 jeenode v6 and v5 where the WDT does not function.
I run the following sketch:

#include <JeeLib.h>
#include <avr/wdt.h>
#define debug 1
char msg[60];
void writeLog(char* msgl)
{
if (debug == 1) {Serial.println(msgl);delay(3);} //else sometimes no nextline is given
}
void setup()
{

wdt_reset(); // First thing, turn it off
wdt_disable();
if (debug == 1) {Serial.begin(115200);}
snprintf(msg,sizeof msg, "setup()"); writeLog(msg);
snprintf(msg,sizeof msg, "Jeenode booted"); writeLog(msg);
wdt_enable(WDTO_8S); // enable watchdogtimer
}
void loop()
{ snprintf(msg,sizeof msg, "wait 5s"); writeLog(msg);
delay(5000);
wdt_reset();
snprintf(msg,sizeof msg, "wait 5s"); writeLog(msg);
delay(5000);
wdt_reset();
snprintf(msg,sizeof msg, "wait 5s"); writeLog(msg);
delay(5000);
wdt_reset();
snprintf(msg,sizeof msg, "wait 20s; WDT must be resetted;"); writeLog(msg);
snprintf(msg,sizeof msg, " + 2 sec;"); writeLog(msg);
delay(2000);
snprintf(msg,sizeof msg, " 2 + 2 sec;"); writeLog(msg);
delay(2000);
snprintf(msg,sizeof msg, " 4 + 2 sec;"); writeLog(msg);
delay(2000);
snprintf(msg,sizeof msg, " 6 + 2 sec;"); writeLog(msg);
delay(2000);
snprintf(msg,sizeof msg, " 8 + 2 sec;"); writeLog(msg);
delay(2000);
snprintf(msg,sizeof msg, " 10 + 2 sec;"); writeLog(msg);
delay(2000);
wdt_reset();
}

and it give the following output:
setup()
Jeenode booted
wait 5s
wait 5s
wait 5s
wait 20s; WDT must be resetted;
+ 2 sec;
2 + 2 sec;
4 + 2 sec;
6 + 2 sec;
8 + 2 sec;

So the node hangs after 8 seconds.

Any idea why ? Has it something to do with the bootloader ?

Thanks in advance,
Jeroen

JohnO

I have used WDT without problems, here are some code snips, this first one sets up the WDT:

// //initialize watchdog void WDT_Init(void) { //disable interrupts cli(); //reset watchdog //wdt_reset(); //set up WDT interrupt WDTCSR = (1<<WDCE)|(1<<WDE); //Start watchdog timer with 8s prescaller WDTCSR = (1<<WDIE)|(1<<WDE)|(1<<WDP0)|(1<<WDP3); //Enable global interrupts sei(); }

I have a watchdog interrupt service routine below:

//Watchdog timeout ISR ISR (WDT_vect) { pseudoTime = pseudoTime + 8000 - 22; /* 8 seconds between watchdog interrupts */ - /* Fine Tuning */ bitSet (WDTCSR, WDIE); WDTwake = true; }

I enable the watchdog in my setup process:

WDT_Init(); // Initialise WatchDog mechanism sei(); // Just to be sure

I don't recall where I got the above code from - probably pinched from @jcw, I hope this helps.

UPDATE: The above are for the Tiny84 processor - probably need a tweak for the ATMEGA328P.

jm_wsb

Hi JohnO,

I've tried your code and had exactly the same problem.

Any other idea ?

Thanks in advance,
Jeroen

JohnO

Hi Jeroen,

Can you post your latest failing sketch as an attachment?

jm_wsb

Hi JohnO,

sketch attached.

thanks.

AttachmentSize
testWDT.txt1.86 KB
JohnO

@Jeroen, what would like like to happen when the WDT triggers. The code I snipped for you (Tiny84 processor) is setup to only enter an interrupt service routine and then return to the code after the point where the interrupt occurred. Other options are only to reset the node and I think the third is to do both actions. Page 58 in the ATMega328P data sheet covers the options and which registers to set for which actions.

If you want to test that the WDT interrupt routine is entered you could set a volatile global flag to a value inside the 'ISR (WDT_vect)' procedure and then test the value of it in the loop procedure.

jm_wsb

Hi JohnO,

I understand what you are doing in your code, but why does the jeenode hangs after 8 sec. As you said, it should return to the main loop after entering the WDT interrupt routine 'ISR (WDT_vect)'.

Thanks again.

JohnO

I have reproduce the problem you are seeing. When I remove:

// wdt_enable(WDTO_8S); // enable watchdogtimer

things work properly. The snippets I supplied do the full setup and I think the wdt_enable library call upsets things - I don't know why.

jm_wsb

Hi JohnO,

you rock !! awesome.

Can you help me to set the right register to enable the ISR (works as in your sketch) but also do reset the arduino ? As I read the datasheet: WDTCSR = (1<<WDCE)|(1<<WDE); WDTCSR = (1<<WDIE)|(1<<WDE)|(1<<WDP0)|(1<<WDP3); should do it not ? If WDE and WDIE = 1 than interrupt + system reset (see table 10-2) ?

Thanks again.

JohnO

Yes you are right and it is already enabled. Now I look at my code and the data sheet again. Against the datasheet recommendation I have 'bitSet (WDTCSR, WDIE)' inside the interrupt routine. If you move this instruction to your main code you will have both mechanisms working. I think the datasheet says that if WDIE is not set before the WDT interrupt occurs then the interrupt will cause an immediate reset.

For my code only I should remove 'bitSet (WDTCSR, WDIE)' from my interrupt routine and also change my setup to leave WDE with a value of 0, disabling the reset function.

jm_wsb

Hi JohnO,

I've tried your suggestions, but still does not reset. Strange.

Jeroen.

JohnO

Sorry, I am being rather opaque today. Using the 'bitSet (WDTCSR, WDIE)' should hold off the reset but failing to set before the next WDT interrupt it will cause a reset.

Or have you tried that and it doesn't - if so, can you post your current sketch as an attachment?

jm_wsb

I've tried it. When I don't set the WDIE bit anyware, it runs the ISR routine once (without reset the system) and then continues the mail loop (where it entered the ISR). The second time when goiing over the 8 sec it hangs.

output:
setup()
Jeenode booted
wait 5s
wait 5s
wait 5s
wait 20s; WDT must be resetted;
0 + 2 sec;
2 + 2 sec;
4 + 2 sec;
6 + 2 sec;
8 + 2 sec;
ISR timeout WDT
10 + 2 sec;
wait 5s
wait 5s
wait 5s
wait 20s; WDT must be resetted;
0 + 2 sec;
2 + 2 sec;
4 + 2 sec;
6 + 2 sec;
8 + 2 sec;

Sketch atteched testWDT2.txt

It seems when the jeenode hangs it should reset. It was the same with my Original sketch, without your code (attachement: testWDTorig.txt).

Are you sure it isn't a problem of the bootloader ? Can you try my Original sketch with your jeenode ? Is it resetting or does it hang.

Thanks a lot !Jeroen.

AttachmentSize
testWDT2.txt2 KB
testWDTorig.txt1.35 KB
JohnO

I haven't tried it yet. Before I do that I think we need to rework the interrupt routine. In my opinion

"snprintf(msg,sizeof msg, "ISR timeout WDT"); writeLog(msg);"

should not be in the interrupt routine as I suspect it uses interrupts itself. While handling an interrupt other interrupts are to some extent held pending until the first interrupt routine exits and returns control. If you want to know that the interrupt routine has been entered set a global volatile flag and then test it or perhaps switch an LED on and then off:

LED1 = !LED1; // Toggle digitalWrite(AIO1, LED1);
jm_wsb

JohnO, you've got a point. Indeed you should never use interupts (alse serial) in other interrupt routines.

I removed it, but still the same problem. The jeenode hangs instead of resetting.

JohnO

Odd as I'm seeing a reset:

setup() Jeenode booted wait 5s wait 5s wait 5s wait 20s; WDT must be resetted; 0 + 2 sec; 2 + 2 sec; 4 + 2 sec; 6 + 2 sec; 8 + 2 sec; 10 + 2 sec; wait 5s wait 5s wait 5s wait 20s; WDT must be resetted; 0 + 2 sec; 2 + 2 sec; 4 + 2 sec; 6 + 2 sec; 8 + 2 sec; setup() Jeenode booted wait 5s wait 5s wait 5s wait 20s; WDT must be resetted; 0 + 2 sec; 2 + 2 sec; 4 + 2 sec; 6 + 2 sec; 8 + 2 sec; 10 + 2 sec; wait 5s wait 5s wait 5s wait 20s; WDT must be resetted; 0 + 2 sec; 2 + 2 sec; 4 + 2 sec; 6 + 2 sec; 8 + 2 sec; setup() Jeenode booted wait 5s

The code change I made is below:

ISR (WDT_vect) { //int pseudoTime = pseudoTime + 8000 - 22; /* 8 seconds between watchdog interrupts */ - /* Fine Tuning */ //bitSet (WDTCSR, WDIE); boolean WDTwake = true; // snprintf(msg,sizeof msg, "ISR timeout WDT"); writeLog(msg); }
JohnO

I have Uno loaded - I also changed the serial speed to 57600 just to be lazy.

jm_wsb

Done exactely the same as you (code changed in ISR + serial on 57600). The only difference that my jeenode v6 can't use the Uno board to load the sketch. I must use Arduino Duemi.. w/Atmega328.

So I still suspect the bootloader. As I am following the post from JC for 2 years, I remember he wrote something about loadting with opti bootloader instead of the default arduino.

JohnO

Looks like you had it pegged from the start. Are you running Arduino 1.0.1 ? Do you have kit to update the boot loader?

Perhaps: http://jeelabs.org/2011/05/17/switching-to-optiboot/

jm_wsb

Hi JohnO, thanks for the correct post.

I've flashed the bootloader with the standard isprepair2 sketch (the isprepair failed to compile)

and PROBLEM SOLVED. Also works with the Original script (a bit simpeler than your code)

Thanks again. I will change on all my jeenodes the bootloader.

JohnO

Excellent.

Premium Drupal Themes by Adaptivethemes