arduinoで、WDTによるリセットが繰り返しちゃう問題
ここと同じ問題が発生して、困っていました。
使っていた、ICは、
ATtiny84
です。
どんな問題か。
正解にたどりついているか、わからないが、私の症状はこう。
#include <avr/wdt.h>
をつかって、プログラムを作成中、妙な挙動に気が付いた。
wdt_enable(WDTO_8S);
をつかって、WDTを起動。 その後 WDTを止めるべく、(スリープ状態にするため)
wdt_disable();
を入れるが、そのコマンドが実行された後も
WDTの最小時間である、15msでリセットがかかり続ける
再び、wdt_enable(WDTO_8S);を実行すると、
WDTは、8秒おきにかかるので、wdt_enableのコマンドは受け付けているようだ。
wdt_disable();で、8秒のWDTは無効化されるものの、 その後は、
15msでリセットがかかり続ける謎現状。これでは、8秒以上のディレイを入れたい時に困る。
しかも驚いた事に、wdt_enableの記述の無い、まったく別のプログラムを書き込んでも、
その石では、WDTが15msで動き続けるという謎現象が発生した。
つまり、プログラム領域とは別に、この石のどこかにWDTを常時ONの状態に設定してしまったようで、 その影響で、wdt_disable();だけでは、WDTを完全に無効にすることが出来なくなってしまったようだ。
トリガーはスリープを走らせたところっぽい。
そういう場合は、Arduino IDEのツールのボードマネージャのどこかに、WDT Disable 的な
config設定がありそうなのだが、無かった。。
で、よくよくデータシートを読んでいたら、
コード例に
void WDT_off(void)
{
_WDR(); /* ウォッチドッグ タイマ リセット /
MCUSR = 0x00; / MCUSRのWDRFを解除(0) /
WDTCSR |= (1<<WDCE)|(1<<WDE); / WDCEとWDEに論理1書き込み /
WDTCSR = 0x00; / ウォッチドッグ禁止 */
}
というのがあったので、
MCUSR = 0x00; /* MCUSRのWDRFを解除(0) /
WDTCSR |= (1<<WDCE)|(1<<WDE); / WDCEとWDEに論理1書き込み /
WDTCSR = 0x00; / ウォッチドッグ禁止 */
を、プログラム冒頭に入れたところ、勝手に動いている15MSのWDTを止める事ができ、
無限リセットは収まった。
電子牛乳のサイトのコメント欄のやり取りを見ると、
ブートローダを一緒に書き込むと、無限ループが発生しないとあるので、
無限ループを完全に止めるには、やはり、プログラム領域外にWDTのON/OFFのconfigがあると
思われる。
なので、wdt_disable();だけでは、WDTが止まらなくなるのだろう。
たしか、PICのライタを使っていたころも、WDTのオンオフは、コンフィグ設定にあったから、
別のライタをつかえば、問題の根本にはたどり着けるとは思う。