Chapterبەش 4 · Lectureوانە 4.5

Lab: The Watchdog Timer — Restarting a Frozen Deviceتاقیگە: تایمەری پاسەوان — دەستپێکردنەوەی ئامێرێکی گیرخواردوو

Why an unattended IoT node needs a watchdog timer; how it counts on its own clock and resets the board; the UNO R3 with avr/wdt.h (wdt_enable, wdt_reset, the WDTO_ time-outs), where to feed it and two classic mistakes; reading the reset cause (MCUSR, WDRF) and the UNO R3 bootloader that clears it; the old-bootloader reset loop; the UNO R4 WDT library and SleepyDog on the MKR WAN 1310; window watchdogs, watchdog chips, Linux and systemd watchdogs, drones; and the everyday word 'watchdog'.

بۆچی نۆدێکی IoTـی بێ کەس پێویستی بە هەیە؛ چۆن بە کاتژمێری خۆی دەژمێرێت و بۆردەکە ڕیسێت دەکات؛ ⁦UNO R3⁩ بە ⁦avr/wdt.h (wdt_enable⁩، ⁦wdt_reset⁩، سنوورەکانی کاتی ⁦WDTO_⁩)، لە کوێ نوێی بکەیتەوە و دوو هەڵەی باو؛ خوێندنەوەی هۆکاری ڕیسێت (MCUSR، WDRF) و ⁦UNO R3⁩ کە پاکی دەکاتەوە؛ خولی ڕیسێتی کۆن؛ WDTـی ⁦UNO R4⁩ و SleepyDog لەسەر ⁦MKR WAN 1310⁩؛ ، چیپی پاسەوان، پاسەوان لە Linux و systemd، ؛ و وشەی ڕۆژانەی «watchdog».

28 min read28 خولەک خوێندنەوە · 22 stepsهەنگاو

What you will learnچی فێر دەبیت

  • Explain what a watchdog timer is, why an unattended device needs one and what it cannot do.
  • Switch on and feed the watchdog of an Arduino UNO R3 with avr/wdt.h and choose a sensible time-out.
  • Feed the watchdog in the right place and recognise the two classic mistakes.
  • Find out whether a reset came from the watchdog, and explain why a stock UNO R3 needs a trick for it.
  • Use the watchdog on the UNO R4 and the MKR WAN 1310, and describe window watchdogs, watchdog chips and watchdogs in Linux and drones.
  • ڕوون بکەیتەوە چییە، بۆچی ئامێرێکی بێ کەس پێویستی پێیەتی و چی ناتوانێت بکات.
  • ⁦Arduino UNO R3⁩ بە ⁦avr/wdt.h⁩ هەڵبکەیت و نوێی بکەیتەوە و سنووری کاتێکی ژیرانە هەڵبژێریت.
  • لە شوێنی دروستدا نوێ بکەیتەوە و دوو هەڵە باوەکە بناسیتەوە.
  • بزانیت ڕیسێتێک لە پاسەوانەوە هاتووە یان نا و ڕوون بکەیتەوە بۆچی ⁦UNO R3⁩ـی ئاسایی فێڵێکی بۆ پێویستە.
  • پاسەوان لەسەر ⁦UNO R4⁩ و ⁦MKR WAN 1310⁩ بەکار بهێنیت و ، چیپی پاسەوان و پاسەوان لە Linux و باس بکەیت.

Nobody is there to press RESETکەس لەوێ نییە دوگمەی RESET دابگرێت

A sensor node can work for months on a farm, on a rooftop or inside a wall. Sometimes its program stops: a loop waits for an answer that never comes, a sensor or a radio module hangs, or a variable gets a value the code never expected. The board still has power, but it does nothing useful: it has frozen.

دەتوانێت مانگان لە کێڵگەیەک، لەسەر سەربانێک یان لەناو دیوارێکدا کار بکات. هەندێک جار بەرنامەکەی دەوەستێت: چاوەڕێی وەڵامێک دەکات کە هەرگیز نایەت، یان مۆدیولێکی ڕادیۆ گیر دەخوات، یان بەهایەک وەردەگرێت کە کۆدەکە هەرگیز چاوەڕێی نەدەکرد. بۆردەکە هێشتا کارەبای هەیە، بەڵام هیچ کارێکی بەسوود ناکات: تووشی بووە.

At home you would press RESET or pull the plug. On a farm 40 km from town nobody is there. This lab adds a watchdog timer: a small timer inside the chip that resets the board by itself when the program stops showing signs of life. You build it on an Arduino UNO R3, then meet the same idea on the UNO R4, the MKR WAN 1310, Linux computers and drones.

لە ماڵەوە دوگمەی RESET دادەگریت یان کارەباکەی لێ دەبڕیت. لە کێڵگەیەک کە ⁦40 km⁩ لە شار دوورە کەس لەوێ نییە. ئەم تاقیگەیە زیاد دەکات: بچووک لەناو چیپەکەدا کە خۆی بۆردەکە کاتێک بەرنامەکە ئیتر نیشانەی ژیان نادات. لەسەر ⁦Arduino UNO R3⁩ دروستی دەکەیت، پاشان هەمان بیرۆکە لەسەر ⁦UNO R4⁩، ⁦MKR WAN 1310⁩، Linux و دەبینیت.

Left: a sensor node with a solar panel on a pole in a field far from town. Middle: the readings received, 02:57 to 03:00, then a dashed line and 'nothing since 03:00: loop() is stuck'. Right: a phone app says the last reading came 6 hours ago, and nobody presses RESET.چەپ: نۆدێکی هەستەوەر بە پانێڵێکی خۆرەوە لەسەر ستوونێک لە کێڵگەیەکی دوور لە شار. ناوەڕاست: ئەو خوێندنەوانەی گەیشتوون، 02:57 تا 03:00، پاشان هێڵێکی پچڕپچڕ و «هیچ لە 03:00ـەوە: loop() گیری خواردووە». ڕاست: ئەپێکی مۆبایل دەڵێت دوایین خوێندنەوە 6 کاتژمێر لەمەوپێش هات و کەس RESET داناگرێت.
A frozen node keeps its power but sends nothing, and nobody is near.نۆدێکی گیرخواردوو کارەبای هەیە بەڵام هیچ نانێرێت و کەس لە نزیکی نییە.CêIT

The watchdog timer: a sign of life, or a resetتایمەری پاسەوان: نیشانەی ژیان، یان ڕیسێت

Definitionپێناسە

A small hardware , separate from the main program, that resets a or a computer unless the program restarts its count in time. It brings back an unattended device that has frozen.

بچووکە لەناو ، جیا لە بەرنامە سەرەکییەکە، کە یان مەگەر بەرنامەکە لە کاتی خۆیدا ژماردنەکەی لە سەرەتاوە دەست پێ بکاتەوە. ئامێرێکی دوور کە کەس لای نییە و ، دەخاتەوە سەر کار.

The idea is simple. The watchdog counts time on its own. Each time the program finishes a good round of work, it feeds the watchdog and the count starts again from zero. If the program freezes, the feeding stops, the count reaches its limit (the time-out) and the watchdog resets the board, as if somebody had pressed RESET. The board starts again from setup().

بیرۆکەکە سادەیە. خۆی کات دەژمێرێت. هەر جارێک بەرنامەکە گەڕێکی باشی کار تەواو دەکات، نوێ دەکاتەوە () و ژماردنەکە لە سفرەوە دەست پێ دەکاتەوە. ئەگەر بەرنامەکە گیری خوارد، ئیتر نوێی ناکاتەوە، ژماردنەکە دەگاتە سنوورەکەی (سنووری کات، بە ئینگلیزی ⁦time-out⁩) و پاسەوانەکە بۆردەکە ، وەک ئەوەی کەسێک RESETـی داگرتبێت. بۆردەکە لە setup()ـەوە دەست پێ دەکاتەوە.

The bakery and the night guardنانەواخانە و پاسەوانی شەو

Rebin bakes bread alone through the night. The market's night guard sits outside with one rule: every 15 minutes Rebin must knock on the window. While the knocks come, the guard does nothing. If 15 minutes pass with no knock, the guard decides something is wrong: he switches off the oven, wakes Rebin, and the work starts again.

ڕێبین بە تەنیا بە درێژایی شەو نان دەکات. پاسەوانی شەوی بازاڕەکە لە دەرەوە دادەنیشێت و یەک یاسای هەیە: هەر ⁦15⁩ خولەک جارێک ڕێبین دەبێت لە پەنجەرەکە بدات. تا لێدانەکان دێن، پاسەوانەکە هیچ ناکات. ئەگەر ⁦15⁩ خولەک بەبێ لێدان تێپەڕی، پاسەوانەکە دەزانێت شتێک هەڵەیە: فڕنەکە دەکوژێنێتەوە، ڕێبین بەئاگا دەهێنێتەوە و کارەکە لە سەرەتاوە دەست پێ دەکاتەوە.

Where the analogy stops workingسنووری ئەم نموونەیە

The guard knows only that the knocks stopped, not why. A baker who keeps knocking while the bread burns fools him, and waking the baker does not repair a broken oven: a watchdog restarts a device, it does not fix the cause.

پاسەوانەکە تەنیا دەزانێت کە لێدانەکان وەستاون، نەک بۆچی. نانەوایەک کە بەردەوام لە پەنجەرە دەدات لە کاتێکدا نانەکە دەسووتێت فریوی دەدات و بەئاگاهێنانەوەی نانەوا فڕنێکی تێکچوو چاک ناکاتەوە: ئامێرەکە دەخاتەوە سەر کار، بەڵام هۆکارەکە چاک ناکاتەوە.

A graph of the time since the last feed over 7 seconds. It rises and drops back to zero at each feed at 0.05, 1.05 and 2.05 s. A pink band from 3 s marks the frozen program: with no feeds the line climbs to the dashed 2 s limit at 4.05 s, where a red line marks RESET. From 4.115 s setup() runs again and the feeds come back.گرافی ئەو کاتەی لە دوایین نوێکردنەوەوە تێپەڕیوە لە ماوەی 7 چرکەدا. بەرز دەبێتەوە و لە هەر نوێکردنەوەیەکدا، لە 0.05، 1.05 و 2.05 چرکەدا، دەگەڕێتەوە بۆ سفر. پشتێنێکی پەمەیی لە چرکەی 3ـەوە بەرنامە گیرخواردووەکە نیشان دەدات: بەبێ نوێکردنەوە هێڵەکە تا سنووری پچڕپچڕی 2 چرکە لە 4.05 چرکەدا سەردەکەوێت، کە هێڵێکی سوور ڕیسێت نیشان دەدات. لە 4.115 چرکەوە setup() دیسان کار دەکات و نوێکردنەوەکان دەگەڕێنەوە.
Feeds keep the line low; a freeze lets it reach the limit.نوێکردنەوەکان هێڵەکە نزم دەهێڵنەوە؛ وای لێ دەکات بگاتە سنوورەکە.CêIT

The watchdog timer: a sign of life, or a resetتایمەری پاسەوان: نیشانەی ژیان، یان ڕیسێت

Feed, kick, reset: words that confusefeed، kick، reset: ئەو وشانەی تێکەڵ دەبن

English has several words for the same action: you feed, kick, pet or refresh the watchdog. Arduino function names make it harder, because two of them say reset:

ئینگلیزی چەند وشەیەکی بۆ هەمان کار هەیە: feed، kick، pet یان refresh دەکەیت. ناوی Arduino کارەکە قورستر دەکەن، چونکە دووانیان دەڵێن reset:

In the codeلە کۆدەکەداWhat it really doesبە ڕاستی چی دەکات
wdt_reset() (UNO R3), Watchdog.reset() (SleepyDog)Feeds: the count starts again. The board does not reset.نوێ دەکاتەوە: ژماردنەکە دیسان دەست پێ دەکات. بۆردەکە ڕیسێت نابێت.
WDT.refresh() (UNO R4), a write to /dev/watchdog (Linux)Feeds too.ئەمیش نوێ دەکاتەوە.
a watchdog reset, a time-out، تەواوبوونی کاتThe count reached its limit: the whole board resets.ژماردنەکە گەیشتە سنوورەکەی: هەموو بۆردەکە ڕیسێت دەبێت.

So read wdt_reset() as reset the watchdog's count, never as reset the board.

کەواتە wdt_reset() وەک ژماردنی پاسەوان لە سفرەوە دەست پێ بکەرەوە بخوێنەوە، هەرگیز وەک بۆردەکە ڕیسێت بکە.

How it counts: its own clockچۆن دەژمێرێت: کاتژمێری خۆی

In the UNO R3's ATmega328P the watchdog is a counter driven by its own small 128 kHz oscillator, separate from the 16 MHz clock that runs your program. It counts about 128,000 ticks a second. With a 2 s time-out it fires after 262,144 ticks. The datasheet gives 2.0 s as a typical value: the oscillator is not exact, so a real time-out can be a little longer or shorter.

لە ⁦ATmega328P⁩ـی ⁦UNO R3⁩ـدا کە لەرەلەرکەرێکی بچووکی ⁦128 kHz⁩ـی خۆی دەیجوڵێنێت، جیا لەو کاتژمێرە ⁦16 MHz⁩ـەی بەرنامەکەت کار پێ دەکات. لە چرکەیەکدا نزیکەی ⁦128,000⁩ تیک دەژمێرێت. بە سنووری کاتی 2 چرکە، دوای ⁦262,144⁩ تیک کار دەکات. ⁦2.0⁩ چرکە وەک بەهایەکی ئاسایی دەدات: لەرەلەرکەرەکە ورد نییە، بۆیە سنووری کاتێکی ڕاستەقینە دەتوانێت کەمێک درێژتر یان کورتتر بێت.

wdt_reset() is a single machine instruction, wdr, that puts the counter back to 0. Because the counter has its own clock, it keeps counting while the program is stuck: nothing stops it except switching the watchdog off, or stuck code that feeds it by mistake (see the common mistake later in this lesson).

wdt_reset() تەنیا یەک فەرمانی ماشێنە، wdr، کە دەگەڕێنێتەوە بۆ 0. لەبەر ئەوەی کاتژمێری خۆی هەیە، کاتێک بەرنامەکە گیری خواردووە بەردەوام دەژمێرێت: هیچ شتێک نایوەستێنێت جگە لە کوژاندنەوەی پاسەوانەکە، یان کۆدێکی گیرخواردوو کە بە هەڵە نوێی بکاتەوە (هەڵە باوەکەی دواتری ئەم وانەیە ببینە).

Inside the ATmega328P: its own 128 kHz clock sends ticks to a counter (0, 1, 2, 3 …). At 262,144 ticks, about 2 s, a time-out box sends a red arrow to 'RESET of the whole chip'. From below, the program's wdt_reset(); sends the counter back to 0. Note: it keeps counting even when the program is stuck.لەناو ATmega328Pـدا: کاتژمێری 128 kHzـی خۆی تیک دەنێرێت بۆ ژمێرەری دیجیتاڵێک (0، 1، 2، 3 …). لە 262,144 تیکدا، نزیکەی 2 چرکە، سندوقی تەواوبوونی کات تیرێکی سوور دەنێرێت بۆ «ڕیسێتی هەموو چیپەکە». لە خوارەوە wdt_reset();ـی بەرنامەکە ژمێرەرە دیجیتاڵەکە دەگەڕێنێتەوە بۆ 0. تێبینی: بەردەوام دەژمێرێت تەنانەت کاتێک بەرنامەکە گیری خواردووە.
Its own clock, its own counter: a stuck program cannot stop it.کاتژمێری خۆی و خۆی: بەرنامەیەکی گیرخواردوو ناتوانێت بیوەستێنێت.CêIT

How it counts: its own clockچۆن دەژمێرێت: کاتژمێری خۆی

What a reset does to the boardڕیسێت چی بە بۆردەکە دەکات

  • All pins go back to inputs at once, so every output switches off. Wire pumps, heaters and motors so that off is their safe state.
  • The program starts from the beginning: global variables get their first values, setup() runs and millis() starts again from 0.
  • Whatever lived only in RAM is lost: counters, the last readings, a half-sent message. Keep what must survive in EEPROM or on the server.
  • An UNO R3 waits about 65 ms after a reset before it starts (a delay set by the chip's fuses), so its clock is steady.
  • هەموو پینەکان دەستبەجێ دەبنەوە بە ، بۆیە هەموو دەکوژێتەوە. پەمپ، گەرمکەرەوە و بە شێوەیەک ببەستە کە کوژاو دۆخی سەلامەتیان بێت.
  • بەرنامەکە لە سەرەتاوە دەست پێ دەکاتەوە: بەهای یەکەمیان وەردەگرنەوە، setup() کار دەکات و millis() دیسان لە 0ـەوە دەست پێ دەکات.
  • هەرچی تەنیا لە بوو ون دەبێت: ، دوایین خوێندنەوەکان، پەیامێکی نیوە نێردراو. ئەوەی دەبێت بمێنێتەوە لە یان لەسەر هەڵی بگرە.
  • ⁦UNO R3⁩ دوای ڕیسێت نزیکەی ⁦65 ms⁩ چاوەڕێ دەکات پێش ئەوەی دەست پێ بکات (دواخستنێک کە ڕێکخستنی چیپەکە دیاری دەکات)، تا کاتژمێرەکەی جێگیر ببێت.
Four boxes on the left, power on, RESET button, low voltage and watchdog, all lead with arrows to one box, MCU. An arrow goes on to 'start again from setup()'.چوار سندوق لە لای چەپ، هەڵکردن، دوگمەی RESET، ڤۆڵتیەی نزم و پاسەوان، هەموویان بە تیر دەچن بۆ یەک سندوق، MCU. تیرێک بەردەوام دەبێت بۆ «دیسان لە setup()ـەوە دەست پێ دەکاتەوە».
Every kind of reset ends the same way: the program starts again from the beginning.هەموو جۆرە بە یەک شێوە کۆتایی دێت: بەرنامەکە لە سەرەتاوە دەست پێ دەکاتەوە.CêIT

Lab 1: a node that freezesتاقیگەی 1: نۆدێک کە گیر دەخوات

The node asks a sensor module for a reading with a short pulse on pin 3. The module answers by setting its READY pin, wired to pin 2, HIGH about 50 ms later. Then the sketch prints the reading number and waits. The while loop waits for READY with no time limit: if a pulse is lost, for example to electrical noise on a long wire, the answer never comes.

نۆدەکە بە کورت لەسەر پینی 3 داوای خوێندنەوە لە مۆدیولێکی دەکات. مۆدیولەکە نزیکەی ⁦50 ms⁩ دواتر وەڵام دەداتەوە بەوەی پینی READYـی خۆی، کە بە پینی 2ـەوە بەستراوە، دەکاتە HIGH. پاشان ژمارەی خوێندنەوەکە دەنووسێت و چاوەڕێ دەکات. بەبێ سنووری کات چاوەڕێی READY دەکات: ئەگەر ون بێت، بۆ نموونە بەهۆی لەسەر وایەرێکی درێژ، وەڵامەکە هەرگیز نایەت.

Lab 1: no watchdogتاقیگەی 1: بەبێ پاسەوانfrozen.inoARDUINORuns on a phone (or an emulator)لەسەر مۆبایل کار دەکات
// A sensor node without a watchdog (UNO R3)
const int requestPin = 3;   // a pulse here asks the sensor module for a reading
const int readyPin = 2;     // the module answers HIGH when the reading is ready
int count = 0;

void setup() {
  Serial.begin(9600);
  pinMode(requestPin, OUTPUT);
  pinMode(readyPin, INPUT);
  Serial.println("Node started");
}

void loop() {
  digitalWrite(requestPin, HIGH);   // ask for a reading
  digitalWrite(requestPin, LOW);
  while (digitalRead(readyPin) == LOW) {
    // wait for the answer... for ever, if the request was lost
  }
  count++;
  Serial.print("Reading ");
  Serial.println(count);
  delay(950);
}
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 14

A short pulse asks the module for a reading.

کورت داوای خوێندنەوە لە مۆدیولەکە دەکات.

Lineدێڕی 16

Waits for READY with no time limit: here the node can freeze.

بەبێ سنووری کات چاوەڕێی READY دەکات: لێرەدا نۆدەکە دەتوانێت گیر بخوات.

After Reading 3 nothing more ever arrives. The board still has power and loop() is still running, but it is stuck in the while line. Without a person, it stays like this until its battery runs out.

دوای Reading 3 ئیتر هیچ شتێک نایەت. بۆردەکە هێشتا کارەبای هەیە و loop() هێشتا کار دەکات، بەڵام لە دێڕی whileـدا گیری خواردووە. بەبێ کەسێک، هەروا دەمێنێتەوە تا تەواو دەبێت.

Two flowcharts of one round of loop(). Left, the healthy round from 0 to 2 s: ask the module with a pulse on pin 3, wait for READY on pin 2, print Reading n, wait 950 ms, and an arrow back to the start; READY comes after 50 ms. Right, the round at 3 s: the pulse is lost to noise, a red arrow loops on 'wait for READY' for ever, and the later steps are grey; READY never comes.دوو هێڵکاریی ڕەوت بۆ یەک گەڕی loop(). چەپ، گەڕی تەندروست لە 0 تا 2 چرکە: بە تڕپەیەک لەسەر پینی 3 داوا لە مۆدیولەکە بکە، چاوەڕێی READY بکە لەسەر پینی 2، Reading n بنووسە، 950 ms چاوەڕێ بکە و تیرێک بۆ سەرەتا؛ READY دوای 50 ms دێت. ڕاست، گەڕی چرکەی 3: تڕپەکە بەهۆی ژاوەژاوەوە ون دەبێت، تیرێکی سوور بۆ هەمیشە بەسەر «چاوەڕێی READY بکە»دا دەسووڕێتەوە و هەنگاوەکانی دواتر خۆڵەمێشین؛ READY هەرگیز نایەت.
One lost pulse, and the round never ends.یەک ونبوو و گەڕەکە هەرگیز تەواو نابێت.CêIT

Lab 2: add the watchdog (UNO R3)تاقیگەی 2: پاسەوانەکە زیاد بکە ⁦(UNO R3)⁩

Three lines change the story. #include <avr/wdt.h> brings the watchdog functions of avr-libc, the C library behind the UNO R3. wdt_enable(WDTO_2S) at the end of setup() switches the watchdog on with a 2-second time-out. wdt_reset() at the end of each round feeds it.

سێ دێڕ چیرۆکەکە دەگۆڕن. #include <avr/wdt.h> پاسەوانی ⁦avr-libc⁩ دەهێنێت، کە Cـیە و ⁦UNO R3⁩ بەکاری دەهێنێت. wdt_enable(WDTO_2S) لە کۆتایی setup()ـدا پاسەوانەکە بە سنووری کاتی 2 چرکە هەڵدەکات. wdt_reset() لە کۆتایی هەر گەڕێکدا نوێی دەکاتەوە.

Lab 2: the same node with a watchdogتاقیگەی 2: هەمان نۆد بە پاسەوانەوەwdt_uno.inoARDUINORuns on a phone (or an emulator)لەسەر مۆبایل کار دەکات
// The same node with the watchdog (UNO R3)
#include <avr/wdt.h>

const int requestPin = 3;
const int readyPin = 2;
int count = 0;

void setup() {
  Serial.begin(9600);
  pinMode(requestPin, OUTPUT);
  pinMode(readyPin, INPUT);
  Serial.println("Node started");
  wdt_enable(WDTO_2S);              // reset the board if it is not fed for 2 s
}

void loop() {
  digitalWrite(requestPin, HIGH);
  digitalWrite(requestPin, LOW);
  while (digitalRead(readyPin) == LOW) {
    // still waiting: no wdt_reset() in here
  }
  count++;
  Serial.print("Reading ");
  Serial.println(count);
  wdt_reset();                      // a whole round is done: feed the watchdog
  delay(950);
}
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 2

The watchdog functions of avr-libc (AVR boards only).

پاسەوانی ⁦avr-libc⁩ (تەنیا بۆردەکانی AVR).

Lineدێڕی 13

Switch on: reset the board if it is not fed for 2 s.

هەڵکردن: ئەگەر 2 چرکە نوێ نەکرایەوە، بۆردەکە ڕیسێت بکە.

Lineدێڕی 25

Feed once, after the whole round has worked.

یەک جار نوێی بکەرەوە، دوای ئەوەی هەموو گەڕەکە کاری کرد.

The last feed came at 2.05 s. At 4.05 s the 2 s were up and the watchdog reset the board. setup() ran again 65 ms later, count started again from 0, and the node worked again, because the next request got its answer.

دوایین نوێکردنەوە لە ⁦2.05⁩ چرکەدا بوو. لە ⁦4.05⁩ چرکەدا 2 چرکەکە تەواو بوو و پاسەوانەکە بۆردەکەی ڕیسێت کرد. ⁦65 ms⁩ دواتر setup() دیسان کاری کرد، count دیسان لە 0ـەوە دەستی پێ کرد و نۆدەکە دیسان کاری کرد، چونکە داواکاریی داهاتوو وەڵامەکەی وەرگرت.

Animation. Left, a Serial Monitor; right, a bar 'time left before a reset'. Reading 1 at 0.05 s fills the bar to 2.00 s; it drains to 1.25 s; Readings 2 and 3 fill it again. At 3.00 s the request is lost and the bar drains, 1.05 s, 0.45 s, until 0.00 s at 4.05 s and a red RESET!. At 4.115 s Node started appears, the bar is full again, and Reading 1 follows.
Animation. Left, a Serial Monitor; right, a bar 'time left before a reset'. Reading 1 at 0.05 s fills the bar to 2.00 s; it drains to 1.25 s; Readings 2 and 3 fill it again. At 3.00 s the request is lost and the bar drains, 1.05 s, 0.45 s, until 0.00 s at 4.05 s and a red RESET!. At 4.115 s Node started appears, the bar is full again, and Reading 1 follows.
Fed, fed, fed… then no feed for 2 s, and the board starts again.نوێکردنەوە، نوێکردنەوە… پاشان 2 چرکە بێ نوێکردنەوە و بۆردەکە دیسان دەست پێ دەکاتەوە.CêIT

Lab 2: add the watchdog (UNO R3)تاقیگەی 2: پاسەوانەکە زیاد بکە ⁦(UNO R3)⁩

Choosing the time-outهەڵبژاردنی سنووری کات

wdt_enable() takes one of ten constants. The times are the datasheet's typical values at 5 V:

wdt_enable() یەکێک لە دە وەردەگرێت. کاتەکان بەها ئاساییەکانی لە ⁦5 V⁩ـدا:

ConstantنەگۆڕTime-outسنووری کاتConstantنەگۆڕTime-outسنووری کات
WDTO_15MS16 msWDTO_500MS0.5 s
WDTO_30MS32 msWDTO_1S1 s
WDTO_60MS64 msWDTO_2S2 s
WDTO_120MS125 msWDTO_4S4 s
WDTO_250MS250 msWDTO_8S8 s

Find the longest healthy round of loop(), with the slowest sensor read, a radio send and every delay(), and choose a time-out comfortably longer, for example about twice as long. Then test it: an embedded-systems course at Carnegie Mellon advises changing the time-out until the watchdog trips, to check that it trips where you expect. Too short, and a healthy node is reset again and again; too long, and a frozen node stays dead longer. wdt_disable() switches the watchdog off; keep it out of normal code, because a bug that reaches it switches off your safety net.

درێژترین گەڕی تەندروستی loop() بدۆزەرەوە، لەگەڵ هێواشترین خوێندنەوەی ، ناردنێکی ڕادیۆ و هەموو delay()ـێک و سنووری کاتێک هەڵبژێرە کە بە باشی درێژترە، بۆ نموونە نزیکەی دوو هێندە. پاشان تاقی بکەرەوە: کۆرسێکی زانکۆی Carnegie Mellon ئامۆژگاری دەکات سنووری کات بگۆڕیت تا پاسەوانەکە کار دەکات، بۆ ئەوەی بزانیت لەو شوێنەدا کار دەکات کە چاوەڕێی دەکەیت. ئەگەر زۆر کورت بێت، نۆدێکی تەندروست جار لەدوای جار ڕیسێت دەبێت؛ ئەگەر زۆر درێژ بێت، نۆدێکی گیرخواردوو ماوەیەکی درێژتر مردوو دەمێنێتەوە. wdt_disable() پاسەوانەکە دەکوژێنێتەوە؛ لە کۆدی ئاساییدا بەکاری مەهێنە، چونکە کە بیگاتێ تۆڕی سەلامەتییەکەت دەکوژێنێتەوە.

Where to feed the watchdogلە کوێ پاسەوانەکە نوێ بکەیتەوە

Feed only when the program has shown that it is healthy: once, at the end of a complete round of loop(), after every job of that round has finished. Then a feed really means: all of my work is going round. Three places look handy but are wrong:

تەنیا کاتێک نوێی بکەرەوە کە بەرنامەکە پیشانی دابێت تەندروستە: یەک جار، لە کۆتایی گەڕێکی تەواوی loop()ـدا، دوای ئەوەی هەموو کارەکانی ئەو گەڕە تەواو بوون. ئەو کاتە نوێکردنەوە بە ڕاستی واتای ئەمەیە: هەموو کارەکانم دەسووڕێنەوە. سێ شوێن ئاسان دەردەکەون بەڵام هەڵەن:

  • inside a loop that waits: the stuck loop itself keeps the watchdog fed;
  • in a timer interrupt: it only proves that the timer works, not that loop() does;
  • in many places: one of them may sit inside the fault.
  • لەناو کە چاوەڕێ دەکات: خودی خولە گیرخواردووەکە پاسەوانەکە نوێ دەکاتەوە؛
  • لە : تەنیا ئەوە دەسەلمێنێت کە کار دەکات، نەک loop()؛
  • لە زۆر شوێندا: لەوانەیە یەکێکیان لەناو هەڵەکەدا بێت.

With several jobs on different timetables, give each job a flag that it sets after it has run. The loop feeds only when all the flags are set, then clears them. Every job must check in, or nobody feeds the watchdog.

ئەگەر چەند کارێک بە خشتەی کاتی جیاواز هەبن، بە هەر کارێک bool بدە کە دوای ئەوەی کاری کرد دەیکاتە true. تەنیا کاتێک نوێ دەکاتەوە کە هەموویان true بن، پاشان دەیانکاتەوە false. هەموو کارێک دەبێت ئامادەیی خۆی نیشان بدات، ئەگەرنا کەس پاسەوانەکە نوێ ناکاتەوە.

Left: void loop() { read the sensor with a time limit, send the reading, update the display, then wdt_reset(); with a green tick: once, at the end of a good round }. Right, three boxes with red crosses: inside a loop that waits (the stuck loop keeps it fed), in a timer interrupt (the timer runs even when loop() is stuck), in many places (one of them may be inside the fault). Below: several jobs? Each one checks in; feed only when all have checked in.چەپ: void loop() { خوێندنەوەی هەستەوەر بە سنووری کات، ناردنی خوێندنەوەکە، نوێکردنەوەی شاشەکە، پاشان wdt_reset(); بە نیشانەیەکی سەوز: یەک جار، لە کۆتایی گەڕێکی باشدا }. ڕاست، سێ سندوق بە خاچی سوور: لەناو خولێک کە چاوەڕێ دەکات (خولە گیرخواردووەکە نوێی دەکاتەوە)، لە پچڕاندنێکی تایمەر (تایمەرەکە کار دەکات کاتێک loop() گیری خواردووە)، لە زۆر شوێندا (لەوانەیە یەکێکیان لەناو هەڵەکەدا بێت). لە خوارەوە: چەند کارێک؟ هەر یەکەیان ئامادەیی خۆی نیشان دەدات؛ تەنیا کاتێک نوێی بکەرەوە کە هەموویان ئامادەیی خۆیان نیشان دابێت.
One feed, at the end of a complete round, and nowhere else.یەک نوێکردنەوە، لە کۆتایی گەڕێکی تەواودا و لە هیچ شوێنێکی تردا نا.CêIT

Where to feed the watchdogلە کوێ پاسەوانەکە نوێ بکەیتەوە

Common mistake: feeding inside the waiting loopهەڵەی باو: نوێکردنەوە لەناو خولی چاوەڕێدا

Left: the code while (digitalRead(readyPin) == LOW) { wdt_reset(); } with the feed in red and a red arrow looping back; READY never comes, this loop runs for ever and feeds thousands of times a second. Right: a meter of the time since the last feed stays at 0 ms, far from the 2 s limit: no reset, the node stays frozen.چەپ: کۆدی while (digitalRead(readyPin) == LOW) { wdt_reset(); } بە نوێکردنەوەکە بە سوور و تیرێکی سوور کە دەسووڕێتەوە؛ READY هەرگیز نایەت، ئەم خولە بۆ هەمیشە دەسووڕێتەوە و هەزاران جار لە چرکەیەکدا نوێی دەکاتەوە. ڕاست: پێوەری کات لە دوایین نوێکردنەوەوە لە 0 msـدا دەمێنێتەوە، دوور لە سنووری 2 چرکە: هیچ ڕیسێتێک نییە، نۆدەکە گیرخواردوو دەمێنێتەوە.
The watchdog is on, fed and useless.پاسەوانەکە هەڵکراوە، نوێ دەکرێتەوە و بێسوودە.CêIT

Where to feed the watchdogلە کوێ پاسەوانەکە نوێ بکەیتەوە

Common mistake: a time-out shorter than a healthy roundهەڵەی باو: سنووری کاتێک کورتتر لە گەڕێکی تەندروست

A timeline from 0 to 9 s. A dashed grey bar shows that delay(5000) would end at 5 s, with a red cross. Below, short orange bars of 2 s each start after every 'Node started, Reading 1', and a red line cuts each one: watchdog resets at about 2.05, 4.17, 6.28 and 8.40 s.هێڵی کاتێک لە 0 تا 9 چرکە. شریتێکی خۆڵەمێشیی پچڕپچڕ پیشان دەدات کە کۆتایی delay(5000) لە چرکەی 5 دەبوو، بە خاچێکی سوور. لە خوارەوە، شریتی پرتەقاڵیی کورتی 2 چرکەیی دوای هەر «Node started، Reading 1»ـێک دەست پێ دەکەن و هێڵێکی سوور هەریەکەیان دەبڕێت: ڕیسێتەکانی پاسەوان لە نزیکەی 2.05، 4.17، 6.28 و 8.40 چرکەدا.
A healthy program, killed every 2 s by its own watchdog.بەرنامەیەکی تەندروست کە پاسەوانی خۆی هەر 2 چرکە جارێک دەیکوژێت.CêIT

Who reset the board? MCUSR and WDRFکێ بۆردەکەی ڕیسێت کرد؟ MCUSR و WDRF

A node should report when the watchdog had to rescue it: one restart a month is fine, ten a day mean a bug to find. The ATmega328P records the cause of the last reset in its MCUSR register: WDRF (bit 3) for the watchdog, BORF for a supply voltage that fell too low, EXTRF for the RESET pin and PORF for power-on. The datasheet says: read MCUSR as early as possible, then clear it.

نۆدێک دەبێت ڕاپۆرت بدات کاتێک پاسەوانەکە ناچار بوو ڕزگاری بکات: یەک دەستپێکردنەوە لە مانگێکدا ئاساییە، دە دانە لە ڕۆژێکدا واتە هەیە کە دەبێت بدۆزرێتەوە. ⁦ATmega328P⁩ هۆکاری دوایین ڕیسێت لە MCUSRـدا تۆمار دەکات: WDRF ( ⁦3⁩) بۆ پاسەوان، BORF بۆ کارەبا کە زۆر دابەزیوە، EXTRF بۆ پینی RESET و PORF بۆ هەڵکردن. دەڵێت: MCUSR هەرچی زووتر بخوێنەوە، پاشان پاکی بکەرەوە.

Newer Optiboot versions keep the flags (from version 7) or hand them to the sketch in a register (from 4.6), and a chip without a bootloader keeps them too. On a stock UNO R3, use the trick on the next screen.

وەشانە نوێیەکانی Optiboot هۆکاری ڕیسێت دەهێڵنەوە (لە وەشانی 7ـەوە) یان لە دەیدەن بە (لە ⁦4.6⁩ـەوە) و چیپێکی بێ دەیانهێڵێتەوە. لەسەر ⁦UNO R3⁩ـی ئاسایی، فێڵەکەی پەڕەی داهاتوو بەکار بهێنە.

The MCUSR register as eight boxes: bits 7 to 4 are unused; bit 3 WDRF (watchdog) is highlighted, bit 2 BORF (low voltage), bit 1 EXTRF (RESET pin), bit 0 PORF (power on). Below, an orange box: UNO R3: its bootloader reads MCUSR, writes 0 and turns the watchdog off, and only then starts your sketch. An arrow leads to setup(): MCUSR = 0.تۆمارگەکە MCUSR وەک هەشت سندوق: بیتەکانی 7 تا 4 بەکار نایەن؛ بیتی 3 WDRF (پاسەوان) دیار کراوە، بیتی 2 BORF (ڤۆڵتیەی نزم)، بیتی 1 EXTRF (پینی RESET)، بیتی 0 PORF (هەڵکردن). لە خوارەوە، سندوقێکی پرتەقاڵی: UNO R3: بارکەری بووتەکەی MCUSR دەخوێنێتەوە، 0ی تێدا دەنووسێت و پاسەوانەکە دەکوژێنێتەوە، پاشان سکێچەکەت دەست پێ دەکات. تیرێک دەچێت بۆ setup(): MCUSR = 0.
The chip knows who reset it; on an UNO R3 the bootloader wipes that before setup().چیپەکە دەزانێت کێ ڕیسێتی کرد؛ لەسەر ⁦UNO R3⁩ ئەوە پێش ⁦setup()⁩ دەسڕێتەوە.CêIT

Who reset the board? MCUSR and WDRFکێ بۆردەکەی ڕیسێت کرد؟ MCUSR و WDRF

UNO R3: let the watchdog leave a note⁦UNO R3⁩: با پاسەوانەکە تێبینییەک بەجێ بهێڵێت

The ATmega328P watchdog has a third mode, interrupt and system reset. At the first time-out it runs an interrupt function, ISR(WDT_vect); only at the next time-out does it reset the board. The datasheet suggests this moment for saving important data before the reset. Here the interrupt writes a special number into a variable in the .noinit part of RAM, which the start-up code does not clear.

⁦ATmega328P⁩ دۆخێکی سێیەمی هەیە، و پاشان ڕیسێت. لە یەکەم تەواوبوونی کاتدا جێبەجێ دەکات، ISR(WDT_vect)؛ تەنیا لە تەواوبوونی کاتی دواتردا بۆردەکە ڕیسێت دەکات. ئەم ساتە پێشنیار دەکات بۆ پاشەکەوتکردنی گرنگ پێش ڕیسێتەکە. لێرەدا ژمارەیەکی تایبەت دەنووسێتە ناو لە بەشی .noinitـی ، کە کۆدی دەستپێکردن پاکی ناکاتەوە.

UNO R3: a note in .noinit memory⁦UNO R3⁩: تێبینییەک لە بیرگەی ⁦.noinit⁩ـداnote.inoARDUINORuns on a phone (or an emulator)لەسەر مۆبایل کار دەکات
// UNO R3: the watchdog interrupt leaves a note before the reset
#include <avr/wdt.h>

const int requestPin = 3;
const int readyPin = 2;
const uint16_t DOG_NOTE = 0xD06;      // a special number: "the watchdog was here"
int count = 0;

// .noinit: the start-up code does not clear this variable,
// so it keeps its value through a reset (not through a power cut)
volatile uint16_t resetNote __attribute__((section(".noinit")));

ISR(WDT_vect) {                       // 1st time-out: runs instead of a reset
  resetNote = DOG_NOTE;               // leave the note; the 2nd time-out resets
}

void setup() {
  Serial.begin(9600);
  pinMode(requestPin, OUTPUT);
  pinMode(readyPin, INPUT);
  if (resetNote == DOG_NOTE) {
    Serial.println("Restarted by the watchdog!");
  } else {
    Serial.println("Node started");
  }
  resetNote = 0;                      // read the note once, then wipe it
  wdt_enable(WDTO_2S);
  WDTCSR |= _BV(WDIE);                // interrupt first, then reset
}

void loop() {
  digitalWrite(requestPin, HIGH);
  digitalWrite(requestPin, LOW);
  while (digitalRead(readyPin) == LOW) {
  }
  count++;
  Serial.print("Reading ");
  Serial.println(count);
  wdt_reset();
  delay(950);
}
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 11

.noinit: the start-up code does not clear this variable.

.noinit: کۆدی دەستپێکردن ئەم پاک ناکاتەوە.

Lineدێڕی 13

Runs at the first time-out, instead of a reset.

لە یەکەم تەواوبوونی کاتدا لە جیاتی ڕیسێت کار دەکات.

Lineدێڕی 28

Switch the interrupt on after wdt_enable(): interrupt first, then reset.

دوای wdt_enable() هەڵبکە: سەرەتا ، پاشان ڕیسێت.

This trick costs one more time-out: the reset now comes 4 s after the last feed. RAM keeps this number through a reset, not through a power cut; at power-on it holds random bits, which is why the marker is a 16-bit number that is unlikely to appear by chance. If the program froze with interrupts switched off, the interrupt cannot run: the board still resets, but without a note.

ئەم فێڵە یەک تەواوبوونی کاتی زیاتری تێدەچێت: ئێستا ڕیسێتەکە 4 چرکە دوای دوایین نوێکردنەوە دێت. تێبینییەکە لە ڕیسێتدا دەهێڵێتەوە، نەک لە بڕانی کارەبادا؛ لە کاتی هەڵکردندا هەڕەمەکی تێدایە، بۆیە تێبینییەکە ژمارەیەکی ⁦16⁩ کە بە ڕێکەوت دەرکەوتنی ئەستەمە. ئەگەر بەرنامەکە لە کاتێکدا گیری خوارد کە کوژاوە بوون، ناتوانێت کار بکات: بۆردەکە هەر ڕیسێت دەبێت، بەڵام بێ تێبینی.

A timeline from 2 to 6 s. Teal line: last feed at 2.05 s. Orange line: 1st time-out at 4.05 s, where ISR(WDT_vect) runs resetNote = DOG_NOTE;. Red line: 2nd time-out at 6.05 s, the board resets but RAM is not wiped. A pink band between them: frozen, no feed. Below: .noinit is kept through a reset and random after power-on; setup() then prints "Restarted by the watchdog!".هێڵی کاتێک لە 2 تا 6 چرکە. هێڵی سەوز: دوایین نوێکردنەوە لە 2.05 چرکەدا. هێڵی پرتەقاڵی: یەکەم تەواوبوونی کات لە 4.05 چرکەدا، کە ISR(WDT_vect) فەرمانی resetNote = DOG_NOTE; جێبەجێ دەکات. هێڵی سوور: دووەم تەواوبوونی کات لە 6.05 چرکەدا، بۆردەکە ڕیسێت دەبێت بەڵام RAM پاک ناکرێتەوە. پشتێنێکی پەمەیی لە نێوانیاندا: گیرخواردوو، هیچ نوێکردنەوەیەک نییە. لە خوارەوە: .noinit لە ڕیسێتدا دەمێنێت و دوای هەڵکردن هەڕەمەکییە؛ پاشان setup() دەنووسێت "Restarted by the watchdog!".
Interrupt first, reset second: time for one last note.سەرەتا ، پاشان ڕیسێت: کات بۆ دوایین تێبینی.CêIT

Old bootloaders: the endless reset loopبارکەرەکانی بووتی کۆن: خولی بێکۆتای ڕیسێت

After a watchdog reset, the ATmega328P keeps the watchdog switched on, at its shortest time-out of 16 ms, for as long as WDRF is set. This is on purpose: a failing system keeps being reset until software deals with it. Optiboot, the UNO R3's bootloader, deals with it: it switches the watchdog off before starting your sketch. The older ATmegaBOOT bootloader, still found on the Pro Mini and on many Nano clones (the IDE's ATmega328P (Old Bootloader) option), does not: it waits for an upload, the watchdog resets it 16 ms later, and again, for ever. The sketch never starts again; only switching the power off and on clears WDRF.

دوای ، ⁦ATmega328P⁩ پاسەوانەکە بە کورتترین سنووری کاتی، ⁦16 ms⁩، هەڵکراو دەهێڵێتەوە تا ئەو کاتەی WDRF دانراوە. ئەمە بە مەبەستە: سیستەمێکی تێکچوو بەردەوام ڕیسێت دەبێت تا چارەسەری دەکات. Optiboot، ⁦UNO R3⁩، چارەسەری دەکات: پێش دەستپێکردنی پاسەوانەکە دەکوژێنێتەوە. کۆنتری ATmegaBOOT، کە هێشتا لەسەر Pro Mini و زۆر کۆپیی Nano هەیە (هەڵبژاردەی ⁦ATmega328P (Old Bootloader)⁩ـی )، چارەسەری ناکات: چاوەڕێی دەکات، پاسەوانەکە ⁦16 ms⁩ دواتر ڕیسێتی دەکات و دیسان و بۆ هەمیشە. هەرگیز دیسان دەست پێ ناکاتەوە؛ تەنیا کوژاندنەوە و هەڵکردنەوەی کارەبا WDRF پاک دەکاتەوە.

Fix: burn the UNO bootloader onto the board (Tools → Board → Arduino Uno, then Burn Bootloader, with a second Arduino or a programmer as ISP) and use it as an UNO from then on. Arduino has said that the Pro Mini, which it no longer makes, will not get a new bootloader.

چارەسەر: UNO لەسەر بۆردەکە بنووسە (Tools → Board → Arduino Uno، پاشان Burn Bootloader، بە Arduinoـیەکی دووەم یان پرۆگرامەرێک وەک ISP) و لەوە بەدواوە وەک UNO بەکاری بهێنە. Arduino ڕایگەیاندووە کە Pro Mini، کە ئیتر دروستی ناکات، نوێ وەرناگرێت.

Two rows. UNO R3 (Optiboot): watchdog reset, then the bootloader sees it is not a RESET-pin start, then watchdog off and the sketch starts, with a green tick. Old bootloader (ATmegaBOOT) on the Pro Mini and many Nano clones: watchdog reset, then the bootloader waits for an upload, then 16 ms later a reset again, and a red arrow back to the start: for ever, the sketch never starts.دوو ڕیز. UNO R3 (Optiboot): ڕیسێتی پاسەوان، پاشان بارکەری بووتەکە دەبینێت دەستپێکی پینی RESET نییە، پاشان پاسەوان دەکوژێنێتەوە و سکێچەکە دەست پێ دەکات، بە نیشانەیەکی سەوز. بارکەری بووتی کۆن (ATmegaBOOT) لەسەر Pro Mini و زۆر کۆپیی Nano: ڕیسێتی پاسەوان، پاشان بارکەری بووتەکە چاوەڕێی هەڵبارکردن دەکات، پاشان دوای 16 ms دیسان ڕیسێت و تیرێکی سوور بۆ سەرەتا: بۆ هەمیشە، سکێچەکە هەرگیز دەست پێ ناکات.
The same reset: one bootloader recovers, the other loops for ever.هەمان ڕیسێت: دەگەڕێتەوە سەر کار، ئەوی تر بۆ هەمیشە دەسووڕێتەوە.CêIT

UNO R4: another chip, another library⁦UNO R4⁩: چیپێکی تر، کتێبخانەیەکی تر

The UNO R4 Minima and the UNO R4 WiFi use a Renesas RA4M1, an Arm Cortex-M4, so avr/wdt.h does not exist there and Lab 2 does not compile. Their core brings a WDT library instead: WDT.begin(ms) starts the watchdog with a time-out from 1 to 5592 ms, and WDT.refresh() feeds it. The library has no function to stop it.

⁦UNO R4 Minima⁩ و ⁦UNO R4 WiFi⁩ چیپی ⁦Renesas RA4M1⁩ بەکار دەهێنن، کە ⁦Arm Cortex-M4⁩ـە، بۆیە avr/wdt.h لەوێ نییە و تاقیگەی 2 کۆمپایل نابێت. ناوەکیی ئەوان لە جیاتی ئەوە WDTـی تێدایە: WDT.begin(ms) پاسەوانەکە بە سنووری کاتێک لە 1 تا ⁦5592 ms⁩ دەست پێ دەکات و WDT.refresh() نوێی دەکاتەوە. هیچ بۆ ڕاگرتنی نییە.

UNO R4: the WDT library⁦UNO R4⁩: کتێبخانەی WDTr4.inoARDUINORuns on a phone (or an emulator)لەسەر مۆبایل کار دەکات
// UNO R4 Minima or WiFi: the WDT library of the UNO R4 core
#include <WDT.h>

const int requestPin = 3;
const int readyPin = 2;
int count = 0;

void setup() {
  Serial.begin(9600);
  pinMode(requestPin, OUTPUT);
  pinMode(readyPin, INPUT);
  Serial.println("Node started");
  WDT.begin(2000);                  // 1 to 5592 ms on the UNO R4
}

void loop() {
  digitalWrite(requestPin, HIGH);
  digitalWrite(requestPin, LOW);
  while (digitalRead(readyPin) == LOW) {
  }
  count++;
  Serial.print("Reading ");
  Serial.println(count);
  WDT.refresh();                    // feed
  delay(950);
}
Three cards. UNO R3, ATmega328P: #include <avr/wdt.h>, wdt_enable(WDTO_2S);, wdt_reset();, wdt_disable(); time-out from 16 ms to 8 s. UNO R4 Minima / WiFi, Renesas RA4M1: #include <WDT.h>, WDT.begin(2000);, WDT.refresh(); and no stop function; from 1 ms to 5592 ms. MKR WAN 1310, SAMD21 + SleepyDog: #include <Adafruit_SleepyDog.h>, Watchdog.enable(4000);, Watchdog.reset();, Watchdog.disable(); about 8 ms to 16 s.سێ کارت. UNO R3، ATmega328P: #include <avr/wdt.h>، wdt_enable(WDTO_2S);، wdt_reset();، wdt_disable(); سنووری کات لە 16 ms تا 8 چرکە. UNO R4 Minima / WiFi، Renesas RA4M1: #include <WDT.h>، WDT.begin(2000);، WDT.refresh(); و هیچ فەرمانێکی ڕاگرتن نییە؛ لە 1 ms تا 5592 ms. MKR WAN 1310، SAMD21 + SleepyDog: #include <Adafruit_SleepyDog.h>، Watchdog.enable(4000);، Watchdog.reset();، Watchdog.disable(); نزیکەی لە 8 ms تا 16 چرکە.
One idea, three ways to write it: check which board you have.یەک بیرۆکە، سێ ڕێگای نووسین: بزانە کام بۆردت هەیە.CêIT

MKR WAN 1310: SleepyDog on the SAMD21⁦MKR WAN 1310: SleepyDog⁩ لەسەر ⁦SAMD21⁩

The MKR WAN 1310 of this course has a SAMD21, an Arm Cortex-M0+. Its watchdog counts the ticks of a slow clock of about 1 kHz, from 8 ticks (about 8 ms) to 16,384 ticks (16 s), and it also has a window mode. The free Adafruit SleepyDog library (install it from the Library Manager) hides the registers: Watchdog.enable(ms) returns the time-out it really set, Watchdog.reset() feeds (reset again means feed) and Watchdog.resetCause() returns the chip's reset-cause register, in which PM_RCAUSE_WDT marks a watchdog reset. This is a labelled example: SleepyDog is not part of the course's kit.

⁦MKR WAN 1310⁩ـی ئەم کۆرسە ⁦SAMD21⁩ـی تێدایە، کە ⁦Arm Cortex-M0+⁩ـە. تیکەکانی کاتژمێرێکی هێواشی نزیکەی ⁦1 kHz⁩ دەژمێرێت، لە 8 تیک (نزیکەی ⁦8 ms⁩) تا ⁦16,384⁩ تیک (⁦16⁩ چرکە) و دۆخێکی پەنجەرەییشی هەیە. بێبەرانبەری Adafruit SleepyDog (لە Library Managerـەوە دایبمەزرێنە) دەشارێتەوە: Watchdog.enable(ms) ئەو سنووری کاتە دەگەڕێنێتەوە کە بە ڕاستی دایناوە، Watchdog.reset() نوێ دەکاتەوە (دیسان reset واتە نوێکردنەوە) و Watchdog.resetCause() هۆکاری ڕیسێتی چیپەکە دەگەڕێنێتەوە، کە PM_RCAUSE_WDT تێیدا نیشان دەدات. ئەمە نموونەیەکی ناونووسکراوە: SleepyDog بەشێک نییە لە کەرەستەکانی کۆرسەکە.

MKR WAN 1310: the watchdog with SleepyDog (example)⁦MKR WAN 1310⁩: پاسەوان بە SleepyDog (نموونە)mkr.inoARDUINORuns on a phone (or an emulator)لەسەر مۆبایل کار دەکات
// MKR WAN 1310 (SAMD21): the watchdog through the Adafruit SleepyDog library
#include <Adafruit_SleepyDog.h>

const int requestPin = 3;
const int readyPin = 2;
int count = 0;

void setup() {
  Serial.begin(9600);
  while (!Serial && millis() < 3000) {
    // wait for the Serial Monitor, but never more than 3 s
  }
  pinMode(requestPin, OUTPUT);
  pinMode(readyPin, INPUT);
  if (Watchdog.resetCause() & PM_RCAUSE_WDT) {
    Serial.println("Restarted by the watchdog!");
  } else {
    Serial.println("Node started");
  }
  int ms = Watchdog.enable(4000);   // returns the time-out it really set
  Serial.print("Watchdog time-out: ");
  Serial.print(ms);
  Serial.println(" ms");
}

void loop() {
  digitalWrite(requestPin, HIGH);
  digitalWrite(requestPin, LOW);
  while (digitalRead(readyPin) == LOW) {
  }
  count++;
  Serial.print("Reading ");
  Serial.println(count);
  Watchdog.reset();                 // in this library, reset() = feed
  delay(950);
}
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 10

Wait for the Serial Monitor, but never more than 3 s.

چاوەڕێی بکە، بەڵام هەرگیز زیاتر لە 3 چرکە نا.

Lineدێڕی 15

The SAMD21 keeps the reset cause; its bootloader does not clear it.

⁦SAMD21⁩ هۆکاری ڕیسێت دەهێڵێتەوە؛ پاکی ناکاتەوە.

Lineدێڕی 20

Returns the time-out it really set: 4000.

ئەو سنووری کاتە دەگەڕێنێتەوە کە بە ڕاستی دایناوە: ⁦4000⁩.

A plain while (!Serial); would wait for ever on a node with no computer attached: on boards with their own USB port, Serial is true only while the Serial Monitor is open. The watchdog is not on yet at that point, so nothing would ever restart the node.

while (!Serial);ـی ئاسایی لەسەر نۆدێک کە هیچ پێوە نەبەستراوە بۆ هەمیشە چاوەڕێ دەکات: لەسەر ئەو بۆردانەی پۆرتی خۆیان هەیە، Serial تەنیا کاتێک true دەبێت کە کراوەیە. لەو ساتەدا پاسەوانەکە هێشتا هەڵنەکراوە، بۆیە هیچ شتێک هەرگیز نۆدەکە ناخاتەوە سەر کار.

Five bars for the SAMD21 watchdog steps: 1000 ms (1024 ticks), 2000 ms (2048), 4000 ms (4096), 8000 ms (8192) and 16000 ms (16384). Below: Watchdog.enable(5000) returns 4000, because 5000 ms falls between two steps.پێنج شریت بۆ پلەکانی تایمەری پاسەوانی SAMD21: 1000 ms (1024 تیک)، 2000 ms (2048)، 4000 ms (4096)، 8000 ms (8192) و 16000 ms (16384). لە خوارەوە: Watchdog.enable(5000) 4000 دەگەڕێنێتەوە، چونکە 5000 ms دەکەوێتە نێوان دوو پلەوە.
Ask for 5 s and you get 4 s: print what enable() returns.داوای 5 چرکە بکە و 4 چرکە وەردەگریت: ئەوەی ⁦enable()⁩ دەیگەڕێنێتەوە بنووسە.CêIT

Window watchdogs and watchdog chipsتایمەرەکانی پاسەوانی پەنجەرەیی و چیپی پاسەوان

A normal watchdog catches only a program that feeds too late. A fault can also make a program feed too often: a runaway loop that calls the feed a thousand times a second looks healthy. A window watchdog accepts a feed only inside a window of time; a feed that comes too early also counts as a fault and resets the system. The SAMD21 has such a window mode, and Zephyr, an operating system for small boards, gives every watchdog a minimum and a maximum feed time.

ئاسایی تەنیا بەرنامەیەک دەگرێت کە زۆر درەنگ نوێی دەکاتەوە. هەڵەیەک دەتوانێت وا لە بەرنامەیەک بکات کە زۆر زوو زوو نوێی بکاتەوە: لەدەستدەرچوو کە هەزار جار لە چرکەیەکدا نوێکردنەوە بانگ دەکات تەندروست دەردەکەوێت. نوێکردنەوە تەنیا لەناو پەنجەرەیەکی کاتدا وەردەگرێت؛ نوێکردنەوەیەک کە زۆر زوو بێت بە هەڵەش دادەنرێت و سیستەمەکە ڕیسێت دەکات. ⁦SAMD21⁩ دۆخێکی پەنجەرەیی وای هەیە و Zephyr، بۆ بۆردە بچووکەکان، کەمترین و زۆرترین کاتی نوێکردنەوە دەدات بە هەر پاسەوانێک.

An internal watchdog shares the chip, the power and often the settings with the program it watches. Boards that must not fail add an external watchdog chip with its own clock: the microcontroller feeds it with a pulse on a pin, and the chip pulls the microcontroller's RESET pin when the pulses stop, or, for a window chip, come too fast. Software cannot switch it off.

پاسەوانێکی ناوەکی چیپ، کارەبا و زۆرجار ڕێکخستنەکانیش لەگەڵ ئەو بەرنامەیەدا هاوبەشە کە چاودێری دەکات. ئەو بۆردانەی نابێت تێکبچن چیپێکی پاسەوانی دەرەکی زیاد دەکەن کە کاتژمێری خۆی هەیە: بە لەسەر پینێک نوێی دەکاتەوە و چیپەکە پینی RESETـی دادەگرێت کاتێک تڕپەکان دەوەستن یان، بۆ چیپێکی پەنجەرەیی، زۆر خێرا دێن. ناتوانێت بیکوژێنێتەوە.

Top: a bar of time after the last feed with three parts: a red closed window (a feed here is too early, reset), a teal open window (a feed here is fine) and a red part at the end (too late, reset). Note: a runaway loop that feeds a thousand times a second is caught too. Bottom: a microcontroller sends pulses (feed, WDI) to a watchdog chip with its own clock, and the chip answers on the RESET pin; software cannot switch it off.سەرەوە: شریتێکی کات لە دوایین نوێکردنەوەوە بە سێ بەش: پەنجەرەی داخراوی سوور (نوێکردنەوە لێرە زووە، ڕیسێت)، پەنجەرەی کراوەی سەوز (نوێکردنەوە لێرە باشە) و بەشێکی سوور لە کۆتاییدا (زۆر درەنگ، ڕیسێت). تێبینی: خولێکی لەدەستدەرچوو کە هەزار جار لە چرکەیەکدا نوێ دەکاتەوە دەگیرێت. خوارەوە: مایکرۆکۆنترۆڵەرێک تڕپەکان (نوێکردنەوە، WDI) دەنێرێت بۆ چیپێکی پاسەوان بە کاتژمێری خۆیەوە و چیپەکە لەسەر پینی RESET وەڵام دەداتەوە؛ نەرمەواڵە ناتوانێت بیکوژێنێتەوە.
Not too early, not too late; and a guard that lives outside the chip.نە زۆر زوو، نە زۆر درەنگ؛ و پاسەوانێک کە لە دەرەوەی چیپەکە دەژی.CêIT

Watchdogs beyond microcontrollersپاسەوان لە دەرەوەی مایکرۆکۆنترۆڵەرەکان

Linux computers, such as an IoT gateway or a server, often have a hardware watchdog too. The Linux kernel shows it as the file /dev/watchdog: a program writes to it regularly (a watchdog daemon, or systemd itself through RuntimeWatchdogSec=), and if the writes stop, the hardware reboots the machine. One level higher, systemd watches services: with WatchdogSec=30 a service must send WATCHDOG=1 at least every 30 s, or systemd marks it as failed and, with Restart=on-watchdog, starts it again, with no reboot.

Linux، وەک IoT یان ، زۆرجار ڕەقەواڵەییشیان هەیە. Linux وەک فایلی /dev/watchdog پیشانی دەدات: بەرنامەیەک بە ڕێکی دەنووسێتە ناوی ( پاسەوان، یان خودی systemd بە RuntimeWatchdogSec=) و ئەگەر نووسینەکان بوەستن، ئامێرەکە دەست پێ دەکاتەوە (). ئاستێک سەرتر، systemd چاودێریی دەکات: بە WatchdogSec=30 دەبێت لانیکەم هەر ⁦30⁩ چرکە جارێک WATCHDOG=1 بنێرێت، ئەگەرنا systemd وەک تێکچوو نیشانی دەکات و، بە Restart=on-watchdog، دیسان دەستی پێ دەکاتەوە، بێ دەستپێکردنەوەی هەموو ئامێرەکە.

Drones use the same idea. ArduPilot flight controllers have an independent watchdog that restarts the processor when its main loop hangs and logs a WDG message; the ArduPilot documentation warns that this may or may not save the vehicle in flight. The link-loss failsafes are time-outs too, but they watch the radio link, not the processor: see Failsafes: planned reactions and The drone's brain.

هەمان بیرۆکە بەکار دەهێنن. ArduPilot پاسەوانێکی سەربەخۆیان هەیە کە کاتێک خولی سەرەکی گیر دەخوات دەست پێ دەکاتەوە و پەیامی WDG تۆمار دەکات؛ بەڵگەنامەکانی ArduPilot ئاگادار دەکەنەوە کە ئەمە لەوانەیە لە کاتی فڕیندا ئامێرەکە ڕزگار بکات یان نا. پچڕانی پەیوەندیش سنووری کاتن، بەڵام چاودێریی پەیوەندیی ڕادیۆ دەکەن، نەک : سەلامەتیی کاتی تێکچوون: کاردانەوەی پلانبۆدانراو و مێشکی درۆنەکە ببینە.

Left, a Linux computer (a gateway, a server) as four stacked boxes: a service sends WATCHDOG=1 often (WatchdogSec=30); systemd restarts the service when the ping does not come (Restart=on-watchdog); systemd pings /dev/watchdog (RuntimeWatchdogSec=); the hardware watchdog restarts the computer when no ping comes. Right, a drone flight controller: an independent watchdog restarts the CPU when the main loop hangs and logs WDG (ArduPilot); link-loss failsafes: no radio signal for 1 s leads to return home or land, a time-out that watches the link, not the CPU.چەپ، کۆمپیوتەری Linux (دەروازەی ڕایەڵە، ڕاژەکار) وەک چوار سندوقی سەریەک: خزمەتگوزارییەک زوو زوو WATCHDOG=1 دەنێرێت (WatchdogSec=30)؛ systemd کاتێک پینگ نایەت خزمەتگوزارییەکە دەست پێ دەکاتەوە (Restart=on-watchdog)؛ systemd پینگ دەنێرێت بۆ /dev/watchdog (RuntimeWatchdogSec=)؛ تایمەری پاسەوانەکە کاتێک پینگ نایەت کۆمپیوتەرەکە دەست پێ دەکاتەوە. ڕاست، کۆنترۆڵکەری فڕینی درۆن: پاسەوانێکی سەربەخۆ کاتێک خولی سەرەکی گیر دەخوات CPU دەست پێ دەکاتەوە و WDG تۆمار دەکات (ArduPilot)؛ سەلامەتیی کاتی تێکچوون بۆ پچڕانی پەیوەندی: 1 چرکە بێ سیگناڵی ڕادیۆ ← گەڕانەوە بۆ ماڵ یان نیشتنەوە، سنووری کاتێک کە چاودێریی پەیوەندییەکە دەکات، نەک CPU.
The same idea at every level: a time limit for a sign of life.هەمان بیرۆکە لە هەموو ئاستێکدا: سنووری کاتێک بۆ نیشانەیەکی ژیان.CêIT

The everyday word 'watchdog'وشەی ڕۆژانەی «watchdog»

Outside electronics you will meet watchdog in the news. Literally, a watchdog is a dog that guards a house. Figuratively, it is a person or an organisation that watches companies or governments for illegal or unfair behaviour: a privacy watchdog, a consumer watchdog, a media watchdog. News reports often call a data-protection authority, the body that enforces Europe's GDPR in each country, a privacy watchdog.

لە دەرەوەی ئەلیکترۆنیات watchdog لە هەواڵەکاندا دەبینیت. بە واتای ڕاستەقینە، سەگێکە کە ماڵێک دەپارێزێت. بە واتای خوازراو، کەسێک یان دەزگایەکە کە چاودێریی کۆمپانیا یان حکومەتەکان دەکات بۆ ڕەفتاری نایاسایی یان نادادپەروەرانە: privacy watchdog، consumer watchdog، media watchdog. هەواڵەکان زۆرجار بە ، ئەو دەزگایەی کە لە هەر وڵاتێکدا ئەوروپا جێبەجێ دەکات، دەڵێن privacy watchdog.

English sentenceڕستەی ئینگلیزیWhat 'watchdog' means herewatchdog لێرەدا واتای چییە
The privacy watchdog fined the company for collecting data without consent.The privacy watchdog fined the company for collecting data without consent.a data-protection authority
Consumer watchdogs warned buyers about unsafe smart plugs.Consumer watchdogs warned buyers about unsafe smart plugs.organisations that protect buyersئەو دەزگایانەی کڕیاران دەپارێزن
The watchdog reset the node twice last night.The watchdog reset the node twice last night.the watchdog timer of this lesson ئەم وانەیە

In Kurdish news such an organisation is usually a «دەزگای چاودێری», an observing body, while the timer of this lesson is the «تایمەری پاسەوان». How GDPR authorities work is taught in Laws that protect data and people.

لە هەواڵی کوردیدا دەزگایەکی وا زۆرجار «دەزگای چاودێری»یە، لە کاتێکدا ئەم وانەیە . چۆنیەتیی کارکردنی دەسەڵاتەکانی GDPR لە ئەو یاسایانەی دراوە و خەڵک دەپارێزندا فێر دەکرێت.

Three panels. A guard dog by a gate: it guards a house and barks. A chip marked WDT with a small red clock: a watchdog timer, it resets a frozen device. A public building with a magnifying glass: a watchdog body, it watches companies and government.سێ پانێڵ. سەگێکی پاسەوان لە تەنیشت دەرگایەک: ماڵێک دەپارێزێت و دەوەڕێت. چیپێک بە نیشانەی WDT و کاتژمێرێکی سووری بچووک: تایمەری پاسەوان، ئامێرێکی گیرخواردوو ڕیسێت دەکات. باڵەخانەیەکی گشتی بە زەرەبینێکەوە: دەزگایەکی چاودێر، چاودێریی کۆمپانیا و حکومەت دەکات.
Same word, three jobs: guard, restart, watch.هەمان وشە، سێ کار: پاراستن، دەستپێکردنەوە، چاودێری.CêIT

Common mistakesهەڵە باوەکان

MistakeهەڵەWhat you seeچی دەبینیتBetterباشتر
Feeding inside a loop that waitsنوێکردنەوە لەناو خولێک کە چاوەڕێ دەکاتThe node stays frozen for ever with its watchdog on.نۆدەکە بە پاسەوانی هەڵکراوەوە بۆ هەمیشە گیرخواردوو دەمێنێتەوە.Feed once, at the end of a complete round; give waits a time limit.یەک جار نوێی بکەرەوە، لە کۆتایی گەڕێکی تەواودا؛ سنووری کات بدە بە چاوەڕێکردنەکان.
A time-out shorter than a healthy round (delay(5000) with WDTO_2S)سنووری کاتێک کورتتر لە گەڕێکی تەندروست (delay(5000) لەگەڵ WDTO_2S)Reset after reset; the node never gets past its first reading.ڕیسێت لەدوای ڕیسێت؛ نۆدەکە هەرگیز لە یەکەم خوێندنەوە تێناپەڕێت.Measure the longest round, allow about twice as long, or use millis() instead of long delay()s.درێژترین گەڕ بپێوە، نزیکەی دوو هێندە ڕێگە بدە، یان millis() لە جیاتی delay()ـی درێژ بەکار بهێنە.
Feeding from a timer interruptنوێکردنەوە لە The timer keeps feeding while loop() is stuck. بەردەوام نوێ دەکاتەوە لە کاتێکدا loop() گیری خواردووە.Feed from loop(), when every job has checked in.لە loop()ـەوە نوێی بکەرەوە، کاتێک هەموو کارێک ئامادەیی خۆی نیشان داوە.
Reading MCUSR in setup() on a stock UNO R3خوێندنەوەی MCUSR لە setup()ـدا لەسەر ⁦UNO R3⁩ـی ئاساییAlways 0: the bootloader cleared it.هەمیشە 0: پاکی کردووەتەوە.Let the watchdog interrupt leave a note in .noinit, or use a bootloader that keeps the flags.با پاسەوان تێبینییەک لە .noinitـدا دابنێت، یان بەکار بهێنە کە ئەو دەهێڵێتەوە.
The old ATmegaBOOT bootloader (Pro Mini, many Nano clones) کۆنی ⁦ATmegaBOOT (Pro Mini⁩، زۆر کۆپیی Nano)An endless reset loop after the first watchdog reset.خولێکی بێکۆتای ڕیسێت دوای یەکەم .Burn the UNO (Optiboot) bootloader. ⁦UNO (Optiboot)⁩ بنووسە.
#include <avr/wdt.h> on an UNO R4 or an MKR board#include <avr/wdt.h> لەسەر ⁦UNO R4⁩ یان بۆردێکی MKRIt does not compile.کۆمپایل نابێت.WDT.h on the UNO R4; a SAMD library such as SleepyDog on MKR boards.WDT.h لەسەر ⁦UNO R4⁩؛ SAMD وەک SleepyDog لەسەر بۆردەکانی MKR.
while (!Serial); on an unattended MKR nodewhile (!Serial); لەسەر نۆدێکی MKRـی بێ کەسIt waits for ever without a computer.بەبێ بۆ هەمیشە چاوەڕێ دەکات.Add a time limit: while (!Serial && millis() < 3000).سنووری کات زیاد بکە: while (!Serial && millis() < 3000).
Trusting the watchdog to fix the bugپشت بەستن بە پاسەوان بۆ چاککردنی The node keeps restarting and losing data.نۆدەکە بەردەوام دەست پێ دەکاتەوە و لەدەست دەدات.Count and report restarts, then find and fix the cause.دەستپێکردنەوەکان بژمێرە و ڕاپۆرتیان بدە، پاشان هۆکارەکە بدۆزەرەوە و چاکی بکە.

Exercisesڕاهێنانەکان

ExerciseڕاهێنانOne reading every 5 s, with a 2 s watchdogهەر 5 چرکە خوێندنەوەیەک، بە پاسەوانی 2 چرکە

Rewrite Lab 2 so that it reads every 5 seconds while the watchdog stays at WDTO_2S. No delay() may be longer than the time-out.

تاقیگەی 2 دووپاتە بنووسەوە بۆ ئەوەی هەر 5 چرکە جارێک بخوێنێتەوە لە کاتێکدا پاسەوانەکە لەسەر WDTO_2S دەمێنێتەوە. نابێت هیچ delay()ـێک لە سنووری کات درێژتر بێت.

Hintئاماژە

Remember the time of the last reading with millis(), and let loop() come round quickly.

کاتی دوایین خوێندنەوە بە millis() لەبیر بێت و با loop() بە خێرایی بسووڕێتەوە.

Show answerوەڵامەکە پیشان بدە
Answer: millis() instead of delay(5000)وەڵام: ⁦millis()⁩ لە جیاتی ⁦delay(5000)⁩ex_millis.inoARDUINORuns on a phone (or an emulator)لەسەر مۆبایل کار دەکات
// One reading every 5 s with a 2 s watchdog: millis() instead of delay(5000)
#include <avr/wdt.h>

const int requestPin = 3;
const int readyPin = 2;
const unsigned long interval = 5000;   // ms between readings
unsigned long lastReading = 0;
int count = 0;

void setup() {
  Serial.begin(9600);
  pinMode(requestPin, OUTPUT);
  pinMode(readyPin, INPUT);
  Serial.println("Node started");
  wdt_enable(WDTO_2S);
}

void loop() {
  if (millis() - lastReading >= interval) {
    lastReading = millis();
    digitalWrite(requestPin, HIGH);
    digitalWrite(requestPin, LOW);
    while (digitalRead(readyPin) == LOW) {
    }
    count++;
    Serial.print("Reading ");
    Serial.println(count);
  }
  wdt_reset();                         // every short round of loop() feeds
}

A round of loop() now takes microseconds, so feeding at its end still means 'the program is going round'. millis() is explained in millis(): check the clock instead of waiting.

ئێستا گەڕێکی loop() چەند میکرۆچرکەیەک دەخایەنێت، بۆیە نوێکردنەوە لە کۆتاییەکەیدا هێشتا واتای «بەرنامەکە دەسووڕێتەوە»یە. millis() لە ⁦millis()⁩: لە جیاتی چاوەڕێکردن سەیری کاتژمێر بکەدا ڕوون کراوەتەوە.

ExerciseڕاهێنانFix the cause: a wait with a time limitهۆکارەکە چاک بکە: چاوەڕێیەک بە سنووری کات

Give the wait for READY a limit of 200 ms. When no answer comes, print a message and carry on, so that a lost request no longer needs the watchdog.

سنووری ⁦200 ms⁩ بدە بە چاوەڕێکردنی READY. کاتێک هیچ وەڵامێک نایەت، پەیامێک بنووسە و بەردەوام بە، بۆ ئەوەی داواکارییەکی ونبوو ئیتر پێویستی بە پاسەوان نەبێت.

Hintئاماژە

Write a function waitForReady(limitMs) that returns true or false.

waitForReady(limitMs) بنووسە کە true یان false دەگەڕێنێتەوە.

Show answerوەڵامەکە پیشان بدە
Answer: waitForReady() with a time limitوەڵام: ⁦waitForReady()⁩ بە سنووری کاتex_timeout.inoARDUINORuns on a phone (or an emulator)لەسەر مۆبایل کار دەکات
// Fix the cause: wait for READY with a time limit
#include <avr/wdt.h>

const int requestPin = 3;
const int readyPin = 2;
int count = 0;

bool waitForReady(unsigned long limitMs) {
  unsigned long start = millis();
  while (digitalRead(readyPin) == LOW) {
    if (millis() - start >= limitMs) {
      return false;                    // no answer in time: give up
    }
  }
  return true;
}

void setup() {
  Serial.begin(9600);
  pinMode(requestPin, OUTPUT);
  pinMode(readyPin, INPUT);
  Serial.println("Node started");
  wdt_enable(WDTO_2S);
}

void loop() {
  digitalWrite(requestPin, HIGH);
  digitalWrite(requestPin, LOW);
  if (waitForReady(200)) {
    count++;
    Serial.print("Reading ");
    Serial.println(count);
  } else {
    Serial.println("No answer: asking again next time");
  }
  wdt_reset();                         // the program is still in control
  delay(950);
}

The watchdog stays switched on as the last safety net for faults nobody foresaw; the time limit handles the fault you know about.

پاسەوانەکە هەڵکراو دەمێنێتەوە وەک دوایین تۆڕی سەلامەتی بۆ ئەو هەڵانەی کەس پێشبینی نەکردوون؛ سنووری کات ئەو هەڵەیە چارەسەر دەکات کە دەیزانیت.

ExerciseڕاهێنانChoose the time-outسنووری کات هەڵبژێرە

Choose a WDTO_ constant for an UNO R3 node and say why: (a) its slowest round takes 300 ms; (b) a radio send can take up to 1.5 s; (c) it must wait 20 s between readings.

نەگۆڕێکی WDTO_ بۆ نۆدێکی ⁦UNO R3⁩ هەڵبژێرە و بڵێ بۆچی: ⁦(a)⁩ هێواشترین گەڕی ⁦300 ms⁩ دەخایەنێت؛ ⁦(b)⁩ ناردنێکی ڕادیۆ دەتوانێت تا ⁦1.5⁩ چرکە بخایەنێت؛ ⁦(c)⁩ دەبێت ⁦20⁩ چرکە لە نێوان خوێندنەوەکاندا چاوەڕێ بکات.

Show answerوەڵامەکە پیشان بدە
  • (a) WDTO_1S: more than three times the slowest round. WDTO_500MS would leave too little room.
  • (b) WDTO_4S: about two and a half times 1.5 s. WDTO_2S would leave only 0.5 s.
  • (c) No constant is that long: 8 s is the maximum. Keep the rounds short and wait with millis(), as in the first exercise.
  • ⁦(a)⁩ WDTO_1S: زیاتر لە سێ هێندەی هێواشترین گەڕ. WDTO_500MS شوێنی زیادەی کەم دەهێڵێتەوە.
  • ⁦(b)⁩ WDTO_4S: نزیکەی دوو و نیو هێندەی ⁦1.5⁩ چرکە. WDTO_2S تەنیا ⁦0.5⁩ چرکە دەهێڵێتەوە.
  • ⁦(c)⁩ هیچ نەگۆڕێک ئەوەندە درێژ نییە: 8 چرکە زۆرترینە. گەڕەکان کورت بهێڵەوە و بە millis() چاوەڕێ بکە، وەک لە یەکەم ڕاهێنان.
ExerciseڕاهێنانSleepyDog's stepsپلەکانی SleepyDog

On the MKR WAN 1310, what does Watchdog.enable() return for 1500, 3000, 8000 and 20000 ms?

لەسەر ⁦MKR WAN 1310⁩، Watchdog.enable() بۆ ⁦1500⁩، ⁦3000⁩، ⁦8000⁩ و ⁦20000 ms⁩ چی دەگەڕێنێتەوە؟

Hintئاماژە

ms × 1.024 gives ticks; take the largest power of two that fits, from 8 to 16,384.

⁦ms × 1.024⁩ تیکەکان دەدات؛ گەورەترین توانی 2 هەڵبژێرە کە جێی دەبێتەوە، لە 8 تا ⁦16,384⁩.

Show answerوەڵامەکە پیشان بدە
AskedداواکراوTicksتیکStepپلەReturnedگەڕێنراوە
1500 ms153610241000 ms
3000 ms307220482000 ms
8000 ms819281928000 ms
20000 ms16000 ms or more⁦16000 ms⁩ یان زیاتر1638416000 ms

Always print what enable() returns: the watchdog you get may be shorter than the one you asked for.

هەمیشە ئەوەی enable() دەیگەڕێنێتەوە بنووسە: لەوانەیە ئەو پاسەوانەی وەری دەگریت کورتتر بێت لەوەی داوات کردووە.

Summaryپوختە

  • A watchdog timer resets a frozen device by itself: the program must feed it in time, or the count reaches its time-out.
  • UNO R3: #include <avr/wdt.h>, wdt_enable(WDTO_2S), and wdt_reset() once at the end of each good round. It runs on its own 128 kHz clock, from 16 ms to 8 s.
  • Never feed inside a waiting loop or from a timer interrupt; never block longer than the time-out.
  • A reset sets every pin to input and every variable to its first value; setup() runs again.
  • MCUSR's WDRF records a watchdog reset, but the UNO R3's bootloader clears it: use the interrupt-and-reset mode to leave a note in .noinit. Old ATmegaBOOT bootloaders loop for ever after a watchdog reset.
  • UNO R4: WDT.begin(ms) and WDT.refresh(); MKR WAN 1310: SleepyDog's Watchdog.enable(), Watchdog.reset() and resetCause().
  • Window watchdogs also catch feeds that come too early; external watchdog chips have their own clock and cannot be switched off. Linux, systemd and drones use the same idea.
  • In the news, a watchdog is an organisation that watches for wrongdoing, such as a data-protection authority.
  • خۆی ئامێرێکی گیرخواردوو ڕیسێت دەکات: بەرنامەکە دەبێت لە کاتی خۆیدا نوێی بکاتەوە، ئەگەرنا ژماردنەکە دەگاتە سنووری کات.
  • ⁦UNO R3⁩: #include <avr/wdt.h>، wdt_enable(WDTO_2S) و wdt_reset() یەک جار لە کۆتایی هەر گەڕێکی باشدا. بە کاتژمێری ⁦128 kHz⁩ـی خۆی کار دەکات، لە ⁦16 ms⁩ تا 8 چرکە.
  • هەرگیز لەناو خولی چاوەڕێدا یان لە نوێی مەکەرەوە؛ هەرگیز لە سنووری کات زیاتر ڕامەگرە.
  • ڕیسێت هەموو پینێک دەکاتە و هەموو دەگەڕێنێتەوە بۆ بەهای یەکەمی؛ setup() دیسان کار دەکات.
  • WDRFـی MCUSR تۆمار دەکات، بەڵام ⁦UNO R3⁩ پاکی دەکاتەوە: دۆخی و پاشان ڕیسێت بەکار بهێنە بۆ دانانی تێبینییەک لە .noinitـدا. کۆنی ATmegaBOOT دوای بۆ هەمیشە دەسووڕێنەوە.
  • ⁦UNO R4⁩: WDT.begin(ms) و WDT.refresh()؛ ⁦MKR WAN 1310⁩: Watchdog.enable()، Watchdog.reset() و resetCause()ـی SleepyDog.
  • نوێکردنەوەی زۆر زوویش دەگرن؛ چیپە دەرەکییەکانی پاسەوان کاتژمێری خۆیان هەیە و ناکوژێنرێنەوە. Linux، systemd و هەمان بیرۆکە بەکار دەهێنن.
  • لە هەواڵەکاندا، watchdog دەزگایەکە کە چاودێریی هەڵەکاری دەکات، وەک .
Review questionsپرسیارەکانی پێداچوونەوە
What can a watchdog not do?پاسەوان چی ناتوانێت بکات؟

It cannot find or fix the cause. It only restarts the device, and a fault that comes back makes the node restart again and again.

ناتوانێت هۆکارەکە بدۆزێتەوە یان چاکی بکات. تەنیا ئامێرەکە دەست پێ دەکاتەوە و هەڵەیەک کە بگەڕێتەوە وا لە نۆدەکە دەکات جار لەدوای جار دەست پێ بکاتەوە.

Why should a node with a watchdog still put time limits on its waits?بۆچی نۆدێک کە پاسەوانی هەیە هێشتا دەبێت سنووری کات بۆ چاوەڕێکانی دابنێت؟

A time limit handles a known problem at once and keeps the data in RAM; the watchdog is the last net for faults nobody foresaw.

سنووری کات کێشەیەکی ناسراو دەستبەجێ چارەسەر دەکات و ناو دەپارێزێت؛ پاسەوان دوایین تۆڕە بۆ ئەو هەڵانەی کەس پێشبینی نەکردوون.

Why does the reset in the .noinit sketch come 4 s after the last feed instead of 2 s?بۆچی لە سکێچی .noinitـدا ڕیسێتەکە 4 چرکە دوای دوایین نوێکردنەوە دێت نەک 2 چرکە؟

In interrupt-and-reset mode the first time-out runs ISR(WDT_vect); only the second time-out resets the board.

لە دۆخی و پاشان ڕیسێتدا، یەکەم تەواوبوونی کات ISR(WDT_vect) جێبەجێ دەکات؛ تەنیا دووەم تەواوبوونی کات بۆردەکە ڕیسێت دەکات.

Lesson complete!وانەکە تەواو بوو!

Well done. Review the key terms, then go on to the next lesson.دەستخۆش. سەیرێکی زاراوە سەرەکییەکان بکەرەوە، پاشان بڕۆ بۆ وانەی داهاتوو.

Key termsزاراوە سەرەکییەکان

Next lessonوانەی داهاتوو

Sensors: How Things Feel the Worldهەستەوەرەکان: شتەکان چۆن هەست بە جیهان دەکەن

Related lecturesوانە پەیوەندیدارەکان

References and further readingسەرچاوەکان و خوێندنەوەی زیاتر

This lecture is a first edition. The Kurdish text and terminology are waiting for review by Kurdish IT teachers.ئەم وانەیە چاپی یەکەمە. دەقە کوردییەکە و زاراوەکانی چاوەڕێی پێداچوونەوەی مامۆستایانی کوردی بواری IT ن.

Appearanceڕووکار

Modeدۆخ
Styleشێواز
Coloursڕەنگەکان

Saved on this device only.تەنیا لەسەر ئەم ئامێرە پاشەکەوت دەکرێت.