Pages: [1]   Go Down
Author Topic: ATmega328P: Watchdog timer stops program, but doesn't reset...  (Read 1482 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 38
Don't eat yellow snow.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all

I'm building a data logger using Seeeduino Stalker V2.3 and a GPRS V2.0 shield. It will be functioning at a remote location for very long(years, hopefully), so I don't want it to freeze up in the first week, and just stop working. I'm storing all data on an SD card, and I'm making it accessible via SMS, so an occasional reset won't hurt.

I want to use the built-in watchdog timer to reset it if the program freezes. As far as I understand it should work as follows (using the avr/wdt.h library):
You activate it with the "wdt_enable(CONST)" command in the setup. I used "wdt_enable(WDTO_8S)" for an 8 second watchdog timer.
After this the watchdog should regularly petted with the "wdt_reset()" command.
If the watchdog isn't petted within the specified time(in my case: 8 seconds), it bites, and resets the Stalker. This reset should have the same effect as pressing the reset button on the controller itself, causing the program to run from setup().

IMPORTANT: If my understanding of the watchdog timer is wrong, please correct it.

So if you look at my attached code, you will see this is what I have done. I activated the timer at the very top of my setup(), and I reset it in the function "stateTransitionMonitor", which is called at the top of loop(). Please note that I use a state machine architecture, and that I initialize the program to an error state only to demonstrate my problem. The idea is that it resets either when the error state is reached, or if it is stuck in any state other than _IDLE_ for too long.

If I run my code, the following happens:
The program gets through setup() fine, printing "Entering loop..." at it's end. Then it goes into stateTransitionMonitor(), where it prints "Watchdog missed" and "ERROR" for 8 seconds, just like it should.

Then it stops. Indefinitely. Which is wrong, right? It should be starting with setup() again, printing "Entering loop...", and repeating the events that happened just before.

So what's going wrong? How can I make it reset?

I googled this, and found slightly similar cases, but most of them had different hardware and solved their problems by burning a new bootloader. As an only slightly experienced Arduino enthusiast, I thought it might be wise to seek the forums advice before messing with the bootloader.

Thanks

* Logger_plus_gprs.ino (20.15 KB - downloaded 25 times.)
Logged

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 208
Posts: 12944
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


What is this gobbledygook....

Code:
... || ( millis() <= millisTimer && ( (millis() + millisTimer)%4294967295ul ) >= 60000ul ) ...
Logged

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 208
Posts: 12944
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


How does the board behave with a simple test case...

Code:
#include <avr/wdt.h> // watchdog timer

void setup( void )
{
  Serial.begin(9600); // Serial line is opened. Used mostly for testing.
  Serial.println( F( "Eight seconds and..." ) );
  wdt_enable(WDTO_8S); // we enable the watchdog timer to bite after 8 seconds
}

void loop( void )
{
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 38
Don't eat yellow snow.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi

I tested your code, and it only printed one line of "Eight seconds and...", and then froze. The same as my big sketch.

As for the gobbledygook: It is supposed to to use millis as a timer for 60 seconds before actually starting to neglect the watchdog, thus leaving me with a 68 second watchdog timer. But the error state in which the program is initialized bypasses this ( "...gobbledygook... || state == _ERROR_" ), so I don't think we need to worry about that right now. The only reason it looks a little big and scary is because I also catered for a millis rollover. Feel free to remove it.

Thanks so far :-)
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5536
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi

I tested your code, and it only printed one line of "Eight seconds and...", and then froze. The same as my big sketch.

It didn't freeze, it went to loop() (which doesn't print any messages).

You may have to clear the "WDRF" bit in MCUSR. You're supposed to check this bit in setup to find out if the reset was caused by the watchdog. Isn't cleared by RESET, you have to reset it manually before watchdog will work.
Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Offline Offline
Newbie
*
Karma: 0
Posts: 38
Don't eat yellow snow.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, the timer works now, and restarts everything every 8 seconds like it should. I used this code I got from http://www.fiz-ix.com/2012/11/low-power-arduino-using-the-watchdog-timer/

Code:
void watchdogOn() {
  
// Clear the reset flag, the WDRF bit (bit 3) of MCUSR.
MCUSR = MCUSR & B11110111;
  
// Set the WDCE bit (bit 4) and the WDE bit (bit 3)
// of WDTCSR. The WDCE bit must be set in order to
// change WDE or the watchdog prescalers. Setting the
// WDCE bit will allow updtaes to the prescalers and
// WDE for 4 clock cycles then it will be reset by
// hardware.
WDTCSR = WDTCSR | B00011000;

// Set the watchdog timeout prescaler value to 1024 K
// which will yeild a time-out interval of about 8.0 s.
WDTCSR = B00100001;

// Enable the watchdog timer interupt.
WDTCSR = WDTCSR | B01000000;
MCUSR = MCUSR & B11110111;

}

Now I'm just trying to come up with a way to pet the dog...

Thanks for the pointer, Coding Badly and fungus :-)
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 38
Don't eat yellow snow.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

For petting the dog, wdt_reset() works fine. Only the wdt_enable() function seems to have a problem. So I'm happy :-)
Logged

Pages: [1]   Go Up
Jump to: