表示を充実させる(Arduino詳解)

Arduino詳解その16です。前回の記事はこちらです。
hirocom777.hatenadiary.org

骨組みが出来たぞ!!

 前回はキッチンタイマーの骨組みを作りました。これからこの骨組みをベースにスケッチを改良していきたいと思います。まずは、まだ使用していな液晶モジュールに表示をしてみましょう。

表示を改善する

 前回はシリアルモニターで秒数の経過を表示していましたが、これでは使い勝手が悪いですね。PCが無いと使えないし、表示も秒数だけじゃなくて分:秒(01:15)みたいな形にしたいです。”/”で区切って設定時間を表示できるようにすると親切ですね。(01:15/03:00のような感じ)

今回の準備

 さて、スケッチへと取り組むわけですが前回作ったフォルダ"KitchenTimer001"をコピーして"KitchenTimer002"として下さい。中にあるスケッチも"KitchenTimer002.ino"と変えましょう。また、このフォルダの中に新たな二つのスケッチファイルを用意します。名前を"KeyCheck.ino"と"TimeText.ino"とします。3つファイルのうちどれかを開くと、全てのファイルがTab形式で切り替えられる形で表示されるはずです。それぞれのファイルに以下の様に入力してください。(今回はこちらからファイルをダウンロードできます。

ボタン入力を処理する"KeyCheck.ino"

 "KeyCheck.ino"の内容は以下になります。

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);
}

 これ、前回のスケッチ"KitchenTimer001"の後半部分です。もうお気づきになっていると思うのですが、これはその9:複数入力を処理するで出てきた内容です。Arduinoでは、こうやって複数のファイルにスケッチを分けることが出来ます。一つ一つが短くなって解りやすいですよね。

時間表示の文字列を作る"TimeText.ino"

 液晶モジュールには分:秒の形で表記するので。秒数から表記形式を変換する関数を作りましょう。以下のようになります。

//秒数を入力すると時間表示の文字列を返します。(例:90⇒01:30)
String TimeText(int second) {
  //分の表示
  String textData = String(int(second / 600));
  second = second % 600;
  textData += String(int(second / 60)) + ":";
  //秒の表示
  second = second % 60;
  if (second < 10) {//0~9秒の時は"0"表示を追加する。
    textData += "0";
  }
  textData += String(int(second));
  return (textData);
}

 Arduinoでは文字列形式のデータを取り扱うのにStringオブジェクトを使います。今までご紹介したスケッチの中にも""で囲まれた文字列があったと思いますが、これらもStringオブジェクトです。この関数は与えられた秒数から分:秒の形の文字列でStringオブジェクトを返します。Stringオブジェクトの詳細については、また別の機会にご紹介したいと思います。

骨組み"KitchenTimer002.ino"

 そして、上記のスケッチを使うため、"KitchenTimer002"を以下の様になります。

#include <Wire.h>
#include "rgb_lcd.h"

rgb_lcd lcd;

int timerStatus = 0;
int setTime = 180;
int countTime;
int buzzerCount;
unsigned long measureTime;

void setup() {
  pinMode(2, INPUT);
  countTime = setTime;
  lcd.begin(16, 2);
}

void loop() {
  int key = keyCheck(50);
  if (key == 2 ) {
    timerStatus ++;
    if (2 < timerStatus) {
      timerStatus = 0;
    }
  }
  if (((setTime - countTime) * 1000L ) < (millis() - measureTime)) {
    lcd.setCursor(3, 0);
    if (timerStatus == 0) {//初期状態
      measureTime = millis();
      countTime = setTime - 1;
      lcd.print(TimeText(setTime));
      buzzerCount = 0;
    } else if (timerStatus == 1) {//カウント中
      lcd.print(TimeText(countTime));
      countTime--;
      if ( countTime == 0 ) {
        timerStatus = 2;
      }
    } else if (timerStatus == 2) {//カウント終了
      if (buzzerCount < 3) {
        tone(8, 349, 800);
        buzzerCount++;
      }
      measureTime = millis();
      countTime = setTime - 1;
      lcd.print(TimeText(0));
    }
    lcd.print("/" + TimeText(setTime));
  }
}

シリアルモニターに関する記述を削除して、液晶モジュールに関する記述に変更。その他、少しだけ変更あります。KeyCheckは別ファイルにしたので、丸ごと削除しました。

動かしてみる

 それでは、早速動かしてみましょう。前回と同じように、GROVEベースモジュールのD2にボタンモジュール、D8にブザーモジュールを接続します。液晶モジュールはI2Cと書かれているコネクタに接続します。スケッチを書き込むと、液晶モジュールに以下のように表示されます。

f:id:HiroCom777:20200706214654j:plain
ボタンを押すとカウントダウン開始。3分経過すると、ブザーが3回鳴ってお知らせします。もう一度押すと、初期状態に戻ります。

次回は宿題(?)の回答

 どうですか?今回みたいに骨組みを考えてから色々な機能を肉付けしていく方法に慣れると、結構大きなスケッチも書けるようになると思います。皆さんも色々挑戦してみてください。次回は、今まで詳細の説明を避けてきた案件について取り組んでいきたいと思います。
hirocom777.hatenadiary.org


Arduino UNO入門の連載記事はコチラからどうぞ!!