WDT and interrupt for ATtiny/Arduino...

Go To Last Post
22 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello to all!

 

I am coming back to the forum, because I would like to add the WDT to the code in oneofmy previous posrs due to the quetiins of stability issues! See the post#54

 

I am not sure how to exactly use the WDT. For example, I would like the WDT to fire every min or so, not 8sec, which is factory max. But more importantly, I am not sure how to avoid most of the stuff in the setup after the WDT reset. For example, I would only need to use one method from there instead of the whole setup function... 

 

Anybody? Is there a way to actually do this? And, most importantly how to even consider the WDT in this example, because, if the led is turned ON it should not be turned OFF due to the WDT, btw is this even possible?

 

Best.

PS I am now writing like you, WDT means watch dog timer, which you all probably know :P

This topic has a solution.

Bravo!!!

Last Edited: Thu. Aug 9, 2018 - 12:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As seen here, many AVRs can go up to 8 seconds for WDT:

 

https://www.nongnu.org/avr-libc/...

 

That manual does note that the 8 second option is only available for:

This is only available on the ATtiny2313, ATtiny24, ATtiny44, ATtiny84, ATtiny84A, ATtiny25, ATtiny45, ATtiny85, ATtiny261, ATtiny461, ATtiny861, ATmega48, ATmega48A, ATmega48PA, ATmega88, ATmega168, ATmega48P, ATmega88P, ATmega168P, ATmega328P, ATmega164P, ATmega324P, ATmega644P, ATmega644, ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561, ATmega8HVA, ATmega16HVA, ATmega32HVB, ATmega406, ATmega1284P, ATmega2564RFR2, ATmega256RFR2, ATmega1284RFR2, ATmega128RFR2, ATmega644RFR2, ATmega64RFR2 AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316, AT90PWM81, AT90PWM161, AT90USB82, AT90USB162, AT90USB646, AT90USB647, AT90USB1286, AT90USB1287, ATtiny48, ATtiny88, ATxmega16a4u, ATxmega32a4u, ATxmega16c4, ATxmega32c4, ATxmega128c3, ATxmega192c3, ATxmega256c3.

Do note however that generally WDT is not something you can "bolt on" to a project as an afterthought. It usually has to be "designed in" from the start so as you write the code you analyse all potential paths of execution and ensure that non might ever exceed the WDT period or, if they will, that regular WDRs are performed during the long work.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
As seen here, many AVRs can go up to 8 seconds for WDT: https://www.nongnu.org/avr-libc/... That manual does note that the 8 second option is only available for: ...

 

Now, that information seems to be >>for a particular toolchain<<.  And then would only apply to that toolchain's facilities, and not the AVR itself.

 

Going through the list is a bit daunting -- "spot the difference".  Tiny13A has 8 second option.  As does Tiny13.  Tiny48 family as well.  Tiny1634. 

 

Knee-jerk is to say "the list hasn't been updated".  But then what about e.g. Tiny13 and 13A?

 

True, some models only reach to two seconds.  Not the models in the original thread title.  Do you want me to search all my downloaded datasheets for WDP3 and get a more complete list?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Thu. Aug 2, 2018 - 02:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mu234 wrote:
I would like to add

So this is new work - nothing to do with the topic of porting existing code.

 

Time for a new thread

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
Knee-jerk is to say "the list hasn't been updated".
Ah, true dat. I linked to the online copy - that is just one snapshot in time (footer says Feb 2016 in fact) so it's possible it does not reflect the entire selection with 8s. I guess a more "up to date" way is to pull a recent toolchain and look there. I pulled a toolchain from Atmel (though it's likely many months old) just a few days ago and within that I see:

#if defined(__DOXYGEN__) || defined(WDP3)

/** \ingroup avr_watchdog
    See \c WDTO_15MS
    Note: This is only available on the 
    ATtiny2313, 
    ATtiny24, ATtiny44, ATtiny84, ATtiny84A,
    ATtiny25, ATtiny45, ATtiny85, 
    ATtiny261, ATtiny461, ATtiny861, 
    ATmega48, ATmega88, ATmega168,
    ATmega48P, ATmega88P, ATmega168P, ATmega328P,
    ATmega164P, ATmega324P, ATmega644P, ATmega644,
    ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
    ATmega8HVA, ATmega16HVA, ATmega32HVB,
    ATmega406, ATmega1284P,
    AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
    AT90PWM81, AT90PWM161,
    AT90USB82, AT90USB162,
    AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
    ATtiny48, ATtiny88.

    Note: This value does <em>not</em> match the bit pattern of the
    respective control register.  It is solely meant to be used together
    with wdt_enable().
    */
#define WDTO_4S     8

/** \ingroup avr_watchdog
    See \c WDTO_15MS
    Note: This is only available on the 
    ATtiny2313, 
    ATtiny24, ATtiny44, ATtiny84, ATtiny84A,
    ATtiny25, ATtiny45, ATtiny85, 
    ATtiny261, ATtiny461, ATtiny861, 
    ATmega48, ATmega48A, ATmega48PA, ATmega88, ATmega168,
    ATmega48P, ATmega88P, ATmega168P, ATmega328P,
    ATmega164P, ATmega324P, ATmega644P, ATmega644,
    ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
    ATmega8HVA, ATmega16HVA, ATmega32HVB,
    ATmega406, ATmega1284P,
    ATmega2564RFR2, ATmega256RFR2, ATmega1284RFR2, ATmega128RFR2, ATmega644RFR2, ATmega64RFR2
    AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
    AT90PWM81, AT90PWM161,
    AT90USB82, AT90USB162,
    AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
    ATtiny48, ATtiny88,
    ATxmega16a4u, ATxmega32a4u,
    ATxmega16c4, ATxmega32c4,
    ATxmega128c3, ATxmega192c3, ATxmega256c3.

    Note: This value does <em>not</em> match the bit pattern of the
    respective control register.  It is solely meant to be used together
    with wdt_enable().
    */
#define WDTO_8S     9

That is clearly the source of the text visible in the manual but as it's presumably human, not auto-generated it is subject to omission I  guess. I suppose the key thing is that those 4S and 8S options are dependent on the existence of WDP3 in a device. With that in mind:

D:\atmel_avr\avr8-gnu-toolchain-win32_x86\avr\include\avr>grep WDP3 io*.h
io90pwm1.h:#define WDP3    5   /* Watchdog Timer Prescaler bit3 */
io90pwm161.h:#define WDP3    5
io90pwm216.h:#define WDP3    5   /* Watchdog Timer Prescaler bit3 */
io90pwm2b.h:#define WDP3 5
io90pwm316.h:#define WDP3    5   /* Watchdog Timer Prescaler bit3 */
io90pwm3b.h:#define WDP3 5
io90pwm81.h:#define WDP3 5
io90pwmx.h:#define WDP3    5   /* Watchdog Timer Prescaler bit3 */
io90scr100.h:#define WDP3 5
ioa5272.h:#define WDP3    5
ioa5505.h:#define WDP3    5
ioa6612c.h:#define WDP3    5
ioa6613c.h:#define WDP3    5
ioa6614q.h:#define WDP3    5
ioa6616c.h:#define WDP3    5
ioa6617c.h:#define WDP3    5
ioa664251.h:#define WDP3    5
iom1284.h:#define WDP3    5
iom1284p.h:#define WDP3 5
iom1284rfr2.h:#define WDP3    5
iom128rfa1.h:#define WDP3                            5
iom128rfr2.h:#define WDP3    5
iom164pa.h:#define WDP3    5
iom168p.h:#define WDP3 5
iom168pa.h:#define WDP3    5
iom168pb.h:#define WDP3    5
iom16hva2.h:#define WDP3 5
iom16hvb.h:#define WDP3 5
iom16hvbrevb.h:#define WDP3 5
iom16m1.h:#define WDP3 5
iom16u2.h:#define WDP3 5
iom16u4.h:#define WDP3 5
iom2564rfr2.h:#define WDP3    5
iom256rfr2.h:#define WDP3    5
iom324a.h:#define WDP3    5
iom324p.h:#define WDP3    5
iom324pa.h:#define WDP3 5
iom328p.h:#define WDP3 5
iom32c1.h:#define WDP3 5
iom32hvb.h:#define WDP3 5
iom32hvbrevb.h:#define WDP3 5
iom32m1.h:#define WDP3 5
iom32u2.h:#define WDP3 5
iom32u4.h:#define WDP3 5
iom32u6.h:#define WDP3 5
iom406.h:#define WDP3    5
iom48p.h:#define WDP3 5
iom48pa.h:#define WDP3    5
iom48pb.h:#define WDP3    5
iom644pa.h:#define WDP3 5
iom644rfr2.h:#define WDP3    5
iom64c1.h:#define WDP3 5
iom64hve.h:#define WDP3 5
iom64hve2.h:#define WDP3    5
iom64m1.h:#define WDP3 5
iom64rfr2.h:#define WDP3    5
iom88p.h:#define WDP3 5
iom88pa.h:#define WDP3 5
iom88pb.h:#define WDP3    5
iom8u2.h:#define WDP3 5
iomx8.h:#define WDP3    5
iomxx0_1.h:#define WDP3    5
iomxx4.h:#define WDP3   5
iomxxhva.h:#define WDP3    5
iotn10.h:#define WDP3 5
iotn13.h:#  define WDP3                 5
iotn13a.h:#define WDP3 5
iotn1634.h:#define WDP3    5
iotn167.h:#define WDP3 5
iotn20.h:#define WDP3 5
iotn2313.h:#define WDP3    5
iotn2313a.h:#define WDP3 5
iotn24a.h:#define WDP3 5
iotn261a.h:#define WDP3 5
iotn4.h:#define WDP3 5
iotn40.h:#define WDP3 5
iotn4313.h:#define WDP3 5
iotn43u.h:#define WDP3 5
iotn441.h:#define WDP3    5
iotn44a.h:#define WDP3 5
iotn461a.h:#define WDP3 5
iotn48.h:#define WDP3 5
iotn5.h:#define WDP3 5
iotn828.h:#define WDP3    5
iotn841.h:#define WDP3    5
iotn84a.h:#define WDP3 5
iotn861a.h:#define WDP3 5
iotn87.h:#define WDP3 5
iotn88.h:#define WDP3 5
iotn9.h:#define WDP3 5
iotnx4.h:#define WDP3    5
iotnx5.h:#define WDP3    5
iotnx61.h:#define WDP3    5
iousbxx2.h:#define WDP3    5
iousbxx6_7.h:#define WDP3    5
iox128a1.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox128a1.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox128a1.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox128a1u.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox128a1u.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox128a1u.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox128a3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox128a3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox128a3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox128a3u.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox128a3u.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox128a3u.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox128a4u.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox128a4u.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox128a4u.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox128b1.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox128b1.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox128b1.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox128b3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox128b3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox128b3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox128c3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox128c3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox128c3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox128d3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox128d3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox128d3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox128d4.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox128d4.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox128d4.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox16a4.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox16a4.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox16a4.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox16a4u.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox16a4u.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox16a4u.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox16c4.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox16c4.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox16c4.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox16d4.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox16d4.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox16d4.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox16e5.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox16e5.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox16e5.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox192a3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox192a3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox192a3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox192a3u.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox192a3u.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox192a3u.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox192c3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox192c3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox192c3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox192d3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox192d3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox192d3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox256a3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox256a3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox256a3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox256a3b.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox256a3b.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox256a3b.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox256a3bu.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox256a3bu.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox256a3bu.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox256a3u.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox256a3u.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox256a3u.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox256c3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox256c3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox256c3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox256d3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox256d3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox256d3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox32a4.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox32a4.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox32a4.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox32a4u.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox32a4u.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox32a4u.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox32c3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox32c3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox32c3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox32c4.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox32c4.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox32c4.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox32d3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox32d3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox32d3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox32d4.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox32d4.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox32d4.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox32e5.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox32e5.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox32e5.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox384c3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox384c3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox384c3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox384d3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox384d3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox384d3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox64a1.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox64a1.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox64a1.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox64a1u.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox64a1u.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox64a1u.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox64a3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox64a3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox64a3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox64a3u.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox64a3u.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox64a3u.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox64a4u.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox64a4u.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox64a4u.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox64b1.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox64b1.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox64b1.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox64b3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox64b3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox64b3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox64c3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox64c3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox64c3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox64d3.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox64d3.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox64d3.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox64d4.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox64d4.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox64d4.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
iox8e5.h:#define NVM_FUSES_WDP3_bm  (1<<3)  /* Watchdog Timeout Period bit 3 mask. */
iox8e5.h:#define NVM_FUSES_WDP3_bp  3  /* Watchdog Timeout Period bit 3 position. */
iox8e5.h:#define FUSE_WDP3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */

However because of the stupid DFP thing they are now doing with the compiler, this list is likely not exhaustive. You'd need to pull the latest DFP for the tiny/mega of interest and check there. Now as it happens I pulled a Tiny one fairly recently so:

D:\atmel_avr\Atmel.ATtiny_DFP.1.3.172\include\avr>grep WDP3 *
iomx8.h:#define WDP3    5
iomxx0_1.h:#define WDP3    5
iomxx4.h:#define WDP3   5
iomxxhva.h:#define WDP3    5
iotn10.h:#define WDP3 5
iotn102.h:#define WDP3    5
iotn104.h:#define WDP3    5
iotn13.h:#  define WDP3                 5
iotn13a.h:#define WDP3 5
iotn1634.h:#define WDP3    5
iotn167.h:#define WDP3 5
iotn20.h:#define WDP3 5
iotn2313.h:#define WDP3    5
iotn2313a.h:#define WDP3 5
iotn24a.h:#define WDP3 5
iotn261a.h:#define WDP3 5
iotn4.h:#define WDP3 5
iotn40.h:#define WDP3 5
iotn4313.h:#define WDP3 5
iotn43u.h:#define WDP3 5
iotn441.h:#define WDP3    5
iotn44a.h:#define WDP3 5
iotn461a.h:#define WDP3 5
iotn48.h:#define WDP3 5
iotn5.h:#define WDP3 5
iotn828.h:#define WDP3    5
iotn841.h:#define WDP3    5
iotn84a.h:#define WDP3 5
iotn861a.h:#define WDP3 5
iotn87.h:#define WDP3 5
iotn88.h:#define WDP3 5
iotn9.h:#define WDP3 5
iotnx4.h:#define WDP3    5
iotnx5.h:#define WDP3    5
iotnx61.h:#define WDP3    5
iousbxx2.h:#define WDP3    5
iousbxx6_7.h:#define WDP3    5

I guess one would need to pull a recent "Mega" DFP and do the same for that. The above confirms all kinds of exotic devices like iotn841 (as just one example) that has WDP3 but that is not documented in the doxygen (so it and hence the "manual" are out of date). I guess this is the kind of thing the DFP nonsense cannot cater for.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you! True, however, I know the code, at least the procedure, by heart :) atm works OK, no problems, however, I have some considerations:

1) if the uc is running for more then 49 days it will go “ballistic”, because the millis() is not able to be punctual (10% deviation), right? Anyway, I guess this is not the biggest problem, because if it is once used during this period /days it will reset the timer... right?

2) what if “something” goes wrong, and the code, namely the application freezes, then I guess I could use at “least” 8 sec to reset the uc, but not sure how to do it...

Ok, I know how to set the wdt ... this looks very useful “manual” https://forum.arduino.cc/index.php?action=dlattach;topic=63651.0;attach=3585
However, will it work on tiny, tried, and got an error with the WDTSCR, but, guess I have put out the ‘S’ and it worked... data sheet ( http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf#page42 ) , p. 45

Anyway, I am still wondering how to conceptually use the wdt. For example, do I bring it in whenever I think the code should not stop, in such a case the wdt should start counting? For example, if the application freezes at the time when the light is on and I cannot change it with the sensor, to turn it off, obviously I could say, if a certain pin is high for more than 8 sec after the sensor is trying to change it, ofcourse, it could be the other way around, ... is this the right way to go about?

Another thing, can I use interrupt to execute a particular method that I have already within a code? Eg. would like to breakdown the setup into two parts, while I would like to call the second part with the interrupt... Or is there other possible way to jump around the code with the wdt?

Finally, I am thinking to reset the whole program every minute or so, for examples the example from the Arduino IDE ( http://forum.arduino.cc/index.php?topic=173850.0 ) shows how to go beyond 8 sec... Would that work to fire wdt after certain time and run the interrupt, namely the second part of the setup()?

I have put down some ideas, it sounds wishy washy, anyway, what do you think?

Best.

Bravo!!!

Last Edited: Thu. Aug 2, 2018 - 05:26 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, thanks, but I am not sure what is all this about?

Best.

Bravo!!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can use the Watchdog Timer in interrupt mode only (no device reset) by enabling WDIE and not WDE.

 

Increment a (volatile) counter in the interrupt service routine and you can extend the period of the timer to whatever you like.

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you, this sounds very interesting!

Bravo!!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello all,

 

I have quickly put code together in Arduino, following the idea of Mike, so that I can print out what is going on. Somehow I cannot get the interrupt, namely the ISR working properly, at least it looks so :/ while the reset, namely the WDE works just fine. 

 

Do I have to use cli(), but that would disable interrupts, should not I rather look for a function that removes the interrupt? 

 

Anyway, please have a look and point me where I am doing it wrong?

 

Best.

 

#include <avr/wdt.h>

int loop_count = 0;
byte led = 6;

void setup() {

  Serial.begin(57600);
  Serial.println();
  Serial.println("Somebody is rebooting... Starting up... ");
  Serial.println();
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  delay (500);
  watchdogSetup();
}
void watchdogSetup(void)
{
  cli();        // disable all interrupts
  wdt_reset(); // reset the WDT time

  // (ONLY) Enter Watchdog Configuration mode:
  WDTCSR |= (1 << WDCE) | (1 << WDE);

  // Set Watchdog settings:

  WDTCSR = (1 << WDIE) | (0 << WDE) | (0 << WDP3) | (1 << WDP2) | (1 << WDP1) | (0 << WDP0);

  sei();
}

// ********************* the loop *************************
void loop()
{ 

  for (int i = 0; i <= loop_count; i++) {
    digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
    delay(100);
  }

  loop_count++;

  wdt_reset();
  Serial.print(loop_count);
  Serial.print(". Watchdog fed in approx. ");
  Serial.print(loop_count * 200);
  Serial.println(" milliseconds.");
}

ISR(WDT_vect) // Watchdog timer interrupt.
{

  // Include your code here - be careful not to use functions they may cause the interrupt to hang and // prevent a reset
  Serial.println("********* we are in IRS ***********");

// reseting the wet
  wdt_reset();
}

 

Bravo!!!

Last Edited: Fri. Aug 3, 2018 - 11:49 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I had a look at the data sheet and it seems I should use the WDRF to remove the flag once I use the interrupt ? See datasheet ( http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf ) p.45

However, this is for at tiny x5 family, anyone knows, if the same holds for mega, which is on Arduino ?

Anyway, will this work and where should wdrf be used?

Best.

Bravo!!!

Last Edited: Fri. Aug 3, 2018 - 07:51 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You want the Watchdog resets (interrupts) to happen, so don't call wdt_reset() anywhere except maybe the setup routine.

 

--Mike

 

EDIT: in the setup routine do a wdt_reset() after you configure the prescaler to get more accurate timing

Last Edited: Fri. Aug 3, 2018 - 08:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Cheers!

 

I got the WDT going/working on MEGA, but now I am working on TINY. 

 

I want to set my "timer" to zero every 8 seconds via the interrupt-ISR, no reset!

 

Is the code below doing this :)

 

void watchdogSetup(void)
{
  //disable all interrupts, especially important, if you are delaing with interrupts, however, Memory is scarce!
  cli();

  wdt_reset(); //need to reset the WDT timer before you start usinging it, because you want to have a clean slate!

  // Enter Watchdog Configuration mode:

  // WDIE = 1 : Interrupt Enable
  // WDE = 0  : Reset NOT Enable (I am only going to use the interrupt!!!
  
  WDTCR |= (1 << WDCE) | (0 << WDE);

  // Set Watchdog settings (time-out after 2S)
  /*
    WDTCSR configuration:

    WDP3 = 0 :For 2000ms Time-out 
    WDP2 = 1 :For 2000ms Time-out 
    WDP1 = 1 :For 2000ms Time-out 
    WDP0 = 1 :For 2000ms Time-out
  */
  WDTCR = (1 << WDIE) | (0 << WDE) |  
          (1 << WDP3) | (0 << WDP2) | (0 << WDP1) | (1 << WDP0);

  //enalbe interrupt
  sei();
}


ISR(WDT_vect) // Watchdog timer interrupt.
{
  //reset the timer
  timer = 0;
}

Best.

Bravo!!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mu234 wrote:
// WDE = 0 : Reset NOT Enable (I am only going to use the interrupt!!! WDTCR |= (1 << WDCE) | (0 << WDE);

Then why the gratuitous use of the |=  ?  Just because you had an extra | lying about that was near expiration date?

 

Part of "will it work" is:  Will it satisfy the four-cycle timing requirement?  What does the generated code look like?

 

I don't think that I (or anyone else) can give more definitive answer without knowing what model you are working with.  And then we would [wait for it] pull up the datasheet and see what it says.  And then parrot that information back to you. 

 

I guess we can infer the toolchain choice from the posted code.

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

FWIW here is the interrupt-only code from the CodeVisionAVR Wizard for Tiny85 target with a 1024k (8 second) timeout:

// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/1024k
// Watchdog timeout action: Interrupt
#pragma optsize-
WDTCR=(0<<WDIF) | (0<<WDIE) | (1<<WDP3) | (1<<WDCE) | (0<<WDE) | (0<<WDP2) | (0<<WDP1) | (1<<WDP0);
WDTCR=(1<<WDIF) | (1<<WDIE) | (1<<WDP3) | (0<<WDCE) | (0<<WDE) | (0<<WDP2) | (0<<WDP1) | (1<<WDP0);
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

That isn't the entire story, as the prologue does the WDR and clears initialization to avoid cascading.  Your chosen toolchain does not do that as a matter of course.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Sat. Aug 25, 2018 - 11:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Changing the WDT prescaler setting requires a timed sequence as does turning off WDE.

 

First you set both WDCE and WDE to 1 (whether you ultimately want WDE or not), then

set WDE and WDPS to what you want within 4 clocks while writing 0 to WDCE.  There

may be some fuse settings which let you change these bits without the timed sequence.

 

--Mike

 

EDIT: also make sure to clear the WDRF reset flag before any of the above

 

Last Edited: Sun. Aug 26, 2018 - 12:43 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr-mike wrote:
First you set both WDCE and WDE to 1 (whether you ultimately want WDE or not),

IME that depends on the generation/model of AVR.  The Wizard sequence I gave above (without WDE in the first incantation) is used in some of my production apps.

 

All moot as OP hasn't given us a model number.

 

But I remember (and there is a thread or two here) about fussing with the sequences when the Mega88 family came out. [edit]

https://www.avrfreaks.net/forum/... more or less directly pertinent

https://www.avrfreaks.net/forum/... also pertinent as it is a solution for a Tiny

... and many more ...

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Sun. Aug 26, 2018 - 01:23 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm pretty sure they're using a mega 328, 32U4 or 2560 since it's an Arduino (see #11)

and another thread indicates a tiny85 might be involved too.

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes! The Mega that is on Arduino Uno is used to program the at tiny 45, I guess the wdt setup/use is the same as for the 85.
Anyway, thank you all for comments, suggestions.

I am new to the wdt, however, I am "sure"my code has a problem somewhere hence would like to make some kind of safety. So, this is the model :)

Maybe you can help me to conceptualize a beeter way to protect against the potential glitch. I was thinking to reset the whole program every 8sec, but I have certain things I do not want to be run, is it possible to avoid that or someother way around?

In my code I am using timing all the time, actually I use two intervals... In the setup() I run the wdt setup function, which is above.

Best.

Bravo!!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Cheers, totally useless part :) You are right I must have not seen that :) anyway, I have removed it and set both to 1, while in next call is set only the interrupt...

 

...
WDTCR = (1 << WDIE) | (0 << WDE) |  
          (1 << WDP3) | (0 << WDP2) | (0 << WDP1) | (1 << WDP0);
          ...

The program runs, however, I do not know how to debug it to see, if the wet works. Maybe I could use an led flash? 

 

If I run a function within the ISR to turn on and off the led, would that work, or should I run the function outside ISR? 

 

Best.

 

Bravo!!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr-mike wrote:

Changing the WDT prescaler setting requires a timed sequence as does turning off WDE.

Not sure what do you mean by that :/

 

avr-mike wrote:

First you set both WDCE and WDE to 1 (whether you ultimately want WDE or not),

Done that, thanks!

avr-mike wrote:

then

set WDE and WDPS to what you want within 4 clocks while writing 0 to WDCE. 

 

Please explain to me this? 

 

avr-mike wrote:

There

may be some fuse settings which let you change these bits without the timed sequence.

Thanks for this, will have a look!

 

Best.

Bravo!!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mu234 wrote:
Not sure what do you mean by that
mu234 wrote:
I guess the wdt setup/use is the same as for the 85

I think you need to spend a bit more time:

 

-- working with the datasheet

-- following the links given, and study the working results of the discussion

-- give more complete information when you post.  The standard stuff:  AVR model; clock speed; language; toolchain; version; optimization settings.  Schematic/connection diagram.  Tell how you are testing; tell what you expect to happen; tell what is happening.  Post code, ideally a complete test program that demonstrates the symptoms.

 

And no, "doesn't work" is not sufficient.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.