Go Down

Topic: Reset via Watchdog (Read 5135 times) previous topic - next topic

wyngnut

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!

Mike T

#1
Oct 10, 2009, 05:24 pm Last Edit: Oct 10, 2009, 05:34 pm by nospam2000 Reason: 1
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: [Select]
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

enthalpy

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

Phlogi

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

Phlogi

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!

Mike T

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: [Select]
/* 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: [Select]

/* 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: [Select]
void setup()
{
if(MCUSR & _BV(WDRF))
{
 MCUSR = 0;

 // handle the WDT reset here
}


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

 MikeT

Go Up