Arduino詳解その15です。前回の記事はこちらです。
hirocom777.hatenadiary.org
骨組みを作る
キッチンタイマー本体の骨組みについて考えてみましょう。キッチンタイマーの動作の流れは大体以下のようになると思います。
①入力を待っている(電源入れたばかりの状態、初期状態)
②時間を設定する
③ボタンを押してカウントをスタートする
④カウントする
⑤時間が来たら音で通知する
⑥ボタンを押して初期状態に戻す(①の状態に戻る)
このうち、キッチンタイマーの状態を表すのは①、④、⑤ですね。②、③は①の状態の時に使用できる機能。⑥は⑤の状態の時に使える機能です。それぞれの状態に移るには、以下の機能もしくはイベントを使用することになります。
①⇒④ ボタンを押す(③)
④⇒⑤ カウントが終わる(イベント)
⑤⇒① ボタンを押す(⑥)
キッチンタイマーのスケッチには、この状態を管理する必要がありそうです。こういった状態の変化を状態遷移って言います。本格的なデバイスになるとこれを管理する状態遷移図ってのを書くらしいのですが、今回はシンプルなのでパスです。
まず、骨組み)を作っていくので細かい機能は省略します。②時間を設定するは、値を60秒に固定します。また、液晶モジュールによる表示は省略してカウントの状況はシリアルモニターに表示することとしましょう。これらの機能は後々揃えていきます。
スケッチの場所を決める
今まではArduinoIDEに含まれるスケッチなどを呼び出して動かしていましたが、今回は1から作るわけですからスケッチの保存場所から作っていきましょう。任意の場所にフォルダを作成してください。名前は"KitchenTimer001"とします。次にフォルダの下にテキストファイルを作ります。ファイル名を"KitchenTimer001.ino"としましょう。拡張子".ino"はArduinoIDEに関連付けられているはずです。開くとArduinoIDEが立ち上がると思います。中身は空っぽですよね。その中に以下のスケッチを入力してみてください。
骨組みのスケッチ
今回用意したスケッチは、以下になります。ちょっと長いですがご容赦ください。
int timerStatus = 0; int setTime = 60; int countTime; int buzzerCount; unsigned long measureTime; void setup() { pinMode(2, INPUT); countTime = setTime; Serial.begin(9600); } void loop() { int key = keyCheck(50); if (key == 2 ) { timerStatus ++; if (2 < timerStatus) { timerStatus = 0; } } if (((setTime - countTime) * 1000L ) < (millis() - measureTime)) { Serial.print(" mode "); Serial.println(timerStatus); if (timerStatus == 0) { measureTime = millis(); countTime = setTime - 1; } else if (timerStatus == 1) { Serial.println(countTime); countTime--; if ( countTime == 0 ) { timerStatus = 2; buzzerCount = 0; } } else if (timerStatus == 2) { if (buzzerCount < 3) { tone(8, 349, 800); buzzerCount++; } measureTime = millis(); countTime = setTime - 1; } } } int buttonCount = 3; int pinNumber[] = {2,3,4}; int buttonState[] = {0,0,0}; unsigned long lastTime[] = {0,0,0}; int keyCheck(int waitTime) { for (int i = 0 ; i <= buttonCount - 1 ; i++ ) { if (digitalRead(pinNumber[i]) == LOW) { buttonState[i] = 0; lastTime[i] = 0; } else { //digitalRead(pinNumber[i]) == HIGH if (lastTime[i] == 0) { lastTime[i] = millis(); } else {//lastTime[i] != 0 if (buttonState[i] == 0 && (millis() - lastTime[i]) > waitTime) { buttonState[i] = 1; return (pinNumber[i]); } } } } return (0); }
動かしてみる
それでは書き込んで動かしてみましょう。GROVEベースモジュールのD2にボタンモジュール。D8にブザーモジュールを接続した後にスケッチを書き込んでみてください。次にシリアルモニターを立ち上げます。"mode 0"と連続して表示されていますよね。このスケッチでは1秒ごとに現在の状態をシリアルモニターに表示するようにしています。"mode 0"は初期状態(①の状態)です。ボタンモジュールを押してみると、表示が"mode 1"となると同時にカウントダウンを始めます。そして、カウントが終了すると表示が"mode 2"となってブザーが3回なったと思います。もう一度ボタンを押すと"mode 0"に戻ります。"mode 1"はカウント中の状態(④の状態)、"mode 2"はカウントが完了した状態(⑤の状態)です。
骨組みが出来たよ!!
どうですか?キッチンタイマーの基本的な動きは再現できたと思います。あとはこれをベースに機能を拡張したり整理したりすればいいですね。あと、ちょっと長くなったんで整理する方法も考えましょう!!
hirocom777.hatenadiary.org