Forum Rule: Always post complete source code & details to reproduce any issue!
Page 2 of 3 FirstFirst 1 2 3 LastLast
Results 26 to 50 of 55

Thread: Teensy 3.0 Watchdog Timer

  1. #26
    Member
    Join Date
    Oct 2012
    Location
    Portland, OR
    Posts
    36
    Hi Martinayotte - do you mind sharing your watchdog code? What Froeber describes in post #24 is exactly what I'm trying to achieve.

    A very simple working code example would be extremely helpful that illustrates how to use the watchdog feature in this manner.

  2. #27
    Hi RBrockman,
    I've simply added the following startup_early_hook() and then call WatchdogReset() function periodically to avoid watchdog restarts.

    #ifdef __cplusplus
    extern "C" {
    #endif
    void startup_early_hook() {
    WDOG_TOVALL = 1000; // The next 2 lines sets the time-out value. This is the value that the watchdog timer compa
    WDOG_TOVALH = 1;
    WDOG_PRESC = 0; // prescaler
    WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN); // Enable WDG
    }
    #ifdef __cplusplus
    }
    #endif

    void WatchdogReset()
    {
    // use the following 4 lines to kick the dog
    noInterrupts();
    WDOG_REFRESH = 0xA602;
    WDOG_REFRESH = 0xB480;
    interrupts();
    // if you don't refresh the watchdog timer before it runs out, the system will be rebooted
    delay(1); // the smallest delay needed between each refresh is 1ms. anything faster and it will also reboot.
    }

  3. #28
    Member
    Join Date
    Sep 2014
    Location
    California
    Posts
    22
    Would watchdog make more sense like this?

    I really dislike delay() and it's pretty easy on a Teensy3 to set up a millisecond clock so you know when it's time to kick the dog. I've set it so it resets the watchdog every 3 milliseconds. You need to make it at least 2 as even set to 2 it can be called in 1.001 milliseconds or so if everything adds up wrong.

    And even if you don't use this for a watchdog, Timer1 and Timer3 are really useful for keeping track of time if you need that.

    Code:
    unsigned char _watchTheDog  // how many milliseconds since we last reset the watchdog
    void Setup()
    {
        Timer3.initialize(1000000 / 1000); // set to fire every millisecond. initialize takes microseconds as an argument.
        Timer3.attachInterrupt(WatchTheDog  ); // call WatchTheDog  every millisecond
    }
    
    void WatchTheDog ()
    {
       _watchTheDog+= 1
    }
    void WatchdogReset()
    {
      if (_watchTheDog> 2){
        // use the following 4 lines to kick the dog
         noInterrupts();
         WDOG_REFRESH = 0xA602;
         WDOG_REFRESH = 0xB480;
         interrupts();
         _watchTheDog = 0
        }
     }

  4. #29
    Member
    Join Date
    Oct 2012
    Location
    Portland, OR
    Posts
    36
    What are the units of these two values and how do they translate into time?

    WDOG_TOVALL = 1000; // The next 2 lines sets the time-out value.
    WDOG_TOVALH = 1;

    I've implemented this and it is resetting about every 60 seconds with these values above. I want to set this to a value less than 1 second - actually in microseconds if possible.

    Is there a minimum amount of elapsed time required between calls to kick the dog?
    Last edited by rbrockman; 09-18-2014 at 10:06 PM.

  5. #30
    Member
    Join Date
    Oct 2012
    Location
    Portland, OR
    Posts
    36
    Thanks Martinayotte!

    How do you start/enable the watchdog after a period of time in your code? Like after completing setup()

  6. #31
    Member
    Join Date
    Oct 2012
    Location
    Portland, OR
    Posts
    36
    Please provide input on the code below. There are still a few watchdog items here I do not have an understanding of as of yet, but the code seems to be more or less working.

    Goal: Start a watchdog when the Teensy first runs with a long timeout value, then after setup() change the timeout to a much smaller timeout period. Kick the dog more often than the timeout period.



    Code:
    #ifdef __cplusplus
    extern "C" {
    #endif
    void startup_early_hook() {
    WDOG_TOVALL = 2000; // The next 2 lines sets the time-out value. This is the value that the watchdog timer compares itself to
    WDOG_TOVALH = 0;
    WDOG_PRESC = 0; // prescaler
    WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN); // Enable WDG
    }
    #ifdef __cplusplus
    }
    #endif
    
    void setup(){
      WDOG_UNLOCK = WDOG_UNLOCK_SEQ1;
      WDOG_UNLOCK = WDOG_UNLOCK_SEQ2;
      WDOG_TOVALL = 10; // The next 2 lines sets the time-out value. This is the value that the watchdog timer compares itself to
      WDOG_TOVALH = 0;
      WDOG_PRESC = 0; // prescaler
      WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN); // Enable WDG
    }
    
    
    void loop(){
      WatchdogReset();
    }
    
    
    void WatchdogReset(){
      static elapsedMillis watchdogTimer;	
     
      if (watchdogTimer > 5){
        watchdogTimer = 0;
    		
        noInterrupts();
        WDOG_REFRESH = 0xA602;
        WDOG_REFRESH = 0xB480;
        interrupts();
      }
    }

  7. #32
    Junior Member
    Join Date
    Dec 2013
    Posts
    8
    Hello forum,
    as far as I see, you use different approaches to simulate a watchdog behavior.
    I am not to sure about the work of an interrupt watchdog.
    Does it only work if the teensy hangs due to infinite (or to long) loops
    or does it also works, if the teensy hangs for no obvios reason.

    I use a teensy3.1 with an MFRC522 door reader and there are no "bad loops" inside.
    The program works fine for days, sometimes weeks, sometimes months, but
    somtimes it just stops working (and I have to go to that place an open the door with a key...)
    When switching the teensy off and on again, everything is fine and it starts working for the next
    unsure period of time.

    A watchdog would be great, but would an interrupt watchdog prevent the teensy from these
    types of chrashes?

    If yes, which is the best approach for this?
    I would love to keep the .c file unchanged...

    If no, what would you reccomend? An oldfashioned 555 circuit?

    Thanks for your help
    Roland

  8. #33
    Junior Member
    Join Date
    Aug 2015
    Posts
    1
    Hello duff
    Great and working code, but where in Your code is definition of 6 second delay ?
    Max

  9. #34
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,828
    The idea of a watchdog is that your app will "and" together several conditions and states to know whether to reset the watchdog timer.

  10. #35
    Senior Member Epyon's Avatar
    Join Date
    Apr 2013
    Location
    Belgium
    Posts
    443
    There are a number of external watchdog ICs, with programmable or fixed reset windows. I personally have used the ADM706SANZ with Teensy, which gives you a 1.6s reset window. You could also use a STM6321S or TPS3828-33DBVT.

    I've also made a simple external watchdog with programmable delay by using a NE556 timer IC. I can share the schematic and workings if you like.

  11. #36
    Senior Member duff's Avatar
    Join Date
    Jan 2013
    Location
    Las Vegas
    Posts
    1,023
    Quote Originally Posted by Max View Post
    Hello duff
    Great and working code, but where in Your code is definition of 6 second delay ?
    Max
    I haven't actually used the watchdog since posting that so I'll have to look at it again and get back to you.

  12. #37
    Junior Member
    Join Date
    Dec 2015
    Posts
    1
    Quote Originally Posted by rbrockman View Post
    What are the units of these two values and how do they translate into time?

    WDOG_TOVALL = 1000; // The next 2 lines sets the time-out value.
    WDOG_TOVALH = 1;

    I've implemented this and it is resetting about every 60 seconds with these values above. I want to set this to a value less than 1 second - actually in microseconds if possible.

    Is there a minimum amount of elapsed time required between calls to kick the dog?
    WDOG_TOVALH and WDOG_TOVALL are the high and low, respectively, registers for the 32-bit timeout value of the watchdog timer. This must be at least 4 cycles. WDOG_PRESC is the 3 bit, at bit 8-10 for some reason, prescaler which divides the watchdog clock by 1 + the three bit prescale value. The watchdog clock is running at 1kHz as far as I can tell. So, to get a WDT of 3 seconds you'd use WDOG_TOVALH = 0, WDOG_TOVALL = 3000 and WDOG_PRESC = 0.

    With your values there of VALH = 1 and VALL = 1000 you should get a WDT of about 1<<16+1000 = 66536 ms which from what you say sounds reasonable.

    To sum up, the final WDT in milliseconds will be (VALH<<16 + VALL) * (1 + PRESC >> 8).

  13. #38
    Junior Member
    Join Date
    Mar 2016
    Posts
    3

    Watchdog stopped working with Teensy V1.27 - solved

    Thanks to everyone that contributed to this topic. I had a strange experience with the watchdog today, and am posting in the hope that it helps someone else. I've had the watchdog working well for quite some time with Arduino 1.6.5-r2 and Teensyduino V1.24, but when I transitioned to Arduino 1.6.5-r5 and Teensyduino V1.27, the sketches with watchdog would just hang. I found out that the watchdog was what was causing the problem - commenting out startup_early_hook() would get it working again. I then found that I had to make the watchdog period longer in order to get the sketch working again. My guess is that the new Teensyduino code takes longer to get to setup() than the old one. I have the watchdog reset as the first statement in setup(), and I found that I had to increase WDOG_TOVALL to 259 in order to get it to work OK. 258 causes it to hang. I'm guessing from the post above, that this is 259ms watchdog. I was trying to minimize this, so that if the program does ever hang, the watchdog would reset it as quickly as possible. I'm using "72MHz Optimized" as the CPU speed selection in the Arduino IDE.

    #ifdef __cplusplus
    extern "C" {
    #endif
    void startup_early_hook() {
    WDOG_TOVALL = 259; // The next 2 lines sets the time-out value. This is the value that the watchdog timer compa
    WDOG_TOVALH = 0;
    WDOG_PRESC = 0; // prescaler
    WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN); // Enable WDG
    }
    #ifdef __cplusplus
    }
    #endif

  14. #39
    Does this work on teensy 3.6?

  15. #40
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,423
    It should work on 3.6. The watchdog hardware is identical. Please give it a try and let us know if it works for you?

  16. #41
    No problem. I am a bit of a noob in programming so ppeas can you tell me what code to use? Post #31?
    Thank you

  17. #42
    tried the watchdog today... It works but like someone else said i can't figure out the time interval.. i used this code for testing
    Code:
    #ifdef __cplusplus
    extern "C" {
    #endif
    void startup_early_hook() {
    WDOG_TOVALL = 3000;
    WDOG_TOVALH = 0;
    WDOG_PRESC = 0;
    WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN); 
    }
    #ifdef __cplusplus
    }
    #endif
     
    int led = 13;
    
    void setup() {
      Serial.begin(9600);                
      pinMode(led, OUTPUT);
      Serial.println("Setup");     
    }
    
    void loop() {
      WatchdogReset();
      Serial.println("Begin");
      delay(2608);
    }
    void WatchdogReset(){
      static elapsedMillis watchdogTimer;  
     
      if (watchdogTimer > 5){
        watchdogTimer = 0;
        
        noInterrupts();
        WDOG_REFRESH = 0xA602;
        WDOG_REFRESH = 0xB480;
        interrupts();
      }
    }
    when the delay(2608); the sketch runs but when i use delay(2609); the watchdog kicks in. I expected a 3 sec reset time... But all and all this works for me .. I don't need accurate timing, just a reset if the code hangs
    Thank you!

  18. #43
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,604
    Quote Originally Posted by Tady View Post
    when the delay(2608); the sketch runs but when i use delay(2609); the watchdog kicks in. I expected a 3 sec reset time... But all and all this works for me .. I don't need accurate timing, just a reset if the code hangs
    Thank you!
    If your teensy 3* watchdog timer is configured to use the LPO, that internal oscillator is spec'd only at 10% accuracy (100,000 ppm). Using the LPTMR, i've measured the accuracy of LPO on various teensy's (anecdotal results at https://github.com/manitou48/crystal...r/crystals.txt). I tested my T3.2 with LPO accuracy of 18934 ppm with the watchdog timer. I modified the BasicUsage example from https://github.com/adafruit/Adafruit_SleepyDog to adjust the delay before "kicking the watchdog" in loop().
    Code:
      if (micros() -t > 3927000) {
        Watchdog.reset();
        t=micros();
        Serial.println("running");
      }
    If i wait longer the 3.927 seconds, the teensy resets. if i wait less than 3.926 secs to kick the dog, then reset is avoided. That timing roughly agrees with measured LPO accuracy for that T3.2. The LPO accuaracy will vary from chip to chip and with temperature.

    2nd test: T3.6 (LPO drift of -3232 ppm). If wait less than 4.011 secs, then reset is avoided.
    Last edited by manitou; 04-06-2017 at 12:42 PM.

  19. #44
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,604
    Quote Originally Posted by duff View Post
    Here is more portable version of your watchdog code, no need to edit any core files but instead use the startup_early_hook. It also uses the interval timer to kick the dog.

    Code:
    #define RCM_SRS0_WAKEUP                     0x01
    #define RCM_SRS0_LVD                        0x02
    #define RCM_SRS0_LOC                        0x04
    #define RCM_SRS0_LOL                        0x08
    #define RCM_SRS0_WDOG                       0x20
    #define RCM_SRS0_PIN                        0x40
    #define RCM_SRS0_POR                        0x80
    
    #define RCM_SRS1_LOCKUP                     0x02
    #define RCM_SRS1_SW                         0x04
    #define RCM_SRS1_MDM_AP                     0x08
    #define RCM_SRS1_SACKERR                    0x20
    
    IntervalTimer wdTimer;
    
    void setup() {
      pinMode(LED_BUILTIN, OUTPUT);
      digitalWrite(LED_BUILTIN, HIGH);
      delay(100);
      digitalWrite(LED_BUILTIN, LOW);
      // You have about 6 secs to open the serial monitor before a watchdog reset
      while(!Serial);
      delay(100);
      printResetType();
      wdTimer.begin(KickDog, 500000); // kick the dog every 500msec
    }
    
    void loop() {
      Serial.println("doing loop things...");
      delay(100);
    }
    
    void KickDog() {
      Serial.println("Kicking the dog!");
      digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
      noInterrupts();
      WDOG_REFRESH = 0xA602;
      WDOG_REFRESH = 0xB480;
      interrupts();
    }
    
    void printResetType() {
        if (RCM_SRS1 & RCM_SRS1_SACKERR)   Serial.println("[RCM_SRS1] - Stop Mode Acknowledge Error Reset");
        if (RCM_SRS1 & RCM_SRS1_MDM_AP)    Serial.println("[RCM_SRS1] - MDM-AP Reset");
        if (RCM_SRS1 & RCM_SRS1_SW)        Serial.println("[RCM_SRS1] - Software Reset");
        if (RCM_SRS1 & RCM_SRS1_LOCKUP)    Serial.println("[RCM_SRS1] - Core Lockup Event Reset");
        if (RCM_SRS0 & RCM_SRS0_POR)       Serial.println("[RCM_SRS0] - Power-on Reset");
        if (RCM_SRS0 & RCM_SRS0_PIN)       Serial.println("[RCM_SRS0] - External Pin Reset");
        if (RCM_SRS0 & RCM_SRS0_WDOG)      Serial.println("[RCM_SRS0] - Watchdog(COP) Reset");
        if (RCM_SRS0 & RCM_SRS0_LOC)       Serial.println("[RCM_SRS0] - Loss of External Clock Reset");
        if (RCM_SRS0 & RCM_SRS0_LOL)       Serial.println("[RCM_SRS0] - Loss of Lock in PLL Reset");
        if (RCM_SRS0 & RCM_SRS0_LVD)       Serial.println("[RCM_SRS0] - Low-voltage Detect Reset");
    }
    
    #ifdef __cplusplus
    extern "C" {
    #endif
      void startup_early_hook() {
        WDOG_TOVALL = (1000); // The next 2 lines sets the time-out value. This is the value that the watchdog timer compare itself to.
        WDOG_TOVALH = 0;
        WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN | WDOG_STCTRLH_WAITEN | WDOG_STCTRLH_STOPEN); // Enable WDG
        //WDOG_PRESC = 0; // prescaler 
      }
    #ifdef __cplusplus
    }
    #endif
    Re: startup_early_hook()
    i get a compile error if i try to compile Duff's watchdog sketch in post #21 ?? what is proper way to override weak startup_early hook?
    Code:
    sketch_apr09a: In function 'void startup_early_hook()':
    sketch_apr09a:58: error: previous declaration of 'void startup_early_hook()' with 'C++' linkage
       void startup_early_hook() {
          ^
    sketch_apr09a:58: error: conflicts with new declaration with 'C' linkage
       void startup_early_hook() {
                               ^
    previous declaration of 'void startup_early_hook()' with 'C++' linkage
    i'm using 1.8.1 with 1.35

  20. #45
    Senior Member
    Join Date
    Jan 2013
    Posts
    843
    Quote Originally Posted by manitou View Post
    Re: startup_early_hook()
    i get a compile error if i try to compile Duff's watchdog sketch in post #21 ?? what is proper way to override weak startup_early hook?
    Code:
    sketch_apr09a: In function 'void startup_early_hook()':
    sketch_apr09a:58: error: previous declaration of 'void startup_early_hook()' with 'C++' linkage
       void startup_early_hook() {
          ^
    sketch_apr09a:58: error: conflicts with new declaration with 'C' linkage
       void startup_early_hook() {
                               ^
    previous declaration of 'void startup_early_hook()' with 'C++' linkage
    i'm using 1.8.1 with 1.35
    The Arduino preprocessor is a buggy piece of <CENSORED>. You need an explicit forward declaration:

    Code:
    #ifdef __cplusplus
    extern "C" { void startup_early_hook(); }
    extern "C" {
    #endif
      void startup_early_hook() {
        WDOG_TOVALL = (1000); // The next 2 lines sets the time-out value. This is the value that the watchdog timer compare itself to.
        WDOG_TOVALH = 0;
        WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN | WDOG_STCTRLH_WAITEN | WDOG_STCTRLH_STOPEN); // Enable WDG
        //WDOG_PRESC = 0; // prescaler 
      }
    #ifdef __cplusplus
    }

  21. #46
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,604
    Quote Originally Posted by tni View Post
    The Arduino preprocessor is a buggy piece of <CENSORED>. You need an explicit forward declaration:
    Thanks! like I would have guessed that.

    Here is a variation on Duff's sketch in the spirit of SleepyDog lib BasicUsage example that kicks the watchdog a few times and then lets teensy 3* reset
    https://github.com/manitou48/teensy3...r/wdogduff.ino

  22. #47
    Junior Member
    Join Date
    Jul 2017
    Posts
    2
    Hello, I have followed this thread and it is confusing. Is there a final answer on how to implement a watchdog on teensy 3.2 ?

  23. #48
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,604
    Quote Originally Posted by trichins View Post
    Hello, I have followed this thread and it is confusing. Is there a final answer on how to implement a watchdog on teensy 3.2 ?
    Did you try the wdogduff.ino sketch in post #46 ?

  24. #49
    Junior Member
    Join Date
    Jul 2017
    Posts
    2
    Quote Originally Posted by manitou View Post
    Did you try the wdogduff.ino sketch in post #46 ?
    Thanks, that seems to summarize what has been posted. I will try it

  25. #50
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,423
    Some time ago I ported Adafruit's SleepyDog library. So if you'd like to avoid the complexity of directly accessing the watchdog, just use that library. Try it's BasicUsage example to get started.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •