CodeZine(コードジン)

特集ページ一覧

マジカルボックスのプログラムを読み解く 1

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2008/11/27 00:00

ダウンロード サンプルソース (44.7 KB)

目次

プログラムを読んでみよう② ―― 間隔計測masure.c

 関数はひとつ、MeasureIntervals()だけです。

 プログラムの説明の前に、どんなふうに間隔を計測するのかについて説明します。図2をご覧ください。これはスプーンをたたいた時、音検出回路の接続された入力ポートにどんな信号が入力されるかを示しています。

図2:スプーン音で入力ポートに加えられる信号
図2:スプーン音で入力ポートに加えられる信号

 無音時は入力ポートは1になっています。スプーンをたたくと、入力ポートに0のパルスが入力されます。この幅は数十ミリ秒~最大50ミリ秒くらいです。

 これに対し、ソフトウェアではまず図3のように①無音の間待って、②最初の音信号が来たところでストップ・ウォッチ(タイマー)をスタートさせます。

図3:最初のスプーン音で時間計測を開始する
図3:最初のスプーン音で時間計測を開始する

 次に図4の③~⑥のように、無音の確認と音信号の確認を繰り返し、2発目と3発目をやりすごします。

図4:2発目3発目を確認しつつ時間計測を続ける
図4:2発目3発目を確認しつつ時間計測を続ける

 最後に図5の⑦~⑧で4発目の音を確認したところでストップウォッチを止めます。計測した時間は4回スプーンをたたいた時間であり、これを3で割ることでスプーンを打った平均間隔時間が求められます。

図5:4発目で時間計測を終える。3で割ると平均時間がわかる
図5:4発目で時間計測を終える。3で割ると平均時間がわかる

 それでは処理プログラムの説明に移ります。

 まず22行目でWaitInactive()を呼んで無音状態を確認します。引数にNOCHEK_TIMEを渡しているのは、タイムアウト(時間切れ)処理をせず、いつまでも無音になるのを待てという指示です。

 無音を確認したら、24行目でWaitSound()を呼んで、今度は最初の1音を待ちます。これも引数にNOCHECK_TIMEを指定していて、スプーンが叩かれるまで永遠に待ちます。音が検出されるとWaitSound()から帰ってきますので、ここでStartTimer()を呼んで時間計測を開始します。本来ならWintSound()の処理の中で、ポートの変化(音の検出)と同時にタイマをスタートさせるほうがより正確ですが、ここでは制御の順番のわかりやすさを優先しています。27行目では1番目のLEDを点灯します。1番目のLEDというのが実際はどのランプなのかはここではわかりません。先に述べたように、それはデバイスドライバの中で解決しています。ここでは「1番目のLED」を灯すという抽象的動作にしてあるのです。

 図5からわかるように、2番目から4番目の音までは同じ処理、つまり「無音を確認して次の音を待つ」という動作を繰り返します。繰り返しということはループ制御文の出番ということで、ここではfor文を使っています。繰り返し回数は変数iで制御していて、2(番目)から4(番目)まで繰り返すよう記述してあります。

 30行目からが繰り返す処理の内容です。最初に1ミリ秒単位の時間待ち関数Wait1msec()を呼んで50ミリ秒待っています。これは、スプーンを1回叩くと、最長で40~50ミリ秒の信号が発生するためです。音信号が消えたころを見計らって、31行目でWaitInactive()を呼んで無音状態に戻るのを待ちます。ここでは引数にCHECK_TIMEを指定して、一定時間以上無音が確認できないときにはタイムアウトしてエラーで帰ります。

 無音状態が正常に確認できたら(33行目)、34行目でスプーン音を待ちます。ここも一定時間音が来なければタイムアウトしてエラーが返ります。音が確認できたら、36行目で対応するLEDを点灯します。for文の回数制御変数iの値を、音が「何番目か」に合わせてあるので、点灯させるLED番号にはiを渡すことで対応LEDを指定できます。

 40行目は無音確認~音確認までの一連の処理でエラー(タイムアウト)があったかをチェックをしています。エラーがあった場合は、41行目でタイマを止めて、ERRORで帰ります。

 こうして正常に4回目の音まで検出しおわると、for文を終了し、46行目でReadTimer()を呼んでタイマ値を読みます。47行目で1/3することで、スプーンを打つ間隔の平均値を求めています。この値があまりに小さいとき(今回のプログラムでは100ミリ秒未満)は、計測に失敗した異常値とみなしてエラーにしています(51行目)。

 前後しますが、49行目でタイマを止め、正常時はスプーンをたたいた間隔の平均時間を持って帰ります。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:たった5つのルールではじめるC言語開発

もっと読む

著者プロフィール

  • 舘 伸幸(タチ ノブユキ)

    NECマイクロシステム株式会社 勤務 NPO法人SESSAME 所属 開発ツールのソフトウェア開発を経て組込みソフトウェア開発に従事。プライベートにも半田ごては手放さない。 2006年からSESSAME に参加。若い世代に物を作る楽しさを伝えていきたい。

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5