Pages: [1]   Go Down
Author Topic: Reset via Watchdog  (Read 3421 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

I have a WiShield on a Garage Door Sensor/Opener that I am building.  Problem is that the WiShield seems to lose connectivity every so often.   The easiest solution is to do a reset, so I am using the watchdog to do a reset.  Problem is that the Arduino seems to hang in the bootloader (I would assume) and one of the LEDs on the board goes nuts.  I was going to Load LadyAda's bootloader to fix the problem, but before that is there another solution to this problem?

Thanks!
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 185
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi wyngnut,

you can also use the bootloader shipped with the Arduino (subfolder hardware\bootloaders\atmega), you just have to add the #define 'WATCHDOG_MODS' in the Makefile:
atmega328: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600  '-DWATCHDOG_MODS'

or for the ATmega168:
ng: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>1' '-DNUM_LED_FLASHES=3'  '-DWATCHDOG_MODS'

When WATCHDOG_MODS is set, the WDT will be disabled and if the WDT was the reason for the reset, the sketch will be started immediately.

To compile the bootloader yourself, you can make use the following script, but you have to adapt the path in the first line to your environment:
Code:
set BASEDIR=C:\arduino-0017\hardware
set DIRAVRUTIL=%BASEDIR%\tools\avr\utils\bin
set DIRAVRBIN=%BASEDIR%\tools\avr\bin
set DIRAVRAVR=%BASEDIR%\tools\avr\avr\bin
set DIRLIBEXEC=%BASEDIR%\tools\avr\libexec\gcc\avr\4.3.2
set OLDPATH=%PATH%
@path %DIRAVRUTIL%;%DIRAVRBIN%;%DIRAVRAVR%;%DIRLIBEXEC%;%PATH%
%DIRAVRUTIL%\make.exe ng
%DIRAVRUTIL%\make.exe atmega328
@path %OLDPATH%

  MikeT
« Last Edit: October 10, 2009, 10:34:28 am by nospam2000 » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry to dredge this one up again, but I have tried to compile a new bootloader so I can use a watchdog timer.  Not sure why this isn't setup to begin with.  

Does someone have a mega (1280) bootloader hex file that is "doggie-friendly"?

I tried your script and it keeps giving me:
C:\arduino-0017>C:\arduino-0017\hardware\tools\avr\utils\bin\make.exe mega
make: *** No rule to make target `mega'.  Stop.

If I launch the same batch file from the \hardware\bootloaders\atmega directory, I get something slightly different:

C:\arduino-0017\hardware\bootloaders\atmega>C:\arduino-0017\hardware\tools\avr\u
tils\bin\make.exe -r mega
make: Nothing to be done for `mega'.

Thank you for any help you can give me!
-Damon
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 29
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just try a make clean first... this deletes the already compiled objects.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 29
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
When WATCHDOG_MODS is set, the WDT will be disabled and if the WDT was the reason for the reset, the sketch will be started immediately.

Can i also detect this in my sketch? I mean can I find out if the reset was due to the wdt timeout? Or would this need additional changes in the bootloader?

Thanks in advance!
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 185
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Phlogi,

Quote
Can i also detect this in my sketch? I mean can I find out if the reset was due to the wdt timeout? Or would this need additional changes in the bootloader?

It needs some changes in the bootloader.

Original bootloader code always clears MCUSR:
Code:
/* main program starts here */
int main(void)
{
      uint8_t ch,ch2;
      uint16_t w;

#ifdef WATCHDOG_MODS
      ch = MCUSR;
      MCUSR = 0;

      WDTCSR |= _BV(WDCE) | _BV(WDE);
      WDTCSR = 0;

      // Check if the WDT was used to reset, in which case we dont bootload and skip straight to the code. woot.
      if (! (ch &  _BV(EXTRF))) // if its a not an external reset...
            app_start();  // skip bootloader
#else


My changed code which leaves MCUSR intact, so you can check it in your sketch. To avoid a lockup (upload not possible when reset is caused by WDT and sketch doesn't clean the WDT flag), MCUSR is cleaned when the Arduino is reset via the reset button, so the boot loader is not skipped at the next reset.
Code:
/* main program starts here */
int main(void)
{
      uint8_t ch,ch2;
      uint16_t w;

#ifdef WATCHDOG_MODS
      ch = MCUSR;
      WDTCSR |= _BV(WDCE) | _BV(WDE);

      // Check if the WDT was used to reset, in which case we dont bootload and skip straight to the code. woot.
      if (ch &  _BV(EXTRF)) // if its an external reset...
            MCUSR = 0; // clear WDRF when reset by reset button
      else
            app_start();  // skip bootloader
#else

In your sketch you can check "MCUSR & _BV(WDRF)" to see whether the WDT caused the reset. After this, you must reset WDRF MCUSR & _BV(WDRF):

Code:
void setup()
{
if(MCUSR & _BV(WDRF))
{
  MCUSR = 0;

  // handle the WDT reset here
}

I didn't test or even compile this, yet.

  MikeT
Logged

Pages: [1]   Go Up
Jump to: