この記事で扱っていること
- カスタムしたタイムスタンプをつけやすくする方法
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
LabVIEWでプログラムを書くことで、何か測定をしたりとか、処理を行った結果などを後から参照できるようにファイルに保存するというケースはとても多くあると思います。
ここで悩むのがそのファイルの名前で、多くのファイルが生成されるようなプログラムの場合、区別できるようなファイル名にしておく必要があります。
そんなときに区別しやすい、あるいは既存のファイル名とかぶらないような命名規則として便利なのが、タイムスタンプを使用する方法かなと思います。
時間は一方向にしか流れないので、同じ時間というのは存在しないから、ですね。
ただ、タイムスタンプの表し方にはいくつか種類が考えられるので、色々カスタマイズできた方が便利です。
そこで、ユーザーがタイムスタンプの表し方をカスタマイズしやすいような設計の例を紹介します。
どんな結果になるか
フロントパネルには、タイムスタンプとして使用されるであろう年月日と時分秒の選択肢以外に区切り文字として使われる可能性があるいくつかの文字のためのボタンと、任意の文字を入れるための文字列制御器とこれに対応したボタン、そしてやり直しボタンと実際の表示を確認するためのボタンがあります。
プログラムを実行して、各ボタンを押すと、指定文字列にボタンに対応した文字が表示され、確認ボタンを押すことで実際に時間表記に変換した結果を見ることができます。
プログラムの構造
プログラムはザ・ステートマシンという作りでできるので、ベーシックにイベント駆動型のステートマシンで組んでいます。
ステートの種類としては、初期化のためのinitステート、イベントを待機、検出するためのeventステート、ボタン操作を一つ戻すためのundoステート、画面表示を更新するためのupdateステート、実際の表示例を表すためのdisplayステート、そしてプログラムを終了させるためのfinishステートです。
ステートを表すための列挙体以外にシフトレジスタで回しているのは文字列配列で、この文字列配列を操作することで日付指定の文字を増やしたり減らしたりができるようにしています。
初期化のためのinitステートでは、画面表示を初期化します。
今回のプログラムの場合には文字列制御器と表示器が全部で3つあるのでそれらに空白文字列定数を渡しています。
この部分は(特に制御器に対しては)ローカル変数でないと対応できないのでローカル変数を使用します。
そしてこの後にeventステートに進むようにします。
eventステートではイベントストラクチャを配置しておきます。
イベントの種類は下記の図に示した通りです。
1個やり直し、現在の設定を確認、OKボタンについてはそれぞれイベントを検出してそれぞれ次のステートに移るだけです。
他のすべてのボタンは、一つのイベントにまとめて、押されたボタンのラベルから判断してケースストラクチャでそれぞれ異なる文字列を配列連結しています。
ケースは、ボタンの数だけ用意します。
今回の例では年月日と時分秒以外にハイフンなど使いそうな文字を選んでいますが、ここは自由に減らしたり増やしたりしてください。
ステートマシンの説明に戻りまして、次にundoステートでは文字列配列の最後の値を削除するようにしています。
この後に、updateステートに進みます。
そしてそのupdateステートでは、文字列配列を一つの文字列の値にするために配列からスプレッドシート文字列に変換を駆使しています。
こうすることで、配列の中の各文字列を連結させたような表示にできます。
displayステートでは、updateステートとほぼ同じことをしていますが、現在の時間を日付/時間を秒で取得関数を使用してこのステートが実行された時点でのタイムスタンプを取得し、これを日付/時間文字列をフォーマット関数に渡すことで、実際の時間表示の様子を表すことができます。
プログラムの活用例
ここで紹介した、カスタムしたタイムスタンプを使用するプログラムの例を紹介します。
ここでは、ハードウェアでデータを取得しているとして、ユーザーが決めた任意のタイミングからデータを保存し、その保存ファイルにタイムスタンプを使用することを想定しています。
エッセンスを紹介するだけなので、ハードウェア操作については最小限の構成にし、またハードウェアとしてはNI社のDAQを例にしています(が、本質的にはどのようなハードウェア操作のプログラムでも同様な構造にすることで対応可能かと思います)。
下の図のようなフロントパネルとし、機械的動作をスイッチとした「ファイル保存」ボタンがTrueの間のデータを保存していきます(「保存ファイル名を構成」ボタンはラッチ動作)。
実行後に保存ファイル名を構成ボタンを押すと、別ウィンドウで上で紹介した日付を構成するプログラムを表示させることができ、この間メインのプログラムでは測定が続いています。
ファイル名を構成後にはいかようにでも保存方法を組めばいいですが、今回はファイル保存のボタン(スイッチ動作としています)を押してこれがTrueになっている間のデータをtdmsファイルに保存するようにしています。
このプログラムのブロックダイアグラムの一例を以下の図に示しています。
イベントを検出するループ以外に、ハードウェアで測定を続けているループを用意しています。
なお、本来はローカル変数を使用しないプログラムの方がいいのですが、単純なプログラムとするため今回は競合状態が起こらないように注意しながらローカル変数を多用しています。
イベントを検出するためのループの中身は3つのイベントを用意しています。
保存ファイル名を構成のボタンの値変更イベント内で一番左に配置しているサブVIが、上で紹介した日付指定のプログラムのことで、このサブVIからの出力をファイル名としています。
ただし、このような形でサブVI化した場合には、finishステートの中で、メインVIに渡すための文字列表示器を用意し、適切な形で渡してやる必要があります(上で紹介したプログラムのままだと、最後に復帰改行文字がついてしまっているため、以下の図のように修正することで復帰改行文字を取り除いています)。
また、今回はこのサブVIが実行されたらフロントパネルが表示されるようにしないと意味がないため、サブVIのVIプロパティの設定で、フロントパネルが表示されるようにしておきます。
下のループは以下の図のようにステートマシンチックな構成とし、イベント検出によってidle状態からstart saveに移れるようにしています。
本記事では、カスタムしたタイムスタンプをつけやすくする方法を紹介しました。
タイムスタンプを構成するための時間コードをユーザーに入力させるのではなく、手軽にタイムスタンプのフォーマットを構成させることでユーザーが使いやすいプログラムにするための工夫として参考になればうれしいです。
ここまで読んでいただきありがとうございました。
コメント