LabViewプログラミングメモ
by K.I
Index
- 計測器の測定環境のプログラムに使用される、LabViewの使い方を簡単に纏めた。
- というより、こんな風にすれば良さそうという感想1かな。
ちゃんとした使い方は、 ASCII出版の「LabVIEW 8プログラミングガイド グラフィカル言語によるPCベース計測とデータ解析」がお薦め。
1使いはじめて間もないので、嘘が多いかもしれないけど。
[top]
- LabViewは、データの流れを配線のように記述する。つまりブロックダイアグラムによるプログラムになる。
- プログラムの基本単位はVIというファイル2で、サブルーチン(サブVI)として階層構造で使用することも出来る。
VIはデータ入出力端子として、制御器と表示器を持つ。
- これは、関数の入力と出力と考えて良い。
- VIをサブVIとして使用する場合は、これがそのまま入出力端子となる。
例として、連続したデータ表示をやってみる。
- Whileループで繰り返し
- 100ms毎に乱数をチャートで表示する。
これは表示器のみ使用している。
測定データは多くの場合、ある時間間隔で記録された複数のデータになる。
- 当然、配列データを扱うことが多くなる。
- LabViewでは、次元と配列の個数がゴッチャになってる場合があるので注意が必要。
例として、配列にある波形データが入っていたとして、それを表示するプログラムを考える。
- データを入力する部分は省略して、データを乱数で作成する。
- データを配列に入れて、それをグラフ表示器で表示する。
- データ処理を行う場合は、配列にしておく必要がある。
プログラムが大きくなってくると、特にLabViewの場合、全体の見通しが悪くなる。
- そのため、一部のプログラムをサブVIとし、部品として使うことが出来る。
- サブVIにしておけば、同じ機能を何個所も使う場合にも便利だ。
一部をサブVIに変換
- 例えば配列の例で示したVIの一部を選択して、サブVIに変換すると、
- 制御器と表示器が、サブVIの入出力になる。
- この制御器、表示器のプロパティも普通のVIのように設定出来るし、実行も出来る。
- デフォルト値や設定範囲等を指定しておけば、部品として使う時にその設定を利用3できる。
アイコンの設定
- フロントパネルで、アイコンを右クリック、アイコンの編集を選ぶ。
コネクタの設定
- フロントパネルで、アイコンを右クリック、コネクタの表示を選ぶ。
- コネクタのパターンは、出来るだけ多めにしておいた方が良い。
- パターンを決めたら、パターンのコネクタをクリック→制御器或いは表示器をクリック、というようにコネクタと、入出力端子を対応させる。
2必ずファイルにする必要があるのは面倒に感じるが、LabViewのプログラム構造上の問題だろう。
3制御器、表示器の生成機能を使う。
[top]
測定自体は、測定器を複数接続して並列に処理する。
- LabViewはブロックダイアグラムのように接続するので、このような並列接続は簡単で分かり易いプログラムを書ける。
- だが測定は、実行順序が重要であることも多く、シーケンス処理は欠かせない。
例えば計測プログラムの大まかな流れが、例えば以下のようになっているとする。
- 初期設定 →測定器のリセット、レンジの設定等
- 測定 →一定間隔で測定を繰り返す
- 後処理 →測定回路の切断、ファイルの保存等
通常のプログラムでは、シーケンスで順番に実行するプログラムの記述は容易だ。
でもLabViewでは、基本的に並列処理されるので、逆にシーケンス記述が面倒になる。
- シーケンス処理を考えずにプログラムを始めると、複雑になってしまう可能性がある。
- LabViewでは、シーケンスストラクチャという記述方法で、順次実行させることが出来る。
- これは、HDLでステートマシンでプログラムするのと同様の考え方だ。
- 順番に処理を実行する場合、シーケンスストラクチャを多用したくなるが、使い過ぎるとプログラムが分かり難くなるし、速度的にも不利になるようだ。
- LabViewでは、データフローにより実行順序が決まるという、独自の方法を取っている。
- HDLや実際の回路では完全に並列処理されるが、LabViewではあくまで順番に処理されるためだ。
LabViewのファイル処理でのエラーフローを例に説明する。
- ファイルのオープン
- ファイルの書込み、読込み
- ファイルのクローズ
- この処理はそれぞれモジュール化されており、LabViewでは例えば以下のようにプログラムする。
- 各モジュールは、それぞれエラー入力とエラー出力を持っている。
- プログラムは、各処理のエラー出力を次の処理のエラー入力に、また次の処理のエラー出力を、次の次のエラー入力にというように接続しているだけだ。
- LabViewでは、データフローにより実行順序が決まり、前のデータ処理が終わらない限り次の処理は実行されない。
- つまり、これだけでシーケンス処理を記述することが出来る。
- またエラーの場合、処理がスルーされるので、エラー処理が1個所で良い利点がある。
- これは、別の言語によるエラー処理でも参考になるやり方だと思う。
- エラーフローと同様に、データフローのための端子を付けておけば、データフローによりシーケンスコントロールが出来る。
- LabViewでは、データフローを使うとスッキリ書けるため、プログラムが見やすくなる。
- シーケンスストラクチャを使ったプログラムと同じ動作だが、こちらの方が分かりやすいと思う
[top]
LabViewでは、測定ボード等の外部プログラムのDLLを利用することが出来る。
- 自分でDLLを作成して、呼び出すことも可能だ。
- VC++で作成した、簡単な足し算プログラムをLabViewで使う例を示す。
VC++で、DLLとしてプロジェクトを作ってコンパイルする。
- ファイル→新規作成→プロジェクトタブ→Win32 Dynamic-Link-Libraryとして、プロジェクトのパスと名前を指定する。
- ファイル→新規作成→ファイルタブ→C++ソースファイルとして、ソースファイル名を指定
- プロジェクトへ追加をチェックしておく
- ファイル名は、DLL名称.cpp とする
- プロジェクト→設定→C/C++タブを選択、カテゴリをプリプロセッサとして、ライブラリのパスを指定する。
- インクルードファイルのパスを、必要に応じて割り当てておく。
これで、VC++の設定は終わり、あとはデフォルトで良い。
プログラムは DLL名称.cpp とする。
- LabViewのDLLとするプログラムは、以下のようにする必要がある。
- 最初にLabViewのcintools/extcode.hをincludeする。
- その後に、プロトタイプ宣言を纏めておく。
- 関数定義の頭に、_declspec (dllexport) を付加する。
- それ以外は、任意の名称で、任意の型、任意の引数の関数を定義することが出来る。
- この例では、AddFunc.cppという名前で、プログラムを作成した。
/* Call Library Source File */
#include <ni/LabVIEW7.1/cintools/extcode.h> →DLL用ヘッダ
_declspec (dllexport) int AddFunc(int in1, int in2); →プロトタイプ宣言
_declspec (dllexport) int AddFunc(int in1, int in2) →関数定義
{
return(in1 + in2) ;
}
- 例では、AddFuncという名称で、2つのパラメータを入力し加算した結果を返す簡単な関数を定義した。
- コンパイルはビルド→ビルドを選択するだけで、何も問題がなければ以下のように表示されて、DLLが作成される。
AddFunc.dll - エラー 0、警告 0
- デフォルトではDebugディレクトリの下に、DLL名称.dllが作成される。
- この例では、DLL名称はAddFunc、関数名もAddFuncとしたが、一致させる必要は無い。
- 出力ディレクトリは、プロジェクト→設定→一般タブの出力ディレクトリで指定する。
- LabViewで、新規のviファイル4を作成する。
- まず、ブロックダイアグラムのウィンドウ上で、関数呼出し用モジュールを配置する。
- 右クリックして、全関数→上級→ライブラリ関数呼出しノード
- さらに配置されたモジュールを右クリックして、構成を選択する。
- これでDLLの関数定義は終わり。パラメータの名前は元々の関数と一致させる必要はないので、分かり易い名称にすると良い。
- まずフロントパネルのウィンドウで、操作パネルを作成する。
- 数値入力のために、右クリックして数値制御器の中から適当なものを2つ配置
- プロパティ→データ範囲で、I32(符号付32bit整数)を選択。最小値、最大値も選択しておくと良い。
- ノブとかの場合は、さらに プロパティ→スケールで表示範囲を指定
- 数値出力のために、右クリックして数値表示器の中から適当なものを配置
- 次にブロックダイアグラムのウィンドウ上で、入力制御器を関数の入力、出力表示器を関数の出力に接続する。
- 関数の設定がうまくいっていない場合は接続出来ないので、DLL呼出しの設定に戻って修正する
- フロントパネルウィンドウで、連続実行ボタンを押す。
- 数値制御器を動かすと、数値表示器の値が変化するのが分かる。
- DLLを作成する際は、出来るだけデータフローでプログラム出来るようにインターフェースを決めておくと良い。
例えば以下のように、エラー入出力用のパラメータを付加しておく。
long _AddFunc(long *err, long arg1, long arg2);
- これは関数呼出し時は、数値のポインタになる。
- データフローが必要な場合は、err端子を数珠繋ぎにすれば良い。
- データフローが不要であれば、接続しなければ良いだけなので、常に付加しておく方が良いと思われる。
- 計測ボード等のコントロールを行う場合に、構造体のハンドル等でアクセスする必要がある場合が多い。
- LabViewでDLLを呼び出す場合に、グローバル変数が使えるかどうかテストしてみた。
- DLLプログラムは、以下のようにした。
- MulFuncで、入力の積をグローバル変数gdataに計算結果を保存
- GetDataで、グローバル変数の値を読み込む
#include <ni/LabVIEW7.1/cintools/extcode.h>
int gdata;
_declspec (dllexport) int MulFunc(int in1, int in2);
_declspec (dllexport) int GetData(void);
_declspec (dllexport) int MulFunc(int in1, int in2)
{
int i=0;
gdata = in1 * in2;
return(gdata);
}
_declspec (dllexport) int getdata(void)
{
return(gdata);
}
- 結果は問題なく、データのやり取りが出来た。
- 従って、LabViewのDLL関数同士でのグローバル変数のやり取りは可能と思われる。
4LabViewのプログラムファイル名。拡張子が.viになる。
[top]
- 良く使うキー操作
- Ctrl-B →無効配線の削除
- Ctrl-E →ブロックダイアグラムとパネルの切替え
- 何もない処でCtrl-Drag →ドラッグした範囲分、配置済みのデータを移動して空き地を作る
- 選択した状態で矢印キー →ピクセル単位で移動
- 選択した状態でCtrl-Drag →コピー
- LabViewで、COMポートやLPTポートを使う場合は、VISAモジュールというのを使うらしい。
[top]
[電子工作関連に戻る]