Arduinoをリセットする必要がある場合、物理的にボタンを押してリセットをかけることが出来る[RESET(リセット)ボタン]は全てのArduinoボードに搭載されています。
リセットボタンが押されるとArduinoはスケッチ(プログラム)を最初から実行する動作をします。
コンピューターで言う再起動のような動作ですね!
例えばArduino Unoではここにリセットボタンが付いています。
全てのArduinoボードには同様にこのリセットボタンが付いていてスケッチを最初から実行したい場合などで主に使われます。
Arduinoを使っているとよく使うもうおなじみのボタンですね!
リセットボタンが押されるとArduinoボードは再起動し、マイクロコントローラーのメモリに書き込まれているスケッチも最初から実行されます。
また、スケッチを書き込む時やシリアル通信を開始した時にもArduinoは一旦リセットされます。
Arduinoには自動的にリセットをかけるオートリセット機能も付いています。
そしてArduinoにはこの物理ボタンを押す以外に[RESET端子]を使いハードウェア的にリセットをかけたり、またソフトウェア的にリセットをかけるなどいくつかの方法があります。
スケッチの不具合(バグ)でArduinoがフリーズ状態になってしまう事や無線接続が切れて応答待ちとなり以前の状態のまま動き続ける(暴走状態)になることはよくありますが、このように特定の状況に陥った際にリセットをかけてArduinoボードを再起動する事が出来れば便利な場合は多々あります。
という事で今回はArduinoをリセットするいくつかの方法を見ていきたいと思います。
Arduinoをリセットするいくつかの方法!
Arduinoのリセット方法として一番使われるのは、冒頭でお話した物理ボタンを押す方法ですね!
全てのArduinoボードにはリセットをかけるための物理ボタンが用意されています。
スケッチを最初から実行したい場合やスケッチのアップロード中にエラーが出て進まなくなった場合などで使われることが多いと思います。
そしてArduinoにはこの物理ボタンを押す以外にもいくつかのリセット方法があります。
[RESET端子]をLOWに落としてリセットする
Arduinoにはハードウェア的にリセットをかけるための[RESET端子]というものが付いています。
Arduino Unoではこの端子ですね。
このRESET端子をLOWレベルに落とすことによりリセットをかけることが出来ます。
リセットボタンを押した時と同じ状態になります。
簡単な例では、RESET端子とGND端子の間にスイッチを接続しておき、このスイッチが押されるとArduinoをリセットさせるという使い方です。
外部リセットスイッチとして機能させることが出来ます!
また、どこでもいいのですが出力設定した端子をリセット端子と接続しておけば、接続している出力端子をLOWにすることによりリセットをかけることが出来ます。
仮にデジタルピンD8端子をpinMode()関数で出力端子として設定しこれをリセット端子に接続しておけば、D8端子をHIGHからLOWにすることによりリセットをかけることが出来ますね!
下記スケッチは、0から10までカウントするとD8端子をLOWにしてリセットをかける簡単なスケッチ例です。
スケッチを実行すると1秒おきに数値をカウントしてシリアルモニタに表示します。
数値が10になるとD8端子をLOWにしてリセットをかけるものです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | // Arduinoのリセット方法① // RESET端子をLOWに落とす! // https://burariweb.info int reset_Pin = 8; void setup(){ digitalWrite(reset_Pin, HIGH); Serial.begin(9600); pinMode(reset_Pin, OUTPUT); Serial.println("----- RESET -----"); } void loop(){ for(int i=0; i<=10; i++){ Serial.print("Number: "); Serial.println(i); delay(1000); } software_reset(); } void software_reset(){ digitalWrite(reset_Pin, LOW); } |
シリアルモニタで確認すると、10をカウントした後にリセット端子に接続したD8端子がLOWになるのでこの時点でリセットがかかりスケッチが最初から実行されているのが確認できます。
非常に簡単な例なんですが、意外と苦戦しました!
リセットがかかるとArduinoが初期化されスケッチの先頭から再度実行されます。
そしてArduino起動時には全てのGPIO端子がLOWになりますが、これだと起動と同時にD8端子に接続されたリセット端子もLOWになり再起動を繰り返してしまうのでスケッチ自体を動かすことが出来ません。
そこで上記スケッチでは、setup()関数内の先頭にdigitalWrite(reset_Pin, HIGH);の1行を入れて起動時にリセット端子がLOWに落ちないようにしています。
7 8 9 10 11 12 | void setup(){ digitalWrite(reset_Pin, HIGH); Serial.begin(9600); pinMode(reset_Pin, OUTPUT); Serial.println("----- RESET -----"); } |
これでArduinoが起動した時点ではリセット端子はHIGTとなりスケッチが実行され、任意のタイミングでリセット端子に接続したD8端子をLOWにすることによりリセットをかけることが出来るようになりました!
ソフトウェアでリセットをかける
次にソフトウェアでリセットをかける方法です。
Arduinoをリセットするための関数を使います。
アドレス0でリセット関数resetFunc()を呼び出す方法です。
上記のように物理的にリセット端子に配線する必要がなくなるので現実的です!
先程のスケッチをリセット関数を呼び出す方法にするとこのようになります。
resetFunc()を呼び出すとArduinoがリセットされ、setup()関数がコールされ実行されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // Arduinoのリセット方法② // ソフトウェアでリセットをかける! // https://burariweb.info void setup() { Serial.begin(9600); Serial.println("----- RESET -----"); } void(*resetFunc)(void) = 0; void loop() { for(int i=0; i<=10; i++){ Serial.print("Number: "); Serial.println(i); delay(1000); } resetFunc(); } |
先程のものとスケッチ内容は同じですがリセット自体の動作が少し違うので比べてみるといいと思います。
リセットボタンを押したりRESET端子をLOWに落とすハードウェア的な方法ではArduinoが初期化されブートローダーが読み込まれ・・・Arduinoに電源を投入した時のような動作となりますが、上記ソフトウェア的にリセットをかける場合setup()関数がコールされそこから実行されます!
参考 Void(* resetFunc) (void) = 0; with Nano EveryArduino FORUMウォッチドッグタイマー(WDT)を使う方法
次にウォッチドッグタイマー(WDT)と呼ばれるタイマー機能を使ったリセット方法です。
ウォッチドッグタイマーとは定期的に割り込みをかける機能です。
“watch dog” = “番犬”という意味のようで、Arduinoが正常にスケッチを実行し続けているかを確認し定められた一定時間応答がなければリセットをかけるなどの用途で使われることが多いものとなります。
Arduinoがスケッチを実行しうまく機能しているか監視するタイマーみたいなものです。
具体的にはArduinoで実行しているスケッチが停止やフリーズ・暴走などしていないか監視するタイマーとして使われることが多く、一定時間経過しても応答がない場合に自動的にリセットをかける機能となります。
ウォッチドッグタイマーはArduinoに限った機能ではありませんが、Arduinoで使う場合「avr/wdt.h」ライブラリを使います。
簡単な例で試してみます。
以下のスケッチはウォッチドッグタイマーを使ってシリアルポートからの通信を監視し、4秒以上やり取りが途絶えたらリセットをかける簡単な例です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // Arduinoのリセット方法③ // ウォッチドッグタイマー(WDT)でリセットをかける! // https://burariweb.info #include <avr/wdt.h> void setup() { Serial.begin(9600); wdt_enable(WDTO_4S); Serial.println("----- RESET -----"); } void loop() { while(Serial.available()){ wdt_reset(); char num = Serial.read(); Serial.print(num); Serial.println(" キーが押されました!"); } } |
上記スケッチを実行するとシリアルモニターに入力した文字が返ってきます。
そして4秒以上やり取りが途絶えると自動的にリセットがかかっているのが確認できます。
シリアルモニタに関して詳しくはこちらの記事も参考にして下さい!
スケッチ解説
簡単にスケッチ内容を見ておきます。
まずライブラリのインクルードです。
ウォッチドッグタイマーを使うためのライブラリです。
5 | #include <avr/wdt.h> |
そして「avr/wdt.h」ライブラリで用意されている関数は3つあります。
- wdt_enable(value):ウォッチドッグタイマーを有効にするための関数
- wdt_reset():ウォッチドッグタイマーをリセットするための関数
- wdt_disable():ウォッチドッグタイマーを無効にするための関数
setup()関数内でウォッチドッグタイマーを有効化します。
9 | wdt_enable(WDTO_4S); |
ウォッチドッグタイマーが発動する時間(リセットがかかるまでの時間)は、15mS(0.015秒)~8秒までいくつか用意されています。
上記スケッチではWDTO_4Sを使い4秒でリセットがかかる設定にしています。
・WDTO_15MS(15m秒)
・WDTO_30MS(30m秒)
・WDTO_60MS(60m秒)
・WDTO_120MS(120m秒)
・WDTO_250MS(250m秒)
・WDTO_500MS(0.5秒)
・WDTO_1S(1秒)
・WDTO_2S(2秒)
・WDTO_4S(4秒)
・WDTO_8S(8秒)
文字を入力しシリアルポートから情報を受け取ると、wdt_reset()関数を呼び出しウォッチドッグタイマーのカウンタをリセットしています。
13 14 15 16 17 18 19 | void loop() { while(Serial.available()){ wdt_reset(); char num = Serial.read(); Serial.print(num); Serial.println(" キーが押されました!"); } |
ウォッチドッグタイマーがリセットされると、この時点から設定した4秒のカウントが再度始まります。
設定した4秒間シリアルポートでのやり取りがない場合、ウォッチドッグタイマーが発動しリセットがかかるというものです。
最後に!
Arduinoをリセットするためのいくつかの方法を見ていきました。
この他にもリセットをかけるための他のライブラリを使う方法もありますが、Arduinoボードに標準で搭載されているリセットボタンを押す以外にもリセットをかける方法はいろいろとあるようですね!
ブレッドボード上のテスト段階ではArduinoの動作がうまく機能しない場合、物理ボタンで用意されているリセットボタンを押せばいいのですが、何か製作物にArduinoを組み込み稼働させている場合にArduinoからの応答がない?やスケッチのバグなのか特定の条件で停止したり暴走するなどの理由でソフトウェア的にリセットをかけたい場合はよくあるので使えますね!
コメントを残す