LabVIEWを触ったことがない方に向けて、それなりのプログラムが書けるようになるところまで基本的な事柄を解説していこうという試みです。
シリーズ10回目としてプログラムの構造の中で頻繁に使われるループ構造を扱います。
この記事は、以下のような方に向けて書いています。
- 処理を繰り返すにはどうすればいいの?
- WhileループとForループってどう違うの?
もし上記のことに興味があるよ、という方には参考にして頂けるかもしれません。
なお、前回の記事はこちらです。
繰り返しの種類を知ろう
プログラムを書こうとするモチベーションには、「手を使ってやるのがめんどくさいから自動的にやれるようにしたい」といった人間の「怠慢」があると思います。
特に何がめんどくさいって、ひたすら同じようなことを繰り返すのが面倒だったりします。私も学生の時にはひたすら似たようなことを繰り返しているのが面倒だなと感じていました。
あるいは、ヒューマンエラーがないとか、機械に任せて自分は他のことに集中できる、といったメリットのためにプログラミングを行うことはよくあると思います。
しかし、これまでの内容で扱ってきたものは、全て一回終わったらプログラムもおしまい、でした。例えば、以前やったような何かデータを記録させるプログラムを例にとっても、値を何かしら書いておしまいでした。
では、プログラムを書いて同じような作業を繰り返させるにはどうすればいいか?そこで繰り返しの構造、ループの登場です。
ただ、プログラムの一部には繰り返さなくても部分もありますよね?プログラム全体を見たときに、繰り返すところと繰り返さなくていいところがあるわけです。プログラムが終わるまでずっと何かを繰り返すときもあるとは思いますが、繰り返す部分と繰り返さない部分がある以上、ループは何らかの方法で止める必要もあるわけです。
LabVIEWでループ構造を扱う際には、大きく分けて二種類の止め方があります。
- 何か決まった条件に達したら止める
- あらかじめ指定した回数だけ動かしたら止める
これらの区別は良くできるようにしておく必要があります。初めて聞くと判断が難しそうと思うかもしれませんが、実際そんなに難しいことではなく、大体直感でわかると思います。
例えば以前の記事で少し例に出したような「サイコロを100回振って出た目の平均を知る」ような場合、サイコロを振るという動作は100回繰り返せばいいことになりますね。
では、何かデータ、例えば温度を1秒ごとに測っていて、測定した値が30度を超えたら測定をやめる、という場合はどうなるかを考えます。
「1秒ごとに測って」の時点で、1秒ごとに温度測定という動作を繰り返しているわけですが、30度を超えるのが何秒後かはわからないことが多いと思います。であれば、30度を超えた、ということを条件にして繰り返しをやめるという動作が適切だと考えられますね。
今挙げた2つの例は、どちらの止め方がいいか、割と考えやすいかと思います。
ここまで簡単ではないかもしれませんが、プログラムを書く人にとっては基本的に「どういうプログラムを書きたいか」がわかって書いているはずなので、どちらの方法を使えばいいかの判断はそれほど難しくないはずです。
LabVIEWで上記二つの止め方を実現するためにはWhileループかForループを使用します。他のテキスト言語などやったことがある方はどっちがどっちという違いが分かるかと思いますが、これらはそれぞれ以下のように分類できます。
- Whileループ:指定した終了の条件が満たされるまで繰り返し続ける
- Forループ:あらかじめ指定した回数が終わるまで繰り返し続ける
となっています。先ほどの区分と全く同じですね。
実はもう少し動作に細かい違いはあるのですがそれはまた別途扱うとして、とりあえず今はどんなものかを知って慣れることが大事だと思うので、早速それぞれのループを試してみましょう。
Whileループを使ったプログラムを組んでみる
まずは簡単に、Whileループを使用してユーザーが停止のボタンを押したら繰り返しを終えるという動作のプログラムを作ってみます。
ループ構造はアルゴリズムに関わる項目なのでフロントパネルで何かするものではなくすべてブロックダイアグラムで扱います。
ブロックダイアグラムで右クリックして左上に表示される「ストラクチャ」にループに関する項目が入っています。ここでWhileループを選択して、ブロックダイアグラムをクリックしてから、ドロップするように右下に枠を伸ばしていきます。すると四角い枠が表れこれがLabVIEWのWhileループになっています。
Whileループの構造を見てみます。グレーの四角い枠組み以外にも下の方に左右に二つ、アイコンが表示されているのが分かると思います。
左側の、iとかかれたものは「反復端子」と呼びます。これは、「今ループは何回目ですよ」という、ループが回った数を表しています。ただし、これもまた配列の指標番号等と同様に0から数え始めます。回数という数字を出すので、このアイコンには数値表示器を繋げられます。
右側の赤い丸ぽちがついたものは「条件端子」と呼びます。Whileループは、指定した終了の条件が満たされるまで繰り返しを続けるという動作をするものだと説明しました。その条件にあたる情報をこの条件端子に渡します。
条件端子には(基本的に)ブールデータを渡します。Whileループを止めるための条件が満たされた、という情報を「条件が満たされた?」という条件判定に置き換え、この質問に対しYesとなった状態をTRUE、Noとなった状態をFALSEとすることになります。そこで、TRUEが渡されるとWhileループが終了します。
ただし、この条件端子、赤い丸ぽち部分をクリックすると、赤い丸ぽちがなくなります。この状態のときには、TRUEとFALSEの扱いが「反転」します。つまり、この状態とするとFALSEが渡されたときにWhileループが終了します。
どちらの方法でも正しく組んでいるのであれば問題なく動作するので、どちらがいいかは好き好きなのですが、特に理由がないのであれば赤い丸ぽち状態の方が混乱が少ないかなと思います。
LabVIEWでは、この四角の枠に入った処理を繰り返し行います。この枠の外の関数は(別のループに入っていなければ)一回しか実行されません。
Whileループを作っただけではプログラムの実行ボタン矢印は壊れています。これは条件を設定していないからですね。Whileループは必ず条件端子に何かしらの配線が必要です。
試しに動作を確認してみます。とてもシンプルに、ただループを回すだけのプログラムとするので、下の図のようにしてください。
このプログラムを実行する前に止まる条件を念のため確認します。
今回は、「停止ボタン」と書かれたブール制御器が条件端子につながっています。ということは、フロントパネルでユーザーがブール制御器をクリックし、ブール制御器がTRUEになったときにループが停止するはずです。(なお、条件端子を右クリックして制御器を作成した場合、このブール制御器の機械的動作はラッチになっています)
早速このプログラムを実行してどんな結果になるか見てみます。Whileループの中には今特に何か処理を入れていませんが、反復端子の値を見るとものすごい速さで値が増加するのがわかります。つまり、そのくらいの速さでループが回っている状態です。ある程度回ったら、フロントパネル上の停止ボタンを押してループを止めます。
ところで、ループの回る速度ってこれでいいんでしょうか?「なるべく早く繰り返したい」という場合ももちろんあると思いますが、場合によっては「1秒に一回」など、繰り返しの動作を行う速度を制御したい場合もあるはずです。
制御を行うためには、「タイミング」パレットの中の関数を使います。主には「待機関数」と「次のミリ秒倍数まで待機」の二種類があるのですが、これらの使い分けは少しややこしいので別の記事で紹介しています。
今はとりあえず、動作が素直な「待機関数」で制御することにします。待機関数を選択したらかならずWhileループの中においてください。Whileループの外では意味がなくなってしまいます。
イメージとしては、待機関数は「何もせずに1秒待つ」という動作をすると思ってもらえばいいです。ループはその中に入っているすべてのコードが終わらないと次のループに進みません。そのため待機関数があるとループは強制的に1秒待つことになります。
これでWhileループの基本的な使い方は終わりです。ではもう少し意味のあるプログラムでWhileループを試してみます。
冒頭の説明でも例を出しましたが温度を測定して1秒ごとに記録し、ある決まった温度になるまで測定を繰り返すということをしてみようと思います。
ベースとなるプログラムは以前作成した以下の図のようなものを使用します。
今回は温度測定をプログラム上で模擬しようと思います。乱数を使って、現実的な温度範囲、例えば20℃から32℃くらいをソフトウェア的に作り出します。
乱数は0~1の値しか出さないので(※LabVIEW 2020などですと範囲を広げた乱数も作れますが今回は汎用的な方法をとります)、これを20~32の範囲にするには以下のようにします。
上の計算の足し算の出力を、華氏、摂氏の部分と丸々置き換えます。そして、ファイルに書き込む関数とこの上の乱数値の部分を丸々Whileループで囲みます。
この状態では、Whileループが止まる条件がついていません。今回は温度が30度になったら止めるのでそのように書きます。また、その他の部分でも少し編集を加えて、Whileループの中身を下の図のようにしてみてください。
保存時の体裁を整える、というのは保存された結果をどのように保存するかを表わしています。上の例だと「復帰改行定数」を「文字列連結追加」という関数で数値(の文字列)と合体させて、一つ一つの数字をファイルに書き込んで改行して次の値を書き込む、という状態にしています。
例えば改行ではなくて「、」(カンマ)で区切ったりスペースで区切りたい場合には、「復帰改行定数」の部分をその区切りたい文字に置き換えられます。
ひとまず上の図のように組めたら最終的なプログラムは下の図のようになります。実行して、例えばデスクトップ上にtemperature.txtとして保存した結果の一例も紹介します。
また、あまりないと思いますが、いつまでたっても乱数の計算の結果が30より上にならない場合も考えて、「30で止まるかあるいはユーザーが停止ボタンを押すまで繰り返す」というアレンジもしてみます。その場合には以下のような形に終了条件を変更してみてください。
いかがでしょうか?だいぶプログラムっぽいプログラムができたと思いませんか?今回は乱数で値を模擬していますが、この部分を実際の計測器からの測定値に置き換えれば、それだけでデータ保存のプログラムを作れるようになったんです。
こうやって一つ一つできることが増えるのはうれしいことですよね!
Forループを使ったプログラムを組んでみる
では次に、もう一つのループの種類であるForループについて扱っていこうと思います。
といっても、実はWhileループをマスター出来たらForループも使い方についてはほぼマスターしたようなものなんです。止める条件が違うだけで、プログラムの書き方は一緒です。
とはいえ、まずForループの基本的な構造からみてみます。先ほどWhileループを出したのと同様に、関数パレットのストラクチャのパレットから今度はForループを選んでブロックダイアグラム上に配置します。
さて、Forループを配置すると、枠の形以外でWhileループと見た目が異なる部分があります。
- 反復端子はあるものの条件端子がない
- Nと書かれた部分がある
WhileループとForループの違い、覚えていますか?そう、Whileループは何かしらループを止める条件を設定する必要があるのに対し、Forループは回数でループを止めることができるのでした。
Forループでは止まるまでにループが回る回数を指定する必要があるのですが、Whileループに無かったNという部分がまさにこれにあたります。ここをカウント端子と呼びます。
指定の回数によって止まるので、Forループは「デフォルトでは」条件端子を持ちません。実際はForループにも条件端子を付けて、「指定した回数に達する前に特定の条件を満たしたらループを止める」という使い方もできるのですが、メインの使い方ではありません。
さて、実はあとの内容はWhileループと同じです。試しに、Whileループでも行った温度測定値を保存するプログラムをForループにしてみます。Whileループの枠をクリックして右クリックで「Forループに置換」で終わりです。
条件端子の部分はもはや必要ないですが、Forループに条件端子を付けても構いません。この場合、例えば10回温度が測定されるかあるいは30度以上の値となったらデータの保存を終わるようになります。
まぁ同じようなプログラムを動かすのは面白くないので、もう一つ別の例でForループを使ってみることも考えようと思います。前回、そして今回の冒頭にも例を出した、サイコロを振って出た目の平均を出すプログラムです。
さぁ、試してみてください。・・・と、ここで疑問が出ると思います。「Forループで100回繰り返すのはできるかもしれないけれど、その100個の値はどうすればいいのか?」と。
実は、今までのループの説明では、ループの中で処理が完結している場合の対応しか紹介していません。実際は、ループで繰り返し何かの値を出してから、それらのデータをまとめてループの外で扱うといった処理も考えられます。「サイコロを100回振ってその平均を求める」なんかがまさにそれです。
ではその100個の値をどうするか?ここで、前回の記事で紹介した配列を使います。でもどうやって?Forループと配列がどう結びつくのか?と思った方。記事が長くなったのでこの続きは次回に紹介したいと思います。
もしよろしければ次の記事も見ていってもらえると嬉しいです。
ここまで読んでいただきありがとうございました。
コメント