Arduinoで遊ぼう - ウォッチドッグタイマを使う
Posted by arms22 on 2009年01月25日

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で作る「会話」するモノたち
-Arduinoで作る「会話」するモノたち
posted with amazlet at 09.01.25
Tom Igoe
オライリージャパン
売り上げランキング: 56322
オライリージャパン
売り上げランキング: 56322
Ads by Google
12 Comments
このコメントは管理人のみ閲覧できます
現状、考えられるのはクロックとマイコンの種類でしょうか。
私が動作確認した環境はArduino Duemilanoveです。DuemilanoveはATmega168を16MHz駆動しています。
Arduino pro mini 328はATmega328を8MHzで駆動しているので、その辺が関係していそうですね。
動作がおかしい時の具体的な挙動を教えてください。
私が動作確認した環境はArduino Duemilanoveです。DuemilanoveはATmega168を16MHz駆動しています。
Arduino pro mini 328はATmega328を8MHzで駆動しているので、その辺が関係していそうですね。
動作がおかしい時の具体的な挙動を教えてください。
このコメントは管理人のみ閲覧できます
現在、Googleのプロジェクトホスティングサービスを使ってコードを管理しています。
圧縮して固めたパッケージはありませんが、ここからソースコードをDLできます。
http://code.google.com/p/arms22/source/browse/#svn/trunk/Watchdog
圧縮して固めたパッケージはありませんが、ここからソースコードをDLできます。
http://code.google.com/p/arms22/source/browse/#svn/trunk/Watchdog
とても参考になる情報をいろいろありがとうございます。利用させていただいています。
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
}
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
}
新しいブートローダー「Optiboot」はウォッチドッグタイマに対応しているようですが、古いブートローダーはリセットを繰り返してしまうらしくて上手く動作しなかったようですね。(例えば↓)
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1278573986/11
下のやり方でブートロダーを新しくしたら問題解決しました。
http://code.google.com/p/optiboot/
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1278573986/11
下のやり方でブートロダーを新しくしたら問題解決しました。
http://code.google.com/p/optiboot/
ウォッチドックでリセットは試してなかったので気がつきませんでした。
これはUNO以前のArduinoでは要注意ですね。
情報ありがとうございます。
これはUNO以前のArduinoでは要注意ですね。
情報ありがとうございます。
いつも参考にさせて頂いておりましてありがとうございます。
今回はウオッチドッグタイマーでわからないところがありますので投稿させていただきました。
下記のスケッチを走らせたところ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;
}
今回はウオッチドッグタイマーでわからないところがありますので投稿させていただきました。
下記のスケッチを走らせたところ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;
}
2つ上のコメントにもありますが、
古いブートローダーではリセットを繰り返してしまうようです。
MEGAのブートローダを新しいブートローダーに書き換えて試してみてください。
古いブートローダーではリセットを繰り返してしまうようです。
MEGAのブートローダを新しいブートローダーに書き換えて試してみてください。
MegaもUNOともにボードはR3で今年初めに買ったものなのでブートローダーのバージョンは同じではないのでしょうか?
確認する方法はあるのでしょうか?
ただ、それでもブートローダーの書き換えは一度はやってみようと思っていますがやりかたがよくわかりません(英語が苦手)。
書き換え方を書いてある日本語のサイトをご存知でしたら教えてください。
図々しいお願いばかりですみませんがよろしくお願いします。
確認する方法はあるのでしょうか?
ただ、それでもブートローダーの書き換えは一度はやってみようと思っていますがやりかたがよくわかりません(英語が苦手)。
書き換え方を書いてある日本語のサイトをご存知でしたら教えてください。
図々しいお願いばかりですみませんがよろしくお願いします。
MEGAのブートローダは stk500boot_v2_mega2560 で、
UNOの optiboot_atmega328 とは別物みたい。
ウォッチドッグ対応してないんじゃね?って気がする。
UNOの optiboot_atmega328 とは別物みたい。
ウォッチドッグ対応してないんじゃね?って気がする。
古い記事への書込みを、失礼します。
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);
}
}
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);
}
}
Leave a reply
該当の記事は見つかりませんでした。