濃厚接触判定アラームをつくろう②

 micro:bit(マイクロビット)は手のひらサイズの小さなコンピューター。いろいろな機能
(きのう)

(そな)
わっていて、自分でプログラミングをすることができるよ。ブログラミングは「MakeCode(メイクコード) for micro:bit」を使えば、初心者でもかんたんにできるんだ。

 『子供の科学』本誌
(ほんし)
連載
(れんさい)
「micro:bitでレッツプログラミング!」では、micro:bitを使った「探検
(たんけん)
ウォッチ」というツールを使って、その機能
(きのう)
をプログラミングでつくったけれど、この連載が「スタプロ」にお引っ越し。Web連載でも、探検ウォッチのいろいろな機能をプログラミングでつくっていくぞ!

 これまでの本誌連載のバックナンバーは、micro:bit特設サイトで公開しているよ(コカネットの無料会員登録が必要)。本誌の連載を見たことがないという人は、まずこちらを見てみてね。Web連載は、本誌の連載の続きになっているから、基本的なことがわからなくなったら本誌のバックナンバーを
り返ろう。

 今月は、探検ウォッチをつけている人同士が、一定時間近くにいるとアラームが鳴る「濃厚接触判定
のうこうせっしょくはんてい
アラーム」をつくっているぞ。

 前回は、micro:bitに搭載
とうさい
されている無線機能
むせんきのう
を使って、無線の電波を送受信して、電波の強弱を調べるプログラムをつくったね。今回は、時間を計測するタイマーをつくっていくぞ。15分以上近くにいるかどうかを調べるときに使うよ。

1 タイマーのしくみ

 micro:bitで時間を測るにはどのような方法があるだろうか。いろいろなブロックを探してみるのもいいが、ここではMakeCodeのホーム画面にあるチュートリアルを紹介しよう。

MakeCodeホーム画面

 MakeCodeのホーム画面では、自分の作品(マイプロジェクト)の下にいろいろなチュートリアルが用意されている。

 下のほうにスクロールしていくと、「Tools(ツール)」というカテゴリーがあって「Stopwatch(ストップウォッチ)」というのがある。どんなプログラムか見てみよう。

チュートリアルの「Stopwatch(ストップウォッチ)」

 「Stopwatch」をクリックすると、「チュートリアルを開始」が3つ表示される。「ブロック」の「チュートリアルを開始」をクリックしよう。

「Stopwatch」ブロックのチュートリアルを開始

 英語で説明している画面が表示されるけど、「OK」をクリックして進もう。

このウィンドウではOKをクリック

 通常のMakeCodeエディターと異なり、上のメニューのところに説明の順番、すぐ下には説明の文章(現在は英語)が表示されている。また、チュートリアルに必要なカテゴリーやブロックだけが表示されるので、迷わないようになっている。

 英語の説明文におどろくかもしれないけど、説明文の右上にあるヒントボタンを
してみよう。説明に書かれたブロックが表示され、それは日本語表示のブロックだからどのブロックを使うかがわかるだろう。このチュートリアルを元に、「Stopwatch」をプログラミングしてみよう。

チュートリアルの内容

 「Stopwatch」のチュートリアルを最後まで見るとわかるけど、「入力」カテゴリーの「…その他」にある「稼働時間
かどうじかん
(ミリ秒)」ブロックを使って時間を計測している。

 「稼働時間」とはmicro:bitのプログラムが実行されてからの時間がずっとカウントされていくものだ。ここでつくったコードを見てみると、開始時点の稼働時間を変数「start」に入れて(①)、停止したときの稼働時間から、変数「start」を引いて時間を計測している(②)。LEDディスプレイに表示するときの「整数
せいすう
の÷」ブロックは、「計算」カテゴリーから「平方根
へいほうこん
」ブロックで選択
せんたく
ができるよ(③)。

「Stopwatch」のプログラム

2 接触の時間をどう測るか

 しかし、今回は、時間を測り始めるのも、15分経ったらアラームを鳴らすのも、ボタンで操作はしないので、「Stopwatch」のプログラムを参考に変えてみよう。

 また、実際には距離
きょり
は一定ではなくて、1メートル以上
はな
れる場合もあるよね。でも、離れてから少しの間はリセットしないようにして、一時的
いちじてき
に遠ざかった場合や、ちょっとした電波の強弱の変化にも対応できるようにしよう。

 ここから新しいプロジェクトで「濃厚接触判定アラーム」としてつくっていこう。
 まず、「ずっと」ブロックで全体の処理の流れをつくろう。「論理
ろんり
」カテゴリーの「もし〈真〉なら~でなければ~」ブロックを使い、1m以内かどうかで振り分ける処理をつくる。ここで変数「1m以内」をつくってフラグとして使う。

 フラグとは0または1など2値の値を持つ変数で、状態をプログラムに伝える変数となる。「論理」カテゴリーの「( )=( )」ブロックを使って、次のように状態を規定
きてい
していくよ。

  • 変数「1m以内」=0 のときは“1メートル以上離れている”
  • 変数「1m以内」=1 のときは“1メートル内に近づいた”

 したがって、「もし〈1m以内=1〉なら」の部分にタイマー開始時刻
かいしじこく
のセットなどのコードを入れる(①)。「でなければ~」の部分には、1メート以上離れているがそれが一時的なものなのかをチェックするタイマーのセットのコードを入れていくぞ。

1m以内かどうかで振り分ける処理

3 タイマーをスタートさせる

 「Stopwatch」の変数「start」と同じように、変数「15分タイマー開始時間」をつくろう。この変数に「稼働時間(ミリ秒)」を入れることで、タイマーをスタートさせる準備
じゅんび
が完了だ(②)。目印として、「基本」カテゴリーの「アイコンを表示」ブロックでチェックマークを表示させておくぞ(③)。

タイマーをスタートさせる

 ただし、このコードをよく見て動作を想像してみよう。1メートル以内にいる限り、いつも「15分タイマー開始時間」が更新
こうしん
されてしまう。つまり、タイマーのスタートが繰り返されて、15分を測ることができない。そこで変数「15分計測中」というフラグをつくって、変数「15分タイマー開始時間」と同じように状態を規定しよう。

  • 変数「15分計測中」=0 タイマーはスタートしていない
  • 変数「15分計測中」=1 タイマー計測中、スタートしている(「15分タイマー開始時間」を更新してはいけない)

 「もし〈真〉なら」ブロックに〈15分計測中=0〉を組み込んで(④)、さっきつくったタイマーをスタートさせるコードを入れよう。それに「変数“15分計測中”を(1)にする」ブロックを追加するよ(⑤)。
 タイマー計測中ということがわかるように、「LED画面に表示」ブロックを使って時計のようなアイコンを表示させたぞ(⑥)。

15分計測中

4 距離が離れたときの処理

 次に、距離が1メートル以上離れたらときの処理を考えよう。単純にタイマーを止めてしまってもいいのだが、一瞬だけ1メートル以上離れたけど、基本的にはずっと近くにいたケースや、電波の測定がときどき不安定になって、1メートルが計測されないことも想定される。そのため、変数「離れているタイマー開始時間」をつくって、離れている時間を計測するタイマーとしてみよう。

 離れているタイマーの計測も常に更新されてはきちんと測れないので、変数「離れている時間を計測中」というフラグでコントロールしているぞ。コード自体は、さっきつくった15分を計測するコードとほぼ同じだ(⑦)。使う変数が違うのと、アイコンの表示は「ちいさなハート」にしている。

 再び近づいた時に、変数「離れている時間を計測中」は無効にするために、「もし〈15分計測中=0〉なら」のコードの最後に、「変数“離れている時間を計測中”を0にする」ブロックの追加も忘れずに入れよう(⑧)。

 なお、「もし〈“離れている時間を計測中”=0〉」ならブロックの後に、「アイコンを表示」ブロックで笑顔のアイコンを表示させるようにしている(⑨)。これは、「離れてる時間を計測中」でない場合に表示されるよ。

離れている時間を計測中

5 時間の単位をそろえておく

 さて、ここではタイマーで使われている時間の単位をそろえておこう。

 「稼働時間(ミリ秒)」ブロックを使ってタイマーの開始を記録
きろく
しているが、ミリ秒とは1000分の1秒となる。なので15分をミリ秒に変換
へんかん
するには

時間の単位をそろえる計算

とすればいい。

 「最初だけ」ブロックの中でそれぞれの数字を設定しておこう。15分のカウント用は変数「15分(ミリ秒)」、一時的に離れている時間は変数「リセット猶予
ゆうよ
(ミリ秒)」としよう。「( )×( )」ブロックを使って、変換の計算式をつくっていくよ。

 変数「15分(ミリ秒)」の方は、テストをするために3分にしている。実際に使うときは、3を15に変えるよ。「リセット猶予(ミリ秒)」は1分にした。

時間の単位をそろえるプログラム

6 15分経過の確認

 15分経っているかの確認は、関数「15分経っているか確認」をつくる。この関数の呼び出しは、「ずっと」のプログラムの一番最後に入れる。

関数「15分経っているか確認」の呼び出し

 関数「15分経っているか確認」は次のようになるよ。確認が必要なのは15分計測中だけなので「もし〈真〉なら」ブロックを使う。

 確認の処理としては現在の「稼働時間(ミリ秒)」から「15分タイマー開始時間」を引いて、それが「15分(ミリ秒)」より大きくなっていたら、15分経過したことになる(⑩)。

 「メロディを開始する“ジャンプダウン”くりかえし“一度だけ”」ブロックで音を鳴らし、「アイコンを表示」ブロックで「残念な顔」を表示させた(⑪)。

 その次は、1メートル以内に15分間にいてアラートが鳴った後、1メートル以上離れたら15分計測するタイマーを無効にしている(⑫)。

関数「15分経っているか確認」のプログラム

7 ずっと離れていたら15分タイマーをリセットする

 離れている時間が長かったら、15分タイマーをリセットする。そのために離れている時間を計測するタイマーの処理もつくっておこう。関数「リセットするか確認」をつくり、呼び出しのブロックは「ずっと」ブロックのプログラムで、「呼び出し  15分経っているか確認」ブロックのの下に入れる。

関数「リセットするか確認」の呼び出し

 関数の中身は以下のようになるよ。
 1メートル以上離れたときの時間を測るタイマーが開始している時だけチェックすればいいので、「もし〈真〉なら」ブロックを使って、変数「離れている時間を計測中」をフラグにして切り替えている(⑬)。

 離れている時間を確認する処理は、現在の「稼働時間(ミリ秒)」から「離れているタイマー開始時間」を引いて、それが「リセット猶予(ミリ秒)」より大きくなっていたら、一定時間離れていたことになる(⑭)。

 もし一定時間離れていたら15分タイマーを無効にして(⑮)、計測していた時間も無効(⑯)にしている。動作確認用に「メロディを開始」ブロックで音も鳴らしてみたぞ(⑰)。

関数「リセットするか確認」のプログラム

8 動作確認をしてみよう

 シミュレーターで動作確認をしてみよう。シミュレーターの場合はボタンを使って「1m以内」かどうかを切り替えるよ。「ボタンAが押されたとき」ブロックで次のようなコードをつくった。

ボタンAが押されたときに1m以内にいる設定とするプログラム

 「最初だけ」ブロックのプログラムにも、「変数“1m以内”を0にする」ブロックを入れておこう。

「最初だけ」ブロックのプログラムにも、「変数“1m以内”を0にする」ブロックを入れる

 これで、ボタンAを1回押すと1メートル以内に近づいたことになり、15分タイマーが開始される。実際は3分に設定したので、3分間待ってみよう。
3分経ったら、アイコンが「こまり顔」と「時計」が交互に表示され、アラームが鳴ったかな。

 成功したら、ボタンAを押した後に、何度かボタンAを押してみよう。これで、1メートル以上離れたり、また近づいたり離れたりという動作を再現できる。少しの間だけ離れたくらいでは、3分経ったらアラームが鳴ることが確認できたかな。1分以上離れたらタイマーが無効になって、3分経ってもアラームが鳴らないんじゃないかな。
 この方法を使うと、探検ウォッチ1台で試せるので、実際に書き込んで試してみてね。

 次回は、いよいよ2台の探検ウォッチにプログラミングをして、濃厚接触判定アラームを完成させるぞ。お楽しみに!

(文/倉本大資)

プログラミング教材 micro:bit

KoKa micro:bit探検ウォッチキット

¥7,700- (税込)

KoKa Shop!で購入する

最新号好評発売中!

子供の科学 2025年 1月号

CTR IMG