きっとこの記事を読んでくれている方は、LabVIEWを使ってプログラミングをしてハードウェアを使って測定を行うという目的を持った方が多いと思います。
とはいえ、プログラミングなんて学ぶ時間ない!でもデータをとらなければいけないんだ!という方も多いと思います。私も学生の時はそうでした。
そんな方のために、「とにかくちゃっちゃとハードウェアを使ってデータの測定をしたいけれど、少しばかり改造して自分のやりたいことにあったプログラムにしたい」というご要望に応えようというのが本記事です。
なお、ここで言うハードウェアはNational Instruments社のDAQ製品と呼ばれるハードウェアを指します。そのため、DAQ製品を扱うためのプログラムの書き方について紹介しています。
別記事で、Express VIを使用してDAQハードウェアを操作するという記事を紹介しました。
こちらの方法でもいいんですが、Express VIというのは途中でプログラムを変えるのがめんどくさくて融通が利きにくいという弱点があります。
せっかくLabVIEWをやるので、必要最小限のことだけ知りつつも、ちゃんと「それっぽい」プログラムが書けるようになった方が色々と役に立つってものです。
そしてLabVIEWに興味が出てきたら、いろいろな本や、本ブログの他の記事も見ていただきながら慣れていければいいかなと思います。
なお、LabVIEWでプログラムを書く際にはいろいろなことができてしまうにもかかわらず本記事は必要最低限のことしか触れません。
扱うトピックもアナログの電圧信号を連続的に測るということを前提にしています。が、基本は他の測定種でも同じですし、記事の最後でこれ以外の信号種を扱う際にはどうすればいいかも紹介していきます。
必要な環境
以下、紹介していくプログラムは冒頭で書いたようにDAQ製品を扱います。National Instruments社は多くのハードウェア製品を出しているので、どれがDAQ製品に該当するかわからない、という場合には、DAQ製品のドライバソフトウェアであるDAQmxというソフトのreadmeファイルを確認すると、DAQmxドライバソフトウェアに対応するハードウェアの一覧があるので、この一覧に該当する製品名があるかを見ます。

実際に必要なものとしては
- LabVIEW(プログラム開発環境)
- DAQmxドライバソフトウェア
- DAQmxドライバが対応しているDAQハードウェア
になります。注意点があるとすれば、ソフトウェアのインストールはLabVIEWを先に行い、その後にドライバソフトウェアをインストールする、といったことでしょうか(この順番でインストールしないとLabVIEWの中でDAQ用の関数が使用できなくなるためです)。
DAQプログラム構築のフローチャート
LabVIEWは関数をブロックとしてつなげていくようにプログラムを書く、グラフィカル言語と呼ばれます。
知っている人はそこまで苦労せずに関数を並べていけますが、まだ慣れていない人にとっては何をすればいいのか、どんな関数を使えばいいのか分からないことだらけだと思います。
そこで、データを測定する、必要に応じて解析する、保存するという目的に特化して、どのような関数を使えばいいかのフローチャートを書いてみました。

このフローチャートに沿って、それぞれの関数を並べてつなげていくだけでプログラムが作れます。
LabVIEWの操作に慣れていない方へ
ここから先、各関数の説明や設定について紹介していきます。その際に必要最低限の操作はどうしても必要になります。
とりあえずLabVIEWでプログラムを作るってことであればviの作り方、制御器や表示器の置き方、関数の探し方、ワイヤの結び方は最低限知っておく必要があります。
それくらいは知っているよ、という方はこのまま読み進めていただければいいのですが、そういった操作も全然わからない超初心者です、という方はまず操作の基本についての記事を確認していただくといいと思います。

ひとまずこれらを知っておけば本記事の操作で困ることはないと思います。
使用するハードウェアの準備、確認
これはNI MAXというソフトウェアを使用します。おいおいいきなりLabVIEWではないソフトの話かい、と思われるかもしれませんが、これは「LabVIEWで操作するハードウェアを管理するソフトウェア」だと思ってください。
本当は色々なことができますが、ここでは最低限、
- そもそも接続できているの?
- 測定ができる準備は整っている?
この二点を確認していきます。
まずはNI MAXのソフトウェアを立ち上げます。そんなものインストールした覚えないぞ、と思われるかもしれませんが、LabVIEWおよびDAQmxドライバソフトウェアをインストールしているのであれば気づかないうちにインストールされているはずです。
なお、NI MAXの見た目はバージョンによって異なることがありますが、中身で表示される項目は同じです。

そもそも接続できているかどうかについては、デバイスがNI MAXのデバイスとインタフェースの項目に表示されているかで確認できますが、念のためセルフテストも行っておきます。
セルフテストは「成功して当たり前」な項目です。これに成功している=ハードウェアトラブルがない、ということにはならないのですが、これに失敗している=ハードウェアトラブルがある、と判断できます。

測定ができる準備が整っているかどうかは、テストパネルで確認することができます。この機能は、プログラミング無しでデータの測定を簡易的に行うモードです。
プログラミングが必要ない代わりにデータの保存や解析などもできず、ただただ測定を行って「センサなどがうまく接続されているな」といったことをまず確認するのに使用します。

これらが終わったら、LabVIEWプログラムに進んでいきます。
LabVIEWプログラムを作っていく
次にLabVIEWを触っていきます。フローチャートの流れに沿って紹介していきます。
チャンネルの決定
まず、関数パレットを開いてDAQmx仮想チャンネルを作成関数をブロックダイアグラムに置きます。このチャンネル作成とは、簡単に言えば「今からこのプログラムでこのチャンネル(端子)を使いますよ」ということを設定するための関数です。

このDAQmx仮想チャンネルを作成の関数に対して必要な入力である物理チャンネルをはじめ、他にも設定できる端子構成、最大値、最小値について制御器を作成します。

チャンネルの決定については以上です。
測定のタイミングについて
次にデータを測定するタイミングについて考えます。ざっくり、
- ハードウェアが制御する、精度の高いタイミングで各データを取得したい
- ソフトウェアが制御する、そこまで精度を求めないタイミングで各データを取得する
のかです。ここで言う精度はデータの精度ではなく、タイミングの精度です。データの一点一点の間隔が高精度で1 ミリ秒ずつとしたいのか、おおよそ1 ミリ秒ずつでもいいのか、といった具合です。

ほとんどの測定ではハードウェアタイミングが求められると思うので、この記事ではハードウェアタイミングを前提に進めていきます。
DAQmxタイミングの関数をDAQmxチャンネルを生成の関数の右側に置きます。
そして、DAQmxタイミングの関数でサンプルレートとサンプル数/チャンネルに対して制御器を、 サンプリングモードに対して定数を用意します。
定数は、フロントパネル上には表示されず、ブロックダイアグラム上で固定値として何か入力を指定したい場合に使用します。サンプリング(データ測定)を連続(回数が決まっていない、という意味になります)で行うので、「連続サンプル」に固定します。

なお、もしソフトウェアタイミングにしたいということであれば、このDAQmxタイミングの関数をおかない状態で次に進みます。
トリガを設定する
次に、トリガ機能を使用したいかを決めます。要は、外部からのトリガ信号を受け取って測定の制御を行いたいか、ということになります。
トリガ信号として受け取れるのはアナログ、デジタルどちらもありますが、トリガの種類としては
- 開始トリガ
- 一時停止トリガ
- 基準トリガ
があります。(他にもありますが、代表的なものを挙げています)
開始トリガはその名の通り、トリガ信号を受け取ってから測定を始めるというものになります。
下の図はイメージです。本来測定したい信号が一番上のグラフの正弦波だとして、開始トリガを設定していた場合、トリガが来たら測定データを取得し始める、といった具合です。そのあとにトリガ信号がどうなっていても関係ありません。
また、トリガ信号の立ち上がり(LOWからHIGH)なのか立下りなのか(HIGHからLOW)、あるいはトリガはデジタル信号でなくてもアナログ信号でも対応します。

一時停止トリガは、トリガ信号の状態によって測定を停止したり再開したりをコントロールできるモードになります。イメージとしては以下のような状態です。

基準トリガは、トリガ信号の前後特定の範囲でデータを指定した数だけ取得したいという場合に使用します。指定した数だけ取得したら測定は終わり、ということになります。

が、タイミングの設定の部分で連続モードを選択している場合には、この基準トリガは使用できません。実質開始トリガか一時停止トリガの二択です。
今回は開始トリガの設定をしてみます。関数としてはDAQmxトリガ関数を使用します。
DAQmxトリガ関数はブロックダイアグラム上に置いただけでは「開始なし」と表示されています。この部分は多態性セレクタと呼ばれ、簡単に言うと一つの関数で様々なタイプに設定が可能な状態です(今までのDAQmx仮想チャンネルを作成もDAQmxタイミングの関数も同じです)。
開始のデジタルエッジと選択し、エッジについて定数を、ソースについて制御器を作ります。

多態性の他の選択肢を選ぶことで他のトリガタイプも指定することができます。ただし、もし決まった数のサンプリングしか行わない(DAQmxタイミングのサンプリングモードが有限サンプリングとしている)として一時停止トリガを使用したい場合にはプロパティノードで設定することになります。

読み取りを行う
次にデータの読み取りです。データの読み取りはDAQmx読み取りの関数で行います。
今回はアナログ信号を扱うのですが、実際に使用するチャンネル数が1チャンネルであっても、多態性セレクタではNチャンネル、複数サンプルを選択したほうが便利だと思います(Nチャンネルには1チャンネルも含まれるためです)。

多態性セレクタでは最後の選択が大きく分けて二つあるのですが、
- FFTをはじめとする波形の解析を行いたいのであれば波形データ
- FFTなどの解析は必要としないのであれば2D DBL
という基準で選びます。
波形データと2D DBLのデータの違いは、時間の情報を持つかどうかです。この時間と呼んでいるのは、ある瞬間の波形データの開始時間t0とデータとデータの間隔dtのことで、これらの時間情報と実際のデータ点の情報(2D DBL)が合わさって波形データとなっています。
FFTをかける際にはデータとデータの間隔などの情報がないと正しく解析できないため、そのような処理を行う場合には波形データ一択です。
もし自分が行おうとしている解析に時間情報が必要か分からない場合には、とりあえず波形データを選んでください。波形データから2D DBLのようなデータに変換することはできますが、2D DBLのデータを波形データに変換するには時間情報がない限りできません。

FFTなどすることはなく時間情報など必要ないということであれば2D DBLで問題ありません。もし時間情報が必要か分からないということであれば、 後で簡易的な判断基準を紹介します。
解析を行う
データの解析については解析の関数としてまとまっています。ただし注意する必要があるのは、これらの解析の関数は基本的に「1チャンネルの波形データに対して」適用する関数になっています。
DAQmx読み取りの関数でNチャンネルを指定していると、1チャンネルではなくNチャンネル、つまり複数のチャンネルのデータがまとまった配列のデータとして出力されます。これでは解析の関数を使用できません。

もし、特定のチャンネルに対してのみ解析をかけたいということであれば、指標配列という関数を用いてどのチャンネルか(正確にはどの指標の波形データか)を指定する必要があります。
指定には、指標配列の関数に指標制御器を作成します。

一方、もしすべてのチャンネルに対して解析をかけたいということであれば、Forループを使用して逐次解析を適用する方法があります。

本記事では例として、すべてのチャンネルに対してFFTをかけるとして次に進みます。
なお、解析に時間情報が必要か、ということを見分ける一つの基準として、その解析の関数が受け付けるデータタイプが何であるかを知るということが挙げられると思います。
実は関数によっては波形データも数値の配列データもどちらも受け付けられるものがあるのですが、本来関数が想定しているデータ型ではない場合には赤い丸がつきます。これは強制ドットと呼ばれ、プログラムの実行はできるのですがLabVIEWが勝手にデータの型を変換している状態です。「勝手に」変換しているので、時間情報などが適切ではない値となる場合があります。
そこで、もし数値の配列をワイヤ配線した状態で強制ドットが出た場合には、波形データが必要だ、と判断します。

データの保存
読み取ったデータは保存のプログラムを書かないと当然保存されません。この時にもLabVIEWはいくつかデータ保存について選択肢があります。大きくわけて、
- TDMS保存
- バイナリデータ保存
- テキストデータ(csvなど)保存
があります。
この記事では、プログラムが一番簡単なTDMSに限定します。
TDMSなんて聞いたことがない、という方もいると思います。ざっくり言うと、DAQmx読み取りで波形データを選択していた場合には、TDMSがオススメです。プログラムが簡単になります。
デメリットとしては、専用のソフトでないと中身を見れないことが挙げられます。じゃあダメじゃん、と思われるかもしれないですが、一応Excelに無料のアドオンを入れることでTDMSの中身を見ることができます。

また、別記事ですが、TDMSからcsvに保存することもできます。
あとから変換できるのであれば最初からcsvにした方がいいじゃんと思うかもしれませんが、TDMSの方がデータの書き込み速度が速いです。データの測定時には素早く書き込めるTDMSにして、後でゆっくりとcsv保存する、何て使い方もできるわけです。
DAQのタスク操作の関数を加える
さて、DAQのプログラムとしてあとは「タスク」についての関数をいくつか加えるだけです。
こちらについてはフローチャートには敢えて載せていませんでした。なぜなら、どんな形であれDAQハードウェアのプログラムをLabVIEWで使う場合には必ず必要になるからです。
このタスクというのは「ハードウェアをこのように動かしますよ」という命令を集めたものと思ってください。今まで使用してきたDAQmxチャンネルを作成やタイミング、トリガの設定は全部タスクに対する命令を決めていた状態です。

タスクは設定を終えたら開始して、読み取りの関数で読み取りを繰り返し行い、ユーザーが任意のタイミングで止められるようにしておきます。
読み取りを繰り返し行うという部分はWhileループを使用します。このWhileループは「ある条件を満たしたら繰り返しを終える」という性質を持ったループで、今回は「ユーザーが停止のボタンを押したら」、および「エラーが起きたら」ということを条件とします。
まずはタスクを制御するための関数3つを配置します。

繰り返しが必要になる部分についてWhileループでぐるっと囲みます。

このWhileループを停止させる条件は、Whileループ右下の赤い丸部分に設定します。まずは停止ボタンの制御器を作成し、あとでエラーが起きても止まるようにOrという関数を下の図のように用意しておきます。

ここで、タスクの設定およびタスクの制御の関数すべてをひとつなぎにします。こうすることで、「ひとつのタスクに対する操作」という情報が各々の関数に伝わります。
ショートカット操作があるので下の図のように操作してみてください。

同様に、TDMSファイル操作に関する3つの関数も、ショートカット操作でつなげることができます。
あとは、Whileループのエラーの情報を停止条件にするためにエラーワイヤを配線します。

これでプログラムとしては完成です。本来はエラーワイヤを解析の関数にもつなげた方がベターですが、エラーが起きている時点で解析の意味はないのでこうしています。また、エラーが起きた時点でデータ保存も終わるのでTDMSについての関数のエラーワイヤもあえて配線していません。
あとはちょこちょことした編集を行って完成です。

サンプル数/チャンネルとは、1チャンネル当たり、毎回どの程度のサンプル数をDAQmx読み取りの関数から出すか、という指定になっています。Whileループに入っていて繰り返しDAQmx読み取りの関数が実行されますが、その1回1回で何データをLabVIEW側で取得、表示するかについての指定になります。
表示、についてはグラフ表示が便利です。以下のようにフロントパネルでグラフを用意し、取得したデータおよび解析したデータをそれぞれグラフ表示させることができます。

もしプログラムが実行できない(実行ボタンが壊れている)場合には、上の図とどこか違う部分があるかもしれません。あるいは、壊れている実行ボタンを押すとエラーリストが表示され、何がダメでプログラムが実行できない状態になっているかを確認することができます。
エラー-200284が出たら
今回作ったプログラムでエラー-200284が出ることがあります。
原因としてあり得る可能性が高いのは以下の二つです。
- 開始トリガが来るのが遅い
- (トリガを設定していなくても)データがたまるのが遅い
今回例として作ったプログラムでは開始トリガを指定していました。開始のトリガが来ないと読み取りがされない、つまりデータがたまらない状態となります。
一方でDAQmx読み取りの関数は、デフォルトでは10秒間データがたまるのを待ちます。この間に「サンプル数/チャンネル」で指定しただけの数のサンプルがたまっていない場合にエラーが起きます。
もし開始トリガを設定していてこのエラーが起こる場合には、プログラムを実行してからタイムアウトになるまでにトリガがくるような環境とする必要があります。あるいは、DAQmx読み取りの関数のタイムアウトの時間を変更してもいいです。
それでもエラーが起こる、あるいは開始トリガを設定していなくてもこのエラーが起こる場合には、「サンプル数/チャンネル」の値を小さくするか、サンプリングレートを上げて、タイムアウトになる前に「サンプル数/チャンネル」で指定した分のサンプルがたまるようにするか、タイムアウトの時間を変更します。

開始トリガがいつ来るか分からない、だからタイムアウトは設定したくない、という場合には-1という値を入力することで無限に待たせることができます。ただ、データがたまらない限りDAQmx読み取りの関数がデータを出力しない関係上、トリガを受ける前に止めることができなくなります。
(この問題を解消する方法はあるのですが、少し複雑な書き方となるので本記事では割愛します。もしこの辺りも知りたければ、下記の記事で紹介しています。)
アナログ電圧以外の信号を測る場合
さて、これでハードウェアを動かして、解析して、測定データを保存することができました。
これまでの話で、アナログの電圧の信号を測定するという前提で紹介してきました。でも実際に測定する信号の種類はただの電圧信号ではなく、温度センサからの信号だったり歪み信号だったりすると思います。
それらについては、DAQmxチャンネルを生成の多態性(DAQmx読み取りで出てきました)の部分を変えてやればいいんです。

もちろん、測定の種類によって例えば温度センサならセンサタイプは何なのかといった新たな入力が加わります。これらをどう組めばいいか、についてはサンプルを見るようにするのが一番です。
DAQの製品のサンプルはDAQmxというカテゴリでまとまっていて、そこにはアナログ入力でも電圧以外の測定のサンプル、他に今回は触れていないアナログ出力やデジタルの入出力のサンプルもそろっています。

サンプルを見てそれが使えるんだったら最初からサンプルでいいじゃん、という意見も聞こえてきそうですが、サンプルには解析の関数もありませんし、データ保存も(関数一つでTDMS保存するというものは組み込まれていますが)柔軟にはできません。
やはり全体の大まかなプログラムの組み方の流れを知っていれば、サンプルをベースにして新たに機能を追加していくこともできるはずです。
その一歩として、まず何はともあれプログラムを最初から組んでみようという意気が大切だと思います。
最後は本題から少しそれた部分もありましたが、本記事では最低限の内容ということでここまでで話は終わりです。
もし余力があるよ、という方のために別記事で
- さらに効率のいいDAQプログラムを作る方法
- ファイルへの保存をもっと柔軟に行う方法
を紹介しています。


今回の記事の内容でも一からプログラムを組むのには事足りると思うのですが、せっかくだからもう少し頑張ってみようという方はこの続きの部分も読んでいただけると嬉しいです。
ここまで読んでいただきありがとうございました。
コメント