なんでも作っちゃう、かも。

Arduino/Make/フィジカルコンピューティング/電子工作あたりで活動しています。スタバの空きカップを使ったスタバカップアンプなど製作。最近はもっぱらArduinoと3Dプリンタの自作に興味があります。

Arduinoで遊ぼう - ウォッチドッグタイマを使う

Posted by arms22 on 2009年01月25日 12  0

Arduinoでウォッチドッグタイマを使うにはavr/wdt.hをインクルードし、wdt_enable関数、wdt_reset関数を使う。

#include <avr/wdt.h>

void setup(){
  wdt_enable(WDTO_2S);
}

void loop(){
  do_something();
  wdt_reset();
}
ウォッチドッグタイマは計時が完了したら割り込み、リセット、または割り込み+リセットを発生させる。wdt_enable関数は計時完了時にリセットを発生させる様、ウォッチドッグタイマを設定する。しかしリセットを発生させず割り込みだけ発生させるようにすれば簡易タイマとして、またウォッチドッグの割り込みはシステムをスリープから起動させる為にも使える。
例によってウォッチドッグタイマを使う為のWatchdogライブラリを作成した。

ダウンロード:Watchdogライブラリ
http://xfind.hp.infoseek.co.jp/electric/arduino/Watchdog001.zip

使い方
1.Watchdogライブラリをarduino-0012/hardware/libraries/以下にコピーする。
2.新しいスケッチを作成する。
3.メニューからSketch > Import Library > Watchdogを選択する。

サンプルスケッチ:ウォッチドッグタイマ
#include <Watchdog.h>

void setup(){
  Watchdog::systemResetEnable(true);
  Watchdog::enable(Watchdog::TimeOut2s);
}

void loop(){
  do_something();
  Watchdog::timerReset();
}

サンプルスケッチ:簡易タイマ
1秒周期で繰り返しcycle1s関数が呼び出されます。
#include <Watchdog.h>

void cycle1s(void){
  static bool flag = 1;
  digitalWrite(13,flag);
  flag = !flag;
}

void setup(void){
  pinMode(13,OUTPUT);
  Watchdog::attachInterrupt(cycle1s);
  Watchdog::systemResetEnable(false);
  Watchdog::enable(Watchdog::TimeOut1s);
}

void loop(void){
}

サンプルスケッチ:スリープからの復帰
ウォッチドッグ割り込みによりスリープ動作から復帰し、LEDを0.5秒周期で点滅させます。
#include <Watchdog.h>
#include <Sleep.h>

void setup() {
  pinMode(13,OUTPUT);
  Watchdog::systemResetEnable(false);
  Watchdog::enable(Watchdog::TimeOut250ms);
}

void loop() {
  digitalWrite(13,HIGH);
  Watchdog::timerReset();
  Sleep::powerDown();

  digitalWrite(13,LOW);
  Watchdog::timerReset();
  Sleep::powerDown();
}

avr-libc: Watchdog timer handling
http://www11.ocn.ne.jp/~akibow/avr-libc-user-manual-1.4.3/group__avr__watchdog.html


Making Things Talk -Arduinoで作る「会話」するモノたち
Tom Igoe
オライリージャパン
売り上げランキング: 56322

Ads by Google

12 Comments

says..."管理人のみ閲覧できます"
このコメントは管理人のみ閲覧できます
2009.12.08 02:58 | | # [edit]
arms22 says..."Re: ウォッチドッグタイマのライブラリについて"
現状、考えられるのはクロックとマイコンの種類でしょうか。
私が動作確認した環境はArduino Duemilanoveです。DuemilanoveはATmega168を16MHz駆動しています。
Arduino pro mini 328はATmega328を8MHzで駆動しているので、その辺が関係していそうですね。


動作がおかしい時の具体的な挙動を教えてください。
2009.12.08 08:58 | URL | #- [edit]
says..."管理人のみ閲覧できます"
このコメントは管理人のみ閲覧できます
2010.11.03 19:58 | | # [edit]
arms22 says..."Re: watchdogライブラリ"
現在、Googleのプロジェクトホスティングサービスを使ってコードを管理しています。
圧縮して固めたパッケージはありませんが、ここからソースコードをDLできます。

http://code.google.com/p/arms22/source/browse/#svn/trunk/Watchdog
2010.11.04 11:55 | URL | #- [edit]
初心者 says..."No title"
とても参考になる情報をいろいろありがとうございます。利用させていただいています。
Watchdog001ライブラリーを使用したところ、arduinoのブートローダーが壊れる現象を3回体験しましたのでご報告いたします。Arduino0018、Arduino Duemilanoveにて下記のスケッチを使用しました。どこかに不具合があるのでしょうか?

#include <Watchdog.h>
int n = 0;
int ledPin = 13;

void setup(){
Watchdog::systemResetEnable(true);
Watchdog::enable(Watchdog::TimeOut4s);
pinMode(ledPin, OUTPUT);
}

void loop(){
// do_something();
n = n+1;
if (n < 10) Watchdog::timerReset();
digitalWrite(ledPin, HIGH); // set the LED on
delay(1000); // wait for a second
digitalWrite(ledPin, LOW); // set the LED off
delay(1000); // wait for a second
}
2010.11.21 14:23 | URL | #- [edit]
初心者 says..."自己解決しました"
新しいブートローダー「Optiboot」はウォッチドッグタイマに対応しているようですが、古いブートローダーはリセットを繰り返してしまうらしくて上手く動作しなかったようですね。(例えば↓)
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1278573986/11

下のやり方でブートロダーを新しくしたら問題解決しました。
http://code.google.com/p/optiboot/
2010.11.21 21:44 | URL | #- [edit]
arms22 says..."Re: 自己解決しました"
ウォッチドックでリセットは試してなかったので気がつきませんでした。
これはUNO以前のArduinoでは要注意ですね。
情報ありがとうございます。
2010.11.21 23:33 | URL | #- [edit]
rodan says..."ArduinoMegaでのウオッチドッグタイマー"
いつも参考にさせて頂いておりましてありがとうございます。

今回はウオッチドッグタイマーでわからないところがありますので投稿させていただきました。

下記のスケッチを走らせたところUNOでは問題なく動作しますが、Megaではウオッチドッグタイマーが働いた時点でリスタートせずにハングアップしてしまいます。
ハングアップした状態ではボードのリセットSWも聞かなくなり、電源をOFF/ONしないと再スタートしません。

UNOもMegaもR3でIDEは1.0.1です。
もしなにかご存知なら教えてください。

以下スケッチ
(なお、スケッチそのもは他のサイトに掲載されていたものです)

#include <avr/wdt.h>
unsigned long ToggleDelay;

void setup()
{
wdt_disable();
ToggleDelay = 100;
pinMode(13, OUTPUT);

delay(4000);

wdt_enable(WDTO_2S);
}

void loop()
{
  wdt_reset();

digitalWrite(13, HIGH); // set the LED on
delay(ToggleDelay); // wait for a second
digitalWrite(13, LOW); // set the LED off
delay(ToggleDelay); // wait for a second

ToggleDelay += 100;
}
2012.07.10 23:19 | URL | #O0C0V3Oc [edit]
arms22 says..."Re: ArduinoMegaでのウオッチドッグタイマー"
2つ上のコメントにもありますが、
古いブートローダーではリセットを繰り返してしまうようです。
MEGAのブートローダを新しいブートローダーに書き換えて試してみてください。
2012.07.12 12:19 | URL | #- [edit]
rodan says..."ArduinoMegaでのウオッチドッグタイマー"
MegaもUNOともにボードはR3で今年初めに買ったものなのでブートローダーのバージョンは同じではないのでしょうか?

確認する方法はあるのでしょうか?

ただ、それでもブートローダーの書き換えは一度はやってみようと思っていますがやりかたがよくわかりません(英語が苦手)。

書き換え方を書いてある日本語のサイトをご存知でしたら教えてください。

図々しいお願いばかりですみませんがよろしくお願いします。


2012.07.12 22:54 | URL | #O0C0V3Oc [edit]
arms22 says..."Re: ArduinoMegaでのウオッチドッグタイマー"
MEGAのブートローダは stk500boot_v2_mega2560 で、
UNOの optiboot_atmega328 とは別物みたい。
ウォッチドッグ対応してないんじゃね?って気がする。
2012.07.13 09:40 | URL | #- [edit]
daive says..."stk500boot_v2_mega2560.hex"
古い記事への書込みを、失礼します。
mega 2560 の wachdog は、
stk500boot_v2_mega2560.hex
に書き換えると、使用可能な様子です。
https://github.com/msproul/Arduino-stk500v2-bootloader
16U2-MEGA:Arduino互換MEGA
CH340-MEGA:中華MEGA
で、確認

//******************************************************************************************
// Check Arduino 1.00 letter
//******************************************************************************************
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#include <avr/wdt.h>

void setup(){
Serial.begin(115200);//initialize the serial port
Serial.println("wachdog Reset DI8 or DI9 ");

//
//for Reset
// 11:Reset , 8 : test in1 , 9 : test in2
digitalWrite(12, HIGH); //先にHigh にする。
pinMode(12, OUTPUT);

delay(200);
pinMode( 9, INPUT_PULLUP);
pinMode( 8, INPUT_PULLUP);

wdt_enable(WDTO_2S);

}

void loop(){
//do_something();
wdt_reset();
// test Reset
int pin8val = 0;
int pin9val = 0;
//
pin8val = digitalRead(8);
pin9val = digitalRead(9);
if ( ( pin8val == LOW ) )
{
Serial.println(" Input DI8-LOW ");
Serial.println(" Watch Dog Reset Wait ");
delay(4000);
//digitalWrite(12, LOW);
Serial.println(" No Watch Dog Reset ..... ");

}
else if ( ( pin9val == LOW ) )
{
Serial.println(" Input DI9-LOW ");
Serial.println(" Watch Dog Reset Wait ");
delay(4000);
//digitalWrite(12, LOW);
Serial.println(" No Watch Dog Reset ..... ");
}
else
{
Serial.println("wachdog reset input wait . Reset DI8 or DI9 ");
delay(500);
digitalWrite(12, HIGH);
}

}
2015.06.01 07:56 | URL | #zdvXpt9s [edit]

Leave a reply






管理者にだけ表示を許可する

該当の記事は見つかりませんでした。